(function () { 'use strict'; var app = window.app; // // Angular file upload hack // // TODO modularize for reuse function analyzeFile(file, vm) { vm.triggerFileRefresh = 'changed'; vm.isZip = /\.zip$/.test(file.name); vm.unzip = vm.isZip; vm.stripZip = vm.isZip; return vm; } /* function handleFiles(ev) { var selector = 'js-file-upload'; var $scope; var vm; if ('INPUT' !== ev.target.tagName || 'file' !== ev.target.type || -1 === ev.target.className.indexOf(selector)) { return; } $scope = angular.element(ev.target).scope(); // 'vm' is the Controller As name. vm = $scope.vm; vm.currentFiles = ev.target.files; analyzeFile(vm.currentFiles[0], vm); $scope.$digest(); console.log('[handleFiles] vm.currentFiles:'); console.log(vm.currentFiles); } window.document.body.addEventListener('change', handleFiles); */ app.directive('daplieFileChange', [function () { return { restrict: 'A', require:"ngModel", link: function (scope, element, attrs, ngModel) { element.bind('change', function (event) { var files = event.target.files; ngModel.$setViewValue(files[0]); scope.$eval(attrs.daplieFileChange); }); } }; }]); app.directive('fileTree', [function () { return { restrict: 'EA', templateUrl: '/templates/widgets/filetree.html', }; }]); app.directive('notificationBar', [function () { return { restrict: 'EA', templateUrl: '/templates/widgets/website-notification-bar.html', }; }]); app.controller('websiteCtrl', [ '$scope', '$q', 'Auth', 'azp@oauth3.org', '$timeout', '$sce', '$rootScope', function ($scope, $q, Auth, Oauth3, $timeout, $sce, $rootScope) { var vm = this; var angular = window.angular; vm.domains = []; vm.copyUploadPath = ''; vm.displaySpinner = ''; vm.deleteAll = ''; vm.alertNotification = { hidden: 'hidden' }; //vm.unzipPath = '/'; vm.uploadPath = '/'; // already validated function domainIsVerified(r) { return r.verifiedAt || r.mode; } Auth.api = function (apiname, opts) { var els = []; return $q.all(Auth.sessions.map(function (session) { return Auth.get(session).then(function (oauth3) { return oauth3.api(apiname, {}).then(function (collection) { if (collection.error) { // not all tokens support all apis return; } if (!Array.isArray(collection)) { console.error('collection is not an array'); console.error(collection); return; } collection.forEach(function (el) { els.push(el); el.session = session.token.sub + '@' + session.token.iss; }); }, function(err) { console.error("There was an error 1A", err); return els; }); }); })).then(function (results) { return els; }, function(err) {console.error("There was an error 1B", err)}); }; vm.getDomains = function () { return Auth.oauth3.api('domains.list', {}).then(function (result) { vm.domains = result.registrations || result; }); }; vm.setDomain = function () { if (!vm.domains || !vm.domains.length) { vm.domain = { domain: vm.newDomain }; return; } vm.domains.some(function (domain) { if (domain.domain === vm.newDomain) { vm.domain = domain; return true; } }); if (!vm.domain) { vm.domain = { domain: vm.newDomain }; } if (!vm.domain.tld) { var parts = vm.domain.domain.split('.'); vm.domain.sld = parts.shift(); vm.domain.tld = parts.join('.'); } vm.setRecord(); }; vm.selectDomain = function (domain) { vm.domain = domain; //vm.selectedDomain.description; vm.newDomain = vm.domain.domain; return Auth.api('dns.list', { }).then(function (records) { records = records.filter(function (r) { return /^A(AAA)?$/i.test(r.type) && ((r.sld + '.' + r.tld) === vm.domain.domain || r.zone === vm.domain.domain); }); vm.records = records; records.forEach(function (record) { if (!record.sub) { record.sub = record.host.replace('.' + record.zone, ''); if (record.host === record.zone) { record.sub = '@'; } } }); console.log('[selectDomain] dns records:'); console.log(records); }); }; vm.setRecord = function () { // TODO set record based on (record.host === sub + domain.domain) var sub = vm.newRecord; if ('@' === sub) { sub = ''; } vm.record = { sub: sub, host: (sub ? sub + '.' : '') + vm.domain.domain }; vm.currentHost = vm.record.host; console.log('[setRecord] vm.record:'); console.log(vm.record); }; vm.shareInit = function () { if ($rootScope.urlInfo.params.token !== undefined) { console.log('FISH STICKS', $rootScope.urlInfo); var result = { data: { info: true } }; var msg = "You can only view inside the "; vm.buildNotification(result, msg); // debugger; } }; vm.selectRecord = function (record) { vm.record = record; vm.newRecord = record.sub; vm.currentHost = record.host; // .replace(new RegExp('\\.' + vm.domain.domain.replace(/\./g, '\\.') + '$', '')); }; vm._uploadFileVm = function (pkg, opts) { return vm._uploadFile(pkg, { domain: opts.currentHost , tld: opts.domain.tld , sld: opts.domain.sld , sub: opts.domain.sub , newFile: opts.newFile , uploadPath: opts.uploadPath , progress: opts }); }; vm._uploadFile = function (pkg, opts) { vm.newFileUploaded = opts.newFile.name; opts.progress = opts.progress || opts; return pkg.add({ hostname: opts.domain , domain: opts.domain , tld: opts.tld , sld: opts.sld //, sub: opts.record.sub , multipart: { site: opts.newFile } , progress: function (ev) { // TODO must digest opts.progress.uploadPercent = Math.round((ev.loaded / ev.total) * 100); // TODO GiB, MiB, KiB, etc opts.progress.uploadTotal = (ev.total / (1024 * 1024)).toFixed(2); opts.progress.uploadProgress = (ev.loaded / (1024 * 1024)).toFixed(2); } , unzip: opts.unzip , strip: opts.stripZip , path: opts.uploadPath }).then(function (result) { if (result.data.error) { var msg = vm.newFileUploaded + " has encountered an error. " + result.data.error.message + '.'; } else { var msg = "'" + vm.newFileUploaded + "'" + " has been uploaded."; vm.uploadFolderContainer = false; vm.uploadFileContainer = false; } vm.buildNotification(result, msg); vm.cleanArrays(); var path = vm.breadcrumbsPath.join('/'); cleanPathQuery(path); vm.Sites.contents(vm.copyR, vm.cleanedPath); }, function (err) { console.log(err); }); }; vm._isSubDomain = function (sub, domain) { return -1 !== ('.' + sub).indexOf(('.' + domain)); }; vm.Sites = {}; vm.Sites.create = function () { var pkg = Auth.oauth3.pkg('www@daplie.com'); var parts; var sub; var sld; var tld; /* //vm.unlock('webpreneur'); if (!vm.currentFiles || !vm.currentFiles.length) { window.alert('No files chosen.'); return; } if (1 !== vm.currentFiles.length) { window.alert('Too many files chosen.'); return; } */ if (!vm.newFile) { window.alert('No file chosen.'); return; } if (!vm.currentHost) { window.alert('No hostname chosen.'); return; } if (vm.domain) { if (!vm.domain.tld || !vm.domain.sld) { parts = vm.domain.domain.split('.'); sld = parts.shift(); tld = parts.join('.'); } else { sld = vm.domain.sld; tld = vm.domain.tld; } } else { parts = vm.currentHost.split('.'); // TODO get list of tlds tld = parts.pop(); sld = parts.pop(); sub = parts.join('.'); } if (vm.sites.some(function (r) { return (-1 !== ('.' + vm.currentHost).indexOf(('.' + r.domain))) && domainIsVerified(r); })) { vm._uploadFileVm(pkg, vm); return; } // We're making a request to claim a domain // (because two users could both claim a single domain) // We're claiming it at the top level (i.e. example.com) // but we could also claim it at the subdomain level (needs UI update) var domainReq = { sld: sld, tld: tld, sub: undefined }; return pkg.request(domainReq).then(function (result) { var sess; var prom; var def; // can validate automatically if (vm.domain.session && vm._isSubDomain(vm.currentHost, vm.domain.domain)) { // this should always succeed Auth.sessions.some(function (session) { if (vm.domain.session === (session.token.sub + '@' + session.token.iss)) { sess = session; return session; } }); if (sess) { prom = Auth.get(sess).then(function (oauth3) { return oauth3.api('dns.set', { sld: sld, tld: tld, sub: ('' + result.data.prefix), type: 'TXT', ttl: 300, value: result.data.challenge }); }); } } if (!prom) { def = $q.defer(); // must validate manually window.alert( "Please set a TXT record for '" + ('' + result.data.prefix) + '.' + sld + '.' + tld + "' with the value '" + result.data.challenge + "' and then continue." ); def.resolve(); prom = def.promise; } return prom.then(function () { return pkg.claim(domainReq).then(function (result) { return vm._uploadFileVm(pkg, vm); }); }); }); }; vm.Sites.setUpload = function (r) { console.log("Hey! At least it can tell if there's a change!"); if (r.newFile === undefined) { r.newFile = vm.newFile; } analyzeFile(r.newFile, r); console.log(r); }; vm.cleanUploads = function (r) { vm.folderName = ''; }; vm.Sites.allContents = function (r) { vm.copyR = r; var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.contents({ hostname: r.domain , domain: r.domain , tld: r.tld , sld: r.sld //, sub: r.sub , path: r.shareAccess.path }).then(function (result) { vm.cleanArrays(); vm.folderStructure = result; result.data.forEach(function(data){ if (data.file) { vm.siteFiles.push(data.name); } if (data.directory) { vm.siteDirectories.push(data.name); } }); vm.displaySpinner = 'hidden'; vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1]; }); }; var cleanPathQuery = function (path) { vm.cleanedPath = path.replace(/\/+/g, '/'); return vm.cleanedPath; }; vm.closeFileUploadsContainers = function () { vm.uploadFolderContainer = false; vm.uploadFileContainer = false; }; vm.Sites.contents = function (r, dir) { vm.siteFiles = []; vm.siteDirectories = []; dir = dir + '/'; cleanPathQuery(dir); dir = vm.cleanedPath; vm.previousSearchQuery = dir; vm.displaySpinner = ''; var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.contents({ hostname: r.domain, domain: r.domain, tld: r.tld, sld: r.sld, // sub: r.sub, path: dir }).then(function (result) { vm.cleanArrays(); vm.displaySpinner = 'hidden'; vm.folderStructure = result; result.data.forEach(function(data){ if (data.file) { vm.siteFiles.push(data.name); } if (data.directory) { vm.siteDirectories.push(data.name); } }); vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1]; }); }; var crumbsCleanUp = function (crumb) { var str2arryQuery = cleanPathQuery(vm.breadcrumbsPath.join('/')); var str2arry = vm.breadcrumbs; str2arryQuery = str2arryQuery.split('/'); if (vm.copyR.shareAccess.path !== '/') { var removeFromBreadcrumbsQuery = str2arryQuery.indexOf(crumb) + 1; var removeFromBreadcrumbs = str2arry.indexOf(crumb) + 1; vm.breadcrumbsPath = str2arryQuery.splice(0,removeFromBreadcrumbsQuery); vm.breadcrumbs = str2arry.splice(0,removeFromBreadcrumbs); var strictPath = vm.strictPath.slice(0, -1); if (vm.breadcrumbsPath.join('/').indexOf(strictPath) !== 0) { vm.breadcrumbsPath = strictPath.split('/'); vm.breadcrumbs = strictPath.split('/'); vm.breadcrumbs.shift(); var result = { data: { warning: true } }; vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 2]; var msg = "You can only view inside the " + "'" + vm.currentFolder + "'" + ' folder.'; vm.buildNotification(result, msg); } } else { var removeFromBreadcrumbsQuery = str2arryQuery.indexOf(crumb) + 1; var removeFromBreadcrumbs = str2arry.indexOf(crumb) + 1; vm.breadcrumbsPath = str2arryQuery.splice(0,removeFromBreadcrumbsQuery); vm.breadcrumbs = str2arry.splice(0,removeFromBreadcrumbs); } }; var removeFolderCrumbsCleanUp = function (crumb) { var str2arryQuery = cleanPathQuery(vm.breadcrumbsPath.join('/')); var str2arry = vm.breadcrumbs; str2arryQuery = str2arryQuery.split('/'); var removeFromBreadcrumbsQuery = str2arryQuery.indexOf(crumb); var removeFromBreadcrumbs = str2arry.indexOf(crumb); vm.breadcrumbsPath = str2arryQuery.splice(0,removeFromBreadcrumbsQuery); vm.breadcrumbs = str2arry.splice(0,removeFromBreadcrumbs); vm.copyR.fromFolder = vm.breadcrumbsPath.join('/'); vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1]; }; vm.getDirectoriesFromBreadcrumbs = function (dir) { crumbsCleanUp(dir); cleanPathQuery(vm.breadcrumbsPath.join('/')); vm.Sites.contents(vm.copyR, vm.cleanedPath); vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1]; }; vm.getDirectories = function (dir) { vm.breadcrumbs.push(dir); vm.breadcrumbsPath.push(dir); cleanPathQuery(vm.breadcrumbsPath.join('/')); vm.Sites.contents(vm.copyR, vm.cleanedPath); vm.currentFolder = vm.breadcrumbs[vm.breadcrumbs.length - 1]; }; vm.removeAllFiles = function (r, opts) { opts = { path: '/', confirm: true }; vm.Sites.remove(r, opts); }; vm.deleteFilesFrom = function (r, file) { vm.pathRemoved = file; var path = vm.breadcrumbsPath.join('/'); path = path + '/' + file; path = cleanPathQuery(path); var opts = { path: path }; vm.Sites.remove(r, opts); }; vm.deleteFromInsideOfFolder = false; vm.triggerDeleteFolder = function (path, r) { removeFolderCrumbsCleanUp(path); vm.deleteFromInsideOfFolder = true; path = vm.previousSearchQuery; var opts = { path: path }; vm.cleanArrays(); vm.Sites.remove(r, opts); }; vm.Sites.remove = function (r, opts) { if (!window.confirm("Delete files for this site?")) { return; } var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.remove({ hostname: r.domain , domain: r.domain , tld: r.tld , sld: r.sld //, sub: vm.record.sub , path: opts.path || r.path , confirm: opts.confirm || r.confirm }).then(function (result) { vm.cleanArrays(); if (vm.deleteFromInsideOfFolder) { cleanPathQuery(vm.copyR.fromFolder); vm.Sites.contents(vm.copyR, vm.cleanedPath); } else { cleanPathQuery(vm.breadcrumbsPath.join('/')); vm.Sites.contents(vm.copyR, vm.cleanedPath); } }); }; vm.Sites.archive = function (r) { var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.archive({ hostname: r.domain , domain: r.domain , tld: r.tld , sld: r.sld //, sub: vm.record.sub //, path: vm.uploadPath }).then(function (result) { window.alert(JSON.stringify(result)); // TODO use iframe to initiate download? window.open(result.data.url); }); }; vm.shareFolderFrom = function (r, opts) { var sharePath; if (vm.breadcrumbsPath.join('/') === '' && vm.breadcrumbs.join('/') === '') { sharePath = '/'; } else { sharePath = cleanPathQuery(vm.breadcrumbsPath.join('/')); sharePath = sharePath + '/'; } cleanPathQuery(sharePath); opts = { sharePath: vm.cleanedPath, shareMode: vm.copiedShareMode }; vm.Shares.invite(r, opts); }; vm.createNewFolder = function (r) { r.folderName = vm.folderName; vm.breadcrumbsPath.push(r.folderName); }; vm.Sites.upload = function (r) { var pkg = Auth.oauth3.pkg('www@daplie.com'); cleanPathQuery(vm.breadcrumbsPath.join('/')) r.uploadPath = vm.cleanedPath; vm._uploadFile(pkg, r); }; vm.Shares = {}; vm.Shares.invite = function (r, opts) { var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.invite({ comment: r.shareEmail , email: r.shareEmail , domain: r.domain , tld: r.tld , sld: r.sld //, sub: r.sub , path: opts.sharePath || r.sharePath , mode: opts.shareMode || r.shareMode }).then(function (result) { var arr = r.sharedWith || []; arr.push(result.data); r.sharedWith = arr; window.alert(JSON.stringify(result.data)); }); }; vm.Shares.accept = function () { var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.acceptInvite({ token: vm.Shares.inviteToken }).then(function (result) { window.alert(JSON.stringify(result)); vm.listSites(); }); }; vm.Shares.list = function (r) { var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.listShares({ domain: r.domain , hostname: r.domain , tld: r.tld , sld: r.sld //, sub: r.sub , path: r.sharePath }).then(function (result) { vm.displaySpinner = 'hidden'; console.log('list shares result:'); console.log(result); r.sharedWith = result.data; //r.usersnames = r.sharedWith.map().join(','); }); }; vm.deleteWebsite = function (r, s) { if (!window.confirm("Delete this site?")) { return; } vm.Shares.remove(r, s); }; vm.Shares.remove = function (r, s) { console.log('Shares.remove'); var pkg = Auth.oauth3.pkg('www@daplie.com'); return pkg.removeShare({ domain: s.domain , hostname: s.domain , tld: s.tld , sld: s.sld //, sub: r.sub , path: s.sharePath , challenge: s.challenge }).then(function (result) { var person = result.data.comment; var msg = "revoked access from " + person; vm.buildNotification(result, msg); console.log('remove share result:'); console.log(result); var index; r.sharedWith.forEach(function (_s, i) { if (s.challenge === _s.challenge) { index = i; } }); r.sharedWith.splice(index, 1); //r.usersnames = r.sharedWith.map().join(','); }); }; vm.listSites = function () { var sites = []; return $q.all(Auth.sessions.map(function (session) { return Auth.get(session).then(function (oauth3) { var pkg = oauth3.pkg('www@daplie.com'); return pkg.list().then(function (result) { var _sites = result.data; if (Array.isArray(_sites)) { sites = _sites.concat(sites); return; } console.error('_sites is not an array'); console.error(_sites); }, function (err) { console.error('_sites had an error'); console.error(err); }); }); })).then(function () { sites.forEach(function (site) { site.pending = !domainIsVerified(site); }); console.log('[listSites] sites:'); console.log(sites); vm.sites = sites; vm.sites.forEach(function(site) { site.urlSafeDomain = "https://" + site.domain; site.urlSafeDomain = $sce.trustAsResourceUrl(site.urlSafeDomain); }); }); }; //vm.getDomains(); Auth.api('domains.list', {}).then(function (els) { // console.log('[init] domains.list els:'); // console.log(els); vm.domains = els; $scope.domain = vm.domains; }); vm.listSites(); vm.triggerDropdown = function() { $timeout(function() { var el = document.querySelector('.trigger-dropdown'); angular.element(el).triggerHandler('focus'); }, 0); }; vm.cleanArrays = function () { vm.breadcrumbsPath = []; vm.breadcrumbs = []; vm.siteFiles = []; vm.siteDirectories = []; if (vm.previousSearchQuery === undefined) { vm.previousSearchQuery = ''; } var getBreadcrumbsPath = vm.previousSearchQuery; vm.breadcrumbsPath = getBreadcrumbsPath.split('/'); var getBreadcrumbs = vm.previousSearchQuery.split('/'); getBreadcrumbs.forEach(function(crumb){ if(crumb !== '') { vm.breadcrumbs.push(crumb); } }); if (vm.copyR.shareAccess.path !== '/') { } else { vm.breadcrumbs.unshift('root'); } }; vm.checkShareRights = function (r) { if (r.invitedBy) { r.shareAccess = { write: false, read: false, invite: false }; if (r.mode.includes('w')) { r.shareAccess.write = true; } if (r.mode.includes('r')) { r.shareAccess.read = true; } if (r.mode.includes('x')) { r.shareAccess.invite = true; } r.shareAccess.path = r.path; vm.strictPath = r.shareAccess.path; vm.previousSearchQuery = vm.strictPath; console.log(r.shareAccess); } else { r.shareAccess = { write: true, read: true, invite: true, path: '/' }; } }; $scope.$watch('vm.selectedDomain', function (domainSelected) { if (domainSelected !== undefined) { vm.dom = domainSelected; vm.selectDomain(vm.selectedDomain.description); } }); vm.getSharedAccess = function (access) { vm.accessLevelArry = []; vm.prettyAccessArray = []; access.forEach(function(letter) { vm.prettyAccessArray.push(letter.name); vm.accessLevelArry.push(letter.value); }); vm.prettyShareMode = vm.prettyAccessArray.join(", "); vm.copiedShareMode = vm.accessLevelArry.join(","); }; $scope.selectedAccess = []; $scope.accessLevel = [{ name: 'Read', value: 'r' }, { name: 'Write', value: 'w' }, { name: 'Invite', value: 'x' }]; $scope.localDomainSearch = function(str, domain) { var matches = []; domain.forEach(function(domain) { if ((domain.domain.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0)) { matches.push(domain); } }); return matches; }; vm.showAction = function (action) { switch(action) { case 'invite': vm.showInviteContainer = true; vm.websiteTiles = true; vm.showBackBtn = true; vm.displayFileTree = true; if (vm.currentFolder === undefined || vm.currentFolder === 'hidden' || vm.currentFolder === 'root') { vm.currentFolder = 'All Folders/Files'; } break; case 'shares': vm.showSharesContainer = true; vm.websiteTiles = true; vm.showBackBtn = true; break; case 'files': vm.showFilesContainer = true; vm.websiteTiles = true; vm.showBackBtn = true; break; default: } }; vm.buildNotification = function (result, msg) { if (result.data.error) { vm.alertNotification = { className: 'danger', title: 'Error', hidden: '', message: msg }; } else if (result.data.warning) { vm.alertNotification = { className: 'warning', title: 'Warning', hidden: '', message: msg }; } else if (result.data.info) { vm.alertNotification = { className: 'info', title: 'Info', hidden: '', message: msg }; } else { vm.alertNotification = { className: 'success', title: 'Success', hidden: '', message: msg }; } }; vm.closeAllOpenActions = function () { $timeout(function() { vm.showInviteContainer = false; vm.showSharesContainer = false; vm.showFilesContainer = false; vm.displayFileTree = false; vm.websiteTiles = false; vm.showBackBtn = false; vm.autoPopulateWebPath = ''; }, 150); }; }]); }()); app.filter('stringify', function() { function getSerialize (fn, decycle) { var seen = [], keys = []; decycle = decycle || function(key, value) { return '[Parent REFERENCE]: ' + value.id; }; return function(key, value) { var ret = value; if (typeof value === 'object' && value) { if (seen.indexOf(value) !== -1) ret = decycle(key, value); else { seen.push(value); keys.push(key); } } if (fn) ret = fn(key, ret); return ret; }; } function getPath (value, seen, keys) { var index = seen.indexOf(value); var path = [ keys[index] ]; for (index--; index >= 0; index--) { if (seen[index][ path[0] ] === value) { value = seen[index]; path.unshift(keys[index]); } } return '~' + path.join('.'); } function stringify(obj, fn, spaces, decycle) { return JSON.stringify(obj, getSerialize(fn, decycle), spaces); } stringify.getSerialize = getSerialize; return function(ob) { return stringify(ob, undefined, 2); }; }); app.filter('capitalize', function() { return function(input) { return (!!input) ? input.charAt(0).toUpperCase() + input.substr(1).toLowerCase() : ''; }; }); app.filter('prettyShareMode', function() { return function(input) { var newArry = []; var arry = input.split(','); arry.forEach(function(action){ if (action.includes('w')) { newArry.push('Write'); } if (action.includes('r')) { newArry.push('Read'); } if (action.includes('x')) { newArry.push('Invite'); } }); return newArry.join(', '); }; });