cryptpad/www/install/onboardscreen.js

501 lines
17 KiB
JavaScript
Raw Normal View History

2024-06-27 01:11:54 +08:00
// SPDX-FileCopyrightText: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
//
// SPDX-License-Identifier: AGPL-3.0-or-later
2024-05-21 07:13:55 +08:00
define([
'jquery',
'/common/inner/sidebar-layout.js',
'/customize/messages.js',
'/customize/application_config.js',
2024-05-21 07:13:55 +08:00
'/common/hyperscript.js',
2024-05-28 23:45:58 +08:00
'/common/common-interface.js',
'/common/common-util.js',
2024-06-19 22:12:22 +08:00
'/common/common-ui-elements.js',
2024-06-20 00:11:55 +08:00
'/common/pad-types.js',
2024-06-20 23:55:20 +08:00
'/components/nthen/index.js',
2024-05-21 07:13:55 +08:00
'css!/components/bootstrap/dist/css/bootstrap.min.css',
'css!/components/components-font-awesome/css/font-awesome.min.css',
2024-06-15 01:35:51 +08:00
2024-05-21 07:13:55 +08:00
], function(
$,
Sidebar,
Messages,
AppConfig,
2024-05-21 07:13:55 +08:00
h,
2024-05-28 23:45:58 +08:00
UI,
Util,
2024-06-20 00:11:55 +08:00
UIElements,
2024-06-20 23:55:20 +08:00
PadTypes,
nThen
2024-05-24 23:36:34 +08:00
) {
2024-05-21 07:13:55 +08:00
let pages = [];
const gotoPage = function (Env, page) {
if (typeof(page) !== "number" || !page) { page = 0; }
if (page > (pages.length - 1)) { page = pages.length - 1; }
2024-05-24 20:36:19 +08:00
2024-06-15 01:35:51 +08:00
var nextPageFunction = pages[page];
var nextPageForm = nextPageFunction(Env);
let frame = h('div.cp-onboarding-box', nextPageForm);
Env.overlay.empty().append(frame);
2024-06-15 01:35:51 +08:00
};
const blocks = Sidebar.blocks('admin');
2024-06-07 19:00:30 +08:00
2024-06-20 23:55:20 +08:00
var flushCache = (Env, cb) => {
const { sendAdminRpc } = Env;
sendAdminRpc('FLUSH_CACHE', {}, function (e, response) {
if (e || response.error) {
console.error(e || response.error);
}
cb();
});
2024-06-20 08:59:53 +08:00
};
var selections = {
title: '',
description: '',
logoURL: '',
color: '',
appsToDisable: [],
mfa: false,
closeRegistration: false
};
2024-06-20 00:11:55 +08:00
2024-06-20 23:55:20 +08:00
const saveAndRedirect = (Env) => {
const { sendAdminDecree, sendAdminRpc } = Env;
2024-05-29 01:43:17 +08:00
2024-06-20 23:55:20 +08:00
let hasError = false;
let error = () => {
hasError = true;
};
nThen(waitFor => {
var name = selections.title;
if (!name) { return; }
sendAdminDecree('SET_INSTANCE_NAME', [name], waitFor((e, response) => {
if (e || response.error) {
console.error(e || response.error);
return void error();
}
}));
}).nThen(waitFor => {
var description = selections.description;
if (!description) { return; }
sendAdminDecree('SET_INSTANCE_DESCRIPTION', [
description
], waitFor((e, response) => {
if (e || response.error) {
console.error(e || response.error);
return void error();
}
}));
}).nThen(waitFor => {
var dataURL = selections.logoURL;
if (!dataURL) { return; }
sendAdminRpc('UPLOAD_LOGO', {dataURL}, waitFor(function (e, response) {
if (e || response.error) {
console.error(e || response.error);
return void error();
}
}));
}).nThen(waitFor => {
var color = selections.color;
if (!color) { return; }
sendAdminRpc('CHANGE_COLOR', {color}, waitFor(function (e, response) {
if (e || response.error) {
console.error(e || response.error);
return void error();
}
}));
}).nThen(waitFor => {
var apps = selections.appsToDisable;
if (!apps.length) { return; }
sendAdminDecree('DISABLE_APPS', apps, waitFor(function (e, response) {
if (e || response.error) {
UI.warn(Messages.error);
return;
}
}));
}).nThen(waitFor => {
if (!selections.mfa) { return; }
sendAdminDecree('ENFORCE_MFA', [selections.mfa], waitFor((e, response) => {
if (e || response.error) {
UI.warn(Messages.error);
return;
}
}));
}).nThen(waitFor => {
if (!selections.closeRegistration) { return; }
sendAdminDecree('RESTRICT_REGISTRATION', [
selections.closeRegistration
], waitFor(function (e, response) {
if (e || response.error) {
UI.warn(Messages.error);
return;
}
}));
}).nThen(() => {
flushCache(Env, function () {
if (hasError) {
UI.alert(Messages.onboarding_save_error, function () {
document.location.href = '/drive/';
2024-06-24 20:32:54 +08:00
});
2024-06-20 23:55:20 +08:00
return;
}
document.location.href = '/drive/';
});
});
};
const titleConfig = function (Env) {
let titleInput = blocks.input({
type: 'text',
value: selections.title,
placeholder: Messages.admin_onboardingNamePlaceholder,
'aria-labelledby': 'cp-admin-name'
});
let description = blocks.textarea({
placeholder: Messages.admin_onboardingDescPlaceholder,
'aria-labelledby': 'cp-admin-description'
}, selections.description);
$(description).addClass('cp-onboardscreen-desc');
let dataURL = selections.logoURL;
var getLogoBlock = function() {
2024-06-03 20:26:59 +08:00
let inputLogo = blocks.input({
type: 'file',
accept: 'image/*',
'aria-labelledby': 'cp-admin-logo'
});
var currentContainer = blocks.block([], 'cp-admin-customize-logo');
var upload = blocks.button('secondary', '', Messages.onboarding_upload);
2024-06-03 20:26:59 +08:00
let formLogo = blocks.form([
currentContainer,
blocks.block(inputLogo, 'cp-onboarding-logo-input'),
blocks.nav([upload])
2024-06-03 20:26:59 +08:00
]);
let $button = $(upload);
let state = false;
let redraw = () => {
var current = h('img', {src: dataURL || '/api/logo?'+(+new Date())});
$(currentContainer).empty().append(current);
$button.removeAttr('disabled');
state = !!dataURL;
if (dataURL) {
$button.text(Messages.admin_logoRemoveButton);
$button.removeClass('btn-secondary').addClass('btn-danger-alt');
} else {
$button.text(Messages.onboarding_upload);
$button.removeClass('btn-danger-alt').addClass('btn-secondary');
}
};
redraw();
let $input = $(inputLogo);
$input.on('change', function () {
2024-06-03 20:26:59 +08:00
let files = inputLogo.files;
if (files.length !== 1) {
UI.warn(Messages.error);
return;
}
let reader = new FileReader();
reader.onloadend = function () {
2024-06-20 08:59:53 +08:00
dataURL = this.result;
redraw(dataURL);
2024-06-03 20:26:59 +08:00
};
reader.readAsDataURL(files[0]);
});
Util.onClickEnter($button, function () {
$button.attr('disabled', 'disabled');
if (!state) {
return void $input.click();
}
dataURL = '';
redraw();
2024-06-03 20:26:59 +08:00
});
2024-05-28 23:45:58 +08:00
2024-06-15 01:35:51 +08:00
return formLogo;
};
2024-06-03 20:26:59 +08:00
var getColorBlock = function () {
2024-06-07 19:00:30 +08:00
2024-06-24 17:53:51 +08:00
// Number of accent color presets
var colors = UIElements.makePalette(4, (color, $color) => {
2024-06-19 22:12:22 +08:00
let rgb = $color.css('background-color');
let hex = Util.rgbToHex(rgb);
2024-06-20 08:59:53 +08:00
if (hex) {
2024-06-20 23:55:20 +08:00
selections.color = color ? hex : '';
selections.colorId = color;
2024-06-20 08:59:53 +08:00
}
2024-06-19 22:12:22 +08:00
});
if (selections.colorId) {
colors.setValue(selections.colorId);
}
2024-06-18 17:44:18 +08:00
var content = h('div.cp-onboardscreen-colorpick', [
2024-06-19 22:12:22 +08:00
h('label', {for:'cp-install-color'}, Messages.kanban_color),
colors
2024-06-18 17:44:18 +08:00
]);
2024-06-15 01:35:51 +08:00
return content;
};
2024-05-28 23:45:58 +08:00
2024-06-24 20:32:54 +08:00
var button = blocks.activeButton('primary', '', Messages.continue, function () {
selections.title = $(titleInput).val() || '';
selections.description = $(description).val() || '';
2024-06-20 08:59:53 +08:00
if (dataURL) {
2024-06-20 20:46:52 +08:00
selections.logoURL = dataURL;
}
2024-06-03 20:26:59 +08:00
gotoPage(Env, 1);
2024-05-28 23:45:58 +08:00
});
var titleBlock = h('div.cp-onboardscreen-name', titleInput);
var descriptionBlock = h('div', description);
var logoBlock = h('div.cp-onboardscreen-logo', getLogoBlock());
var colorBlock = h('div.cp-onboardscreen-color', getColorBlock());
2024-06-07 19:00:30 +08:00
2024-06-15 01:35:51 +08:00
var screenTitle = h('div.cp-onboardscreen-screentitle');
$(screenTitle).append(('div.cp-onboardscreen-maintitle', [
h('h1.cp-onboardscreen-title', Messages.admin_onboardingNameTitle),
h('span', Messages.admin_onboardingNameHint)
]));
var nav = blocks.nav([h('span'), button]);
2024-06-18 17:44:18 +08:00
$(button).addClass('cp-onboardscreen-save');
2024-06-20 20:46:52 +08:00
$(nav).addClass('cp-onboardscreen-nav');
2024-06-18 17:44:18 +08:00
var textForm = h('div.cp-instance-text-form', [
titleBlock,
descriptionBlock,
colorBlock,
]);
var instanceForm = h('div.cp-instance-form', [logoBlock, textForm]);
var form = blocks.form([
screenTitle,
instanceForm
2024-05-28 23:45:58 +08:00
], nav);
2024-06-15 01:35:51 +08:00
$(form).addClass('cp-onboardscreen-form');
2024-06-06 19:16:01 +08:00
2024-06-15 01:35:51 +08:00
return form;
2024-06-07 19:00:30 +08:00
2024-06-15 01:35:51 +08:00
};
2024-05-28 23:45:58 +08:00
const createAppsGrid = appsToDisable => {
2024-06-18 17:44:18 +08:00
const grid = blocks.block([], 'cp-admin-customize-apps-grid');
const $grid = $(grid);
2024-06-20 00:11:55 +08:00
const allApps = PadTypes.appsToSelect;
let select = function (app, $app) {
2024-06-20 00:11:55 +08:00
if (appsToDisable.indexOf(app) === -1) {
appsToDisable.push(app);
$app.toggleClass('cp-inactive-app', true);
$app.toggleClass('cp-active-app', false);
2024-06-18 17:44:18 +08:00
} else {
2024-06-20 00:11:55 +08:00
appsToDisable.splice(appsToDisable.indexOf(app), 1);
$app.toggleClass('cp-inactive-app', false);
$app.toggleClass('cp-active-app', true);
}
};
2024-06-18 17:44:18 +08:00
allApps.forEach(app => {
let name = Messages.type[app] || app;
let icon = UI.getNewIcon(app);
2024-06-21 17:47:52 +08:00
let appBlock = h('div.cp-appblock',
{tabindex:0, role:"button"},
[
icon,
2024-06-21 17:47:52 +08:00
h('span.cp-app-name', name),
h('i.fa.fa-check.cp-on-enabled')
]);
let $app = $(appBlock).appendTo($grid);
if (appsToDisable.includes(app)) {
$app.addClass('cp-inactive-app');
} else {
$app.addClass('cp-active-app');
}
$app.on('click', () => select(app, $app));
});
2024-06-18 17:44:18 +08:00
return grid;
};
const appConfig = function (Env) {
const appsToDisable = selections.appsToDisable;
const grid = createAppsGrid(appsToDisable);
2024-06-24 20:32:54 +08:00
var save = blocks.activeButton('primary', '', Messages.continue, function () {
gotoPage(Env, 2);
2024-06-18 17:44:18 +08:00
});
var prev = blocks.activeButton('secondary', '', Messages.form_backButton, function () {
gotoPage(Env, 0);
2024-06-18 17:44:18 +08:00
});
var screenTitle = h('div.cp-onboardscreen-screentitle');
$(screenTitle).append(h('div.cp-onboardscreen-maintitle', h('h1.cp-onboardscreen-title', Messages.admin_appsTitle), h('span', Messages.admin_appsHint)));
2024-06-18 17:44:18 +08:00
$(save).addClass('cp-onboardscreen-save');
$(prev).addClass('cp-onboardscreen-prev');
2024-06-20 20:46:52 +08:00
var nav = blocks.nav([prev, save]);
2024-06-18 17:44:18 +08:00
$(nav).addClass('cp-onboardscreen-nav');
let form = blocks.form([
screenTitle,
grid
2024-06-18 17:44:18 +08:00
], nav);
$(form).addClass('cp-onboardscreen-form');
2024-06-18 17:44:18 +08:00
return form;
};
const mfaRegistrationScreen = function (Env) {
2024-05-29 00:48:59 +08:00
var restrict = blocks.activeCheckbox({
key: 'registration',
getState: function () {
2024-06-20 23:09:26 +08:00
return selections.closeRegistration;
2024-05-29 00:48:59 +08:00
},
2024-06-18 20:02:46 +08:00
label: 'registration',
2024-06-20 23:09:26 +08:00
query: function (val, setState) {
2024-06-20 20:46:52 +08:00
selections.closeRegistration = val;
2024-06-24 20:32:54 +08:00
setState(val);
2024-05-29 00:48:59 +08:00
},
});
var forceMFA = blocks.activeCheckbox({
key: 'forcemfa',
getState: function () {
2024-06-20 23:09:26 +08:00
return selections.mfa;
2024-05-29 00:48:59 +08:00
},
2024-06-18 20:02:46 +08:00
label: 'forcemfa',
2024-06-20 23:09:26 +08:00
query: function (val, setState) {
2024-06-20 20:46:52 +08:00
selections.mfa = val;
2024-06-24 20:32:54 +08:00
setState(val);
2024-05-29 00:48:59 +08:00
},
});
2024-06-07 19:00:30 +08:00
2024-06-21 17:47:52 +08:00
let mfaOption = h('div.cp-optionblock', [
2024-06-20 23:09:26 +08:00
forceMFA,
h('span.cp-option-hint', Messages.admin_forcemfaHint)
2024-06-20 23:09:26 +08:00
]);
let registrationOption = h('div.cp-optionblock', [
2024-06-20 23:09:26 +08:00
restrict,
h('span.cp-option-hint', Messages.admin_registrationHint)
2024-06-20 23:09:26 +08:00
]);
const grid = blocks.block([
mfaOption,
registrationOption
], 'cp-admin-customize-options-grid');
2024-06-07 19:00:30 +08:00
2024-06-15 01:35:51 +08:00
var save = blocks.activeButton('primary', '', Messages.settings_save, function () {
2024-06-20 23:55:20 +08:00
saveAndRedirect(Env);
2024-06-15 01:35:51 +08:00
});
2024-05-29 00:48:59 +08:00
var prev = blocks.activeButton('secondary', '', Messages.form_backButton, function () {
gotoPage(Env, 1);
2024-06-15 01:35:51 +08:00
});
var screenTitle = h('div.cp-onboardscreen-screentitle');
2024-06-27 19:58:37 +08:00
$(screenTitle).append(h('div.cp-onboardscreen-maintitle', h('h1.cp-onboardscreen-title', Messages.admin_onboardingOptionsTitle), UI.setHTML(h('span'), Messages.admin_onboardingOptionsHint)));
2024-06-18 17:44:18 +08:00
$(save).addClass('cp-onboardscreen-save');
$(prev).addClass('cp-onboardscreen-prev');
2024-06-20 20:46:52 +08:00
var nav = blocks.nav([prev, save]);
2024-06-18 17:44:18 +08:00
$(nav).addClass('cp-onboardscreen-nav');
2024-06-07 19:00:30 +08:00
2024-06-06 19:16:01 +08:00
var form = blocks.form([
2024-06-15 01:35:51 +08:00
screenTitle,
2024-06-18 17:44:18 +08:00
grid], nav
2024-06-15 01:35:51 +08:00
);
2024-06-07 19:00:30 +08:00
2024-06-15 01:35:51 +08:00
$(form).addClass('cp-onboardscreen-form');
2024-06-06 19:16:01 +08:00
2024-06-15 01:35:51 +08:00
return form;
};
2024-05-29 00:48:59 +08:00
pages = [
titleConfig,
appConfig,
mfaRegistrationScreen
];
const create = (sendAdminDecree, sendAdminRpc) => {
let Env = {
sendAdminDecree,
sendAdminRpc
};
Env.overlay = $(h('div#cp-onboarding'));
gotoPage(Env, 0);
$('body').append(Env.overlay);
};
2024-06-20 23:55:20 +08:00
// XXX test functions to remove
window.CP_onboarding_test = () => {
create(() => {}, () => {});
};
2024-06-20 23:55:20 +08:00
window.CP_onboarding_test_full = () => {
require([
'/common/cryptpad-common.js',
'/common/outer/local-store.js',
'/common/outer/login-block.js',
'/common/rpc.js',
'/common/common-constants.js',
'/common/cryptget.js',
], function (CryptPad, LocalStore, Block, Rpc, Constants, CryptGet) {
var blockHash = LocalStore.getBlockHash();
if (!blockHash) { return void console.error('NOT LOGGED IN'); }
var parsed = Block.parseBlockHash(blockHash);
var sessionToken = LocalStore.getSessionToken() || undefined;
let userHash;
nThen(w => {
// Get user keys
Util.getBlock(parsed.href, {
bearer: sessionToken
}, w((err, response) => {
if (err) {
w.abort();
return void console.error('Please login in and try again');
}
response.arrayBuffer().then(w(arraybuffer => {
arraybuffer = new Uint8Array(arraybuffer);
var block_info = Block.decrypt(arraybuffer, parsed.keys);
userHash = block_info[Constants.userHashKey];
}));
}));
}).nThen(() => {
// Make RPC
if (!userHash) { return void console.error('AUTH FAILED'); }
CryptPad.makeNetwork((err, network) => {
if (err) { return void console.error(err); }
CryptGet.get(userHash, (err, val) => {
let p = Util.tryParse(val);
Rpc.create(network, p.edPrivate, p.edPublic, function (e, rpc) {
let sendAdminDecree = function (command, data, callback) {
var params = ['ADMIN_DECREE', [command, data]];
rpc.send('ADMIN', params, callback);
};
let sendAdminRpc = function (command, data, callback) {
var params = [command, data];
rpc.send('ADMIN', params, callback);
};
create(sendAdminDecree, sendAdminRpc);
});
}, {network: network});
});
});
});
};
return { create, createAppsGrid };
2024-05-24 20:36:19 +08:00
2024-05-21 07:13:55 +08:00
});