'use strict'; /* global angular, $, showdown */ // create main application module var app = angular.module('Application', ['pascalprecht.translate', 'ngCookies']); app.filter('markdown2html', function () { var converter = new showdown.Converter({ simplifiedAutoLink: true, strikethrough: true, tables: true, openLinksInNewWindow: true }); return function (text) { return converter.makeHtml(text); }; }); // disable sce for footer https://code.angularjs.org/1.5.8/docs/api/ng/service/$sce app.config(function ($sceProvider) { $sceProvider.enabled(false); }); app.config(['$translateProvider', function ($translateProvider) { $translateProvider.useStaticFilesLoader({ prefix: 'translation/', suffix: '.json' }); $translateProvider.preferredLanguage('en'); $translateProvider.fallbackLanguage('en'); }]); // Add shorthand "tr" filter to avoid having ot use "translate" // This is a copy of the code at https://github.com/angular-translate/angular-translate/blob/master/src/filter/translate.js // If we find out how to get that function handle somehow dynamically we can use that, otherwise the copy is required function translateFilterFactory($parse, $translate) { var translateFilter = function (translationId, interpolateParams, interpolation, forceLanguage) { if (!angular.isObject(interpolateParams)) { var ctx = this || { '__SCOPE_IS_NOT_AVAILABLE': 'More info at https://github.com/angular/angular.js/commit/8863b9d04c722b278fa93c5d66ad1e578ad6eb1f' }; interpolateParams = $parse(interpolateParams)(ctx); } return $translate.instant(translationId, interpolateParams, interpolation, forceLanguage); }; if ($translate.statefulFilter()) { translateFilter.$stateful = true; } return translateFilter; } translateFilterFactory.displayName = 'translateFilterFactory'; app.filter('tr', translateFilterFactory); app.controller('PasswordResetController', ['$scope', '$translate', '$http', function ($scope, $translate, $http) { // Stupid angular location provider either wants html5 location mode or not, do the query parsing on my own const search = decodeURIComponent(window.location.search).slice(1).split('&').map(function (item) { return item.indexOf('=') === -1 ? [item, true] : [item.slice(0, item.indexOf('=')), item.slice(item.indexOf('=')+1)]; }).reduce(function (o, k) { o[k[0]] = k[1]; return o; }, {}); $scope.initialized = false; $scope.mode = ''; $scope.busy = false; $scope.error = false; $scope.branding = null; $scope.username = ''; $scope.password = ''; $scope.totpToken = ''; $scope.passwordResetIdentifier = ''; $scope.newPassword = ''; $scope.newPasswordRepeat = ''; const API_ORIGIN = window.cloudronApiOrigin || window.location.origin; $scope.onPasswordReset = function () { $scope.busy = true; var data = { identifier: $scope.passwordResetIdentifier }; function done(error) { if (error) $scope.error = error.message; $scope.busy = false; $scope.mode = 'passwordResetDone'; } $http.post(API_ORIGIN + '/api/v1/auth/password_reset_request', data).success(done).error(done); }; $scope.onNewPassword = function () { $scope.busy = true; var data = { resetToken: search.resetToken, password: $scope.newPassword, totpToken: $scope.totpToken }; function error(data, status) { console.log('error', status); $scope.busy = false; if (status === 401) $scope.error = data.message; else if (status === 409) $scope.error = 'Ask your admin for an invite link first'; else $scope.error = 'Unknown error'; } $http.post(API_ORIGIN + '/api/v1/auth/password_reset', data).success(function (data, status) { if (status !== 202) return error(data, status); // set token to autologin localStorage.token = data.accessToken; $scope.mode = 'newPasswordDone'; }).error(function (data, status) { error(data, status); }); }; $scope.showPasswordReset = function () { window.document.title = 'Password Reset Request'; $scope.mode = 'passwordReset'; $scope.passwordResetIdentifier = ''; setTimeout(function () { $('#inputPasswordResetIdentifier').focus(); }, 200); }; $scope.showNewPassword = function () { window.document.title = 'Set New Password'; $scope.mode = 'newPassword'; setTimeout(function () { $('#inputNewPassword').focus(); }, 200); }; $http.get(API_ORIGIN + '/api/v1/auth/branding').success(function (data, status) { $scope.initialized = true; if (status !== 200) return; if (data.language) $translate.use(data.language); $scope.branding = data; }).error(function () { $scope.initialized = false; }); // Init into the correct view if (search.passwordReset) { $scope.showPasswordReset(); } else if (search.resetToken) { $scope.showNewPassword(); } else if (search.accessToken || search.access_token) { // auto-login feature localStorage.token = search.accessToken || search.access_token; window.location.href = '/'; } else { $scope.showPasswordReset(); } }]);