Merge branch 'authsso' into forcemfa

This commit is contained in:
yflory 2023-12-11 16:30:18 +01:00
commit e2dd7f6305
16 changed files with 144 additions and 89 deletions

View File

@ -48,7 +48,7 @@ define([
]),
h('div.extra', [
(Config.restrictRegistration?
undefined:
h('div'):
h('a#register', {
href: "/register/",
}, Msg.login_register)
@ -56,13 +56,14 @@ define([
h('button.login', Msg.login_login),
]),
]),
h('div.col-md-3'),
h('div.col-md-3'+ssoEnabled),
h('div#ssoForm.form-group.col-md-6'+ssoEnabled, [
h('div.cp-login-sso', Msg.sso_login_description)
]),
h('div.col-md-3')
h('div.col-md-3'+ssoEnabled),
]),
h('div.row', [
h('div.row.cp-login-encryption', [
h('div.col-md-3'),
h('div.col-md-6', Msg.register_warning_note),
h('div.col-md-3'),

View File

@ -30,22 +30,21 @@ define([
return frame([
h('div.row', [
h('div.hidden.col-md-3'),
h('div#userForm.form-group.col-md-6', [
h('div.cp-ssoauth-pw', [
h('p.register', Msg.ssoauth_form_hint_register),
h('p.login', Msg.ssoauth_form_hint_login),
h('input.form-control#password', {
type: 'password',
placeholder: Msg.login_password,
}),
h('input.form-control.register#passwordconfirm', {
type: 'password',
placeholder: Msg.login_confirm,
}),
h('div.cp-ssoauth-button',
h('button.btn.btn-primary#cp-ssoauth-button', Msg.continue)
)
]),
h('div#userForm.form-group.col-md-6.cp-ssoauth-pw', [
h('p.cp-isregister.cp-login-instance', Msg.ssoauth_form_hint_register),
h('p.cp-islogin.cp-login-instance', Msg.ssoauth_form_hint_login),
h('input.form-control#password', {
type: 'password',
placeholder: Msg.login_password,
}),
h('input.form-control.cp-isregister#passwordconfirm', {
type: 'password',
placeholder: Msg.login_confirm,
}),
h('div.cp-ssoauth-button.extra',
h('div'),
h('button.login#cp-ssoauth-button', Msg.continue)
)
]),
h('div.hidden.col-md-3'),
])

View File

@ -0,0 +1,50 @@
@import (reference) "../include/infopages.less";
@import (reference) "../include/colortheme-all.less";
@import (reference) "../include/alertify.less";
@import (reference) "../include/forms.less";
.login_main() {
#userForm, #ssoForm {
.cp-shadow();
background-color: @cp_static-card-bg;
padding: 10px;
margin: 0;
border-radius: @infopages-radius-L;
.cp-login-instance, .cp-login-sso-description {
margin-bottom: 5px;
}
.form-control {
border-radius: @infopages-radius;
color: @cryptpad_text_col;
background-color: @cp_forms-bg;
margin-bottom: 10px;
&:focus {
border-color: @cryptpad_color_brand;
}
.tools_placeholder-color();
}
.checkbox-container {
color: @cryptpad_text_col;
}
}
#ssoForm {
margin-top: 10px;
button {
margin: 0 5px;
}
.cp-login-sso {
display: flex;
align-items: center;
}
}
.cp-default-label {
display: none;
}
.extra {
margin-top: 1em;
button.login {
margin-right: 0px;
}
}
}

View File

@ -3,6 +3,7 @@
@import (reference) "../include/alertify.less";
@import (reference) "../include/checkmark.less";
@import (reference) "../include/forms.less";
@import (reference) "../include/login.less";
&.cp-page-login {
.infopages_main();
@ -22,47 +23,15 @@
.cp-hidden {
display: none !important;
}
#userForm, #ssoForm {
.cp-shadow();
background-color: @cp_static-card-bg;
padding: 10px;
margin: 0 10px 10px 10px;
border-radius: @infopages-radius-L;
.cp-login-instance, .cp-login-sso-description {
margin-bottom: 5px;
}
.form-control {
border-radius: @infopages-radius;
color: @cryptpad_text_col;
background-color: @cp_forms-bg;
margin-bottom: 10px;
&:focus {
border-color: @cryptpad_color_brand;
}
.tools_placeholder-color();
}
.checkbox-container {
color: @cryptpad_text_col;
}
}
#ssoForm {
button {
margin: 0 5px;
}
}
.login_main();
.align-items-center {
box-shadow: 0 5px 15px @cp_shadow-color;
background: @cryptpad_color_white;
}
.extra {
margin-top: 1em;
button.login {
margin-right: 0px;
}
}
.cp-default-label {
display: none;
}
}
.cp-login-encryption {
margin-top: 10px;
}
.cp-password-form {

View File

@ -3,6 +3,7 @@
@import (reference) "../include/alertify.less";
@import (reference) "../include/checkmark.less";
@import (reference) "../include/forms.less";
@import (reference) "../include/login.less";
&.cp-page-register {
.infopages_main();
@ -88,37 +89,21 @@
.cp-hidden {
display: none !important;
}
.login_main();
#userForm, #ssoForm {
padding: 15px;
background-color: @cp_static-card-bg;
position: relative;
z-index: 2;
//margin-bottom: 100px;
border-radius: @infopages-radius-L;
max-width: 100%;
.cp-shadow();
.form-control {
border-radius: @infopages-radius;
color: @cryptpad_text_col;
background-color: @cp_forms-bg;
margin-bottom: 10px;
&:focus {
border-color: @cryptpad_color_brand;
}
.tools_placeholder-color();
}
padding: 15px;
.checkbox-container {
margin-top: 0.5rem;
color: @cryptpad_text_col;
}
button#register {
margin-top: 10px;
}
}
#ssoForm {
button {
margin: 0 5px;
}
margin-top: 15px;
}
.cp-register-notes {

View File

@ -2,28 +2,47 @@
@import (reference) "../include/colortheme-all.less";
@import (reference) "../include/alertify.less";
@import (reference) "../include/forms.less";
@import (reference) "../include/login.less";
&.cp-page-ssoauth {
.infopages_main();
.forms_main();
.alertify_main();
.form-group {
.extra {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
}
div.cp-ssoauth-pw {
display: none;
width: 100%;
}
&.cp-regsiter {
.login {
.cp-container {
.login_main();
}
&.cp-register {
.cp-islogin {
display: none;
}
#passwordconfirm {
margin-bottom: 0px !important;
}
}
&.cp-login {
.register {
.cp-isregister {
display: none;
}
#password {
margin-bottom: 0px !important;
}
}
}

View File

@ -9,8 +9,9 @@ const Core = require("./commands/core");
const Metadata = require("./commands/metadata");
const Meta = require("./metadata");
const Logger = require("./log");
const plugins = require("./plugin-manager");
let SSOUtils; try { SSOUtils = require("./plugins/sso/sso-utils"); } catch (e) {}
let SSOUtils = plugins.SSO && plugins.SSO.utils;
const Path = require("path");
const Fse = require("fs-extra");

View File

@ -10,8 +10,6 @@ const BlockStore = require("../storage/block");
const Block = require("../commands/block");
const config = require("../load-config");
let SSOUtils; try { SSOUtils = require("../plugins/sso/sso-utils"); } catch (e) {}
const Commands = module.exports;
var isString = s => typeof(s) === 'string';
@ -66,6 +64,7 @@ var EXPIRATION = (config.otpSessionExpiration || 7 * 24) * 3600 * 1000;
// Create a session with a token for the given public key
const makeSession = (Env, publicKey, oldKey, ssoSession, cb) => {
const sessionId = ssoSession || Sessions.randomId();
let SSOUtils = Env.plugins && Env.plugins.SSO && Env.plugins.SSO.utils;
// For password change, we need to get the sso session associated to the old block key
// In other cases (login and totp_setup), the sso session is associated to the current block

View File

@ -15,8 +15,6 @@ const ArchiveAccount = require('../archive-account');
const { Worker } = require('node:worker_threads');
/* jshint ignore:end */
let SSOUtils; try { SSOUtils = require("../plugins/sso/sso-utils"); } catch (e) {}
var Fs = require("fs");
var Admin = module.exports;
@ -724,6 +722,7 @@ var archiveBlock = function (Env, Server, cb, data) {
});
cb(err);
});
let SSOUtils = Env.plugins && Env.plugins.SSO && Env.plugins.SSO.utils;
if (SSOUtils) { SSOUtils.deleteAccount(Env, key, () => {}); }
};
@ -741,6 +740,7 @@ var restoreArchivedBlock = function (Env, Server, cb, data) {
});
// Also restore SSO data
let SSOUtils = Env.plugins && Env.plugins.SSO && Env.plugins.SSO.utils;
if (SSOUtils) { SSOUtils.restoreAccount(Env, key, () => {}); }
cb(err);

View File

@ -6,8 +6,6 @@ const nThen = require("nthen");
const Util = require("../common-util");
const BlockStore = require("../storage/block");
let SSOUtils; try { SSOUtils = require("../plugins/sso/sso-utils"); } catch (e) {}
var isString = s => typeof(s) === 'string';
Block.isValidBlockId = id => {
return id && isString(id) && id.length === 44;
@ -191,6 +189,8 @@ Block.removeLoginBlock = function (Env, publicKey, reason, _cb) {
// is already deleted anyway.
// If this is NOT a password change, also delete sso user.
let SSOUtils = Env.plugins && Env.plugins.SSO && Env.plugins.SSO.utils;
if (!SSOUtils) { return; }
if (reason !== 'PASSWORD_CHANGE') {
SSOUtils.deleteAccount(Env, publicKey, () => {});

View File

@ -14,6 +14,8 @@ const Package = require("../package.json");
const Default = require("./defaults");
const Path = require("path");
const plugins = require('./plugin-manager');
const Nacl = require("tweetnacl/nacl-fast");
var canonicalizeOrigin = function (s) {
@ -79,6 +81,7 @@ module.exports.create = function (config) {
const curve = Nacl.box.keyPair();
const Env = {
plugins: plugins,
logFeedback: Boolean(config.logFeedback),
mainPages: config.mainPages || Default.mainPages(),

View File

@ -1,5 +1,6 @@
var Nacl = require("tweetnacl/nacl-fast");
var Util = require('./common-util.js');
const plugins = require("./plugin-manager");
var Challenge = require("./storage/challenge.js");
// C.read(Env, id, cb)
@ -75,7 +76,7 @@ COMMANDS.TOTP_REMOVE_BLOCK = TOTP.TOTP_REMOVE_BLOCK;
try {
// SSO plugin may not be installed
const SSO = require("./plugins/sso/challenge.js");
const SSO = plugins.SSO && plugins.SSO.challenge;
COMMANDS.SSO_AUTH = SSO.SSO_AUTH;
COMMANDS.SSO_AUTH_CB = SSO.SSO_AUTH_CB;
COMMANDS.SSO_WRITE_BLOCK = SSO.SSO_WRITE_BLOCK; // Account creation only

View File

@ -13,13 +13,15 @@ const cookieParser = require("cookie-parser");
const bodyParser = require('body-parser');
const BlobStore = require("./storage/blob");
const BlockStore = require("./storage/block");
const plugins = require("./plugin-manager");
const DEFAULT_QUERY_TIMEOUT = 5000;
const PID = process.pid;
let SSOUtils; try { SSOUtils = require("./plugins/sso/sso-utils"); } catch (e) {}
let SSOUtils = plugins.SSO && plugins.SSO.utils;
var Env = JSON.parse(process.env.Env);
Env.plugins = plugins;
const response = Util.response(function (errLabel, info) {
if (!Env.Log) { return; }
Env.Log.error(errLabel, info);

18
lib/plugin-manager.js Normal file
View File

@ -0,0 +1,18 @@
const fs = require('node:fs');
const plugins = {};
try {
let pluginsDir = fs.readdirSync(__dirname + '/plugins');
pluginsDir.forEach((name) => {
try {
let plugin = require(`./plugins/${name}/index`);
plugins[plugin.name] = plugin.modules;
} catch (err) {
console.error(err);
}
});
} catch (err) {
if (err.code !== 'ENOENT') { console.error(err); }
}
module.exports = plugins;

View File

@ -40,6 +40,10 @@ define([
return b;
});
$sso.append(list);
// Disable bfcache (back/forward cache) to prevent SSO button
// being disabled when using the browser "back" feature on the SSO page
$(window).on('unload', () => {});
}
/* Log in UI */

View File

@ -70,6 +70,10 @@ define([
return b;
});
$sso.append(list);
// Disable bfcache (back/forward cache) to prevent SSO button
// being disabled when using the browser "back" feature on the SSO page
$(window).on('unload', () => {});
}
var registerClick = function () {