From 18d6ccdfd3802df121d6d66786de39d0c0834a0d Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 23 Jun 2023 17:46:14 +0200 Subject: [PATCH 001/283] SSO: OIDC auth --- .gitignore | 1 + config/sso.example.js | 21 +++ customize.dist/login.js | 33 ++++ customize.dist/pages/login.js | 2 + customize.dist/pages/register.js | 3 +- lib/challenge-commands/sso.js | 105 +++++++++++++ lib/env.js | 2 + lib/http-commands.js | 7 +- lib/http-worker.js | 11 +- lib/load-config.js | 7 + lib/plugins/sso/oidc.js | 67 +++++++++ lib/sso-utils.js | 71 +++++++++ lib/storage/sso.js | 57 +++++++ package-lock.json | 250 ++++++++++++++++--------------- package.json | 2 + www/register/main.js | 27 +++- www/ssoauth/index.html | 14 ++ www/ssoauth/main.js | 3 + 18 files changed, 557 insertions(+), 126 deletions(-) create mode 100644 config/sso.example.js create mode 100644 lib/challenge-commands/sso.js create mode 100644 lib/plugins/sso/oidc.js create mode 100644 lib/sso-utils.js create mode 100644 lib/storage/sso.js create mode 100644 www/ssoauth/index.html create mode 100644 www/ssoauth/main.js diff --git a/.gitignore b/.gitignore index 3ef8d2e15..e42df1b06 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ block/ logs/ privileged.conf config/config.js +config/sso.js *.sh diff --git a/config/sso.example.js b/config/sso.example.js new file mode 100644 index 000000000..a1b7289ab --- /dev/null +++ b/config/sso.example.js @@ -0,0 +1,21 @@ +module.exports = { + // Enable SSO login on this instance + enabled: false, + // Block registration for non-SSO users on this instance + enforced: false, + // Allow users to add an additional CryptPad password to their SSO account + cpPassword: false, + // List of SSO providers + list: [ + /* + { + name: 'google', + type: 'oidc', + url: 'https://accounts.google.com', + client_id: "{your_client_id}", + client_secret: "{your_client_secret}" + } + */ + ] +}; + diff --git a/customize.dist/login.js b/customize.dist/login.js index c8219ed0b..c0b06fa04 100644 --- a/customize.dist/login.js +++ b/customize.dist/login.js @@ -43,6 +43,39 @@ define([ setRedirectTo(); } + Exports.ssoRegister = function (provider, cb) { + var keys = Nacl.sign.keyPair(); + localStorage.CP_sso_auth = JSON.stringify({ + s: Nacl.util.encodeBase64(keys.secretKey), + p: Nacl.util.encodeBase64(keys.publicKey) + }); + ServerCommand(keys, { + command: 'SSO_AUTH', + provider: provider, + register: true + }, cb); + }; + Exports.ssoRegisterCb = function () { + var b64Keys = Util.tryParse(localStorage.CP_sso_auth); + if (!b64Keys) { + throw new Error("MISSING_SIGNATURE_KEYS"); + } + var keys = { + secretKey: Nacl.util.decodeBase64(b64Keys.s), + publicKey: Nacl.util.decodeBase64(b64Keys.p) + }; + ServerCommand(keys, { + command: 'SSO_AUTH_CB', + url: window.location.href + }, function (err, data) { + delete localStorage.CP_sso_auth; + if (data && data.state) { window.location.href = '/register/'; } + }); + }; + Exports.ssoLogin = function () { + + }; + var allocateBytes = Exports.allocateBytes = function (bytes) { var dispense = Cred.dispenser(bytes); diff --git a/customize.dist/pages/login.js b/customize.dist/pages/login.js index a4b452ffc..c6774c222 100644 --- a/customize.dist/pages/login.js +++ b/customize.dist/pages/login.js @@ -38,6 +38,8 @@ define([ undefined: h('button#register.cp-secondary', Msg.login_register) ), + h('button.login', Msg.login_login), + h('br'), h('button.login', Msg.login_login) ]) ]), diff --git a/customize.dist/pages/register.js b/customize.dist/pages/register.js index 8a0859263..44e939e72 100644 --- a/customize.dist/pages/register.js +++ b/customize.dist/pages/register.js @@ -79,7 +79,8 @@ define([ UI.createCheckbox('import-recent', Msg.register_importRecent, true) ]), termsCheck, - h('button#register', Msg.login_register) + h('button#register', Msg.login_register), + Config.sso ? h('div.cp-register-sso') : undefined ]) ]), ]) diff --git a/lib/challenge-commands/sso.js b/lib/challenge-commands/sso.js new file mode 100644 index 000000000..b00e3a89e --- /dev/null +++ b/lib/challenge-commands/sso.js @@ -0,0 +1,105 @@ +const Util = require("../common-util"); +const Commands = module.exports; +const SSOUtils = require('../sso-utils'); + +const checkConfig = (Env) => { + return Env && Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && Env.sso.list.length; +}; +const getProviderConfig = (Env, provider) => { + if (!checkConfig) { return; } + if (!provider) { return; } + const data = Env.sso.list.find((cfg) => { return cfg.name === provider; }); + return data; +}; + +const TYPES = SSOUtils.TYPES; + +const isValidConfig = (cfg) => { + if (!cfg) { return; } + if (!cfg.type) { return; } + const type = cfg.type.toLowerCase(); + const idp = TYPES[type]; + if (!idp) { return; } + return idp.checkConfig(cfg); +}; + +const auth = Commands.SSO_AUTH = function (Env, body, cb) { + if (!checkConfig(Env)) { return void cb('INVALID_SERVER_CONFIG'); } + const { provider } = body; + const cfg = getProviderConfig(Env, provider); + if (!cfg) { return void cb('UNRECOGNIZED_IDP'); } + if (!isValidConfig(cfg)) { return void cb('INVALID_IDP_CONFIG'); } + + cb(); +}; +auth.complete = function (Env, body, cb, req, res) { + // If we're here it means a valid provider was given. We can start the authentication process + const { provider, register, publicKey } = body; + const cfg = getProviderConfig(Env, provider); + const idp = TYPES[cfg.type.toLowerCase()]; + idp.auth(Env, cfg, (err, obj) => { + if (err) { return void cb(err); } // TODO log + + const { url, token } = obj; + + SSOUtils.writeRequest(Env, { + id: token, + type: idp.type, + provider: provider, + publicKey: publicKey, + register: Boolean(register) + }, (err) => { + if (err) { return void cb("E_REQ_WRITE"); } + + let value = `ssotoken="${token}"; SameSite=Strict; HttpOnly`; + res.setHeader('Set-Cookie', value); + cb(void 0, {url: url}); + }); + }); +}; + +const authCb = Commands.SSO_AUTH_CB = function (Env, body, cb, req) { + if (!checkConfig(Env)) { return void cb('INVALID_SERVER_CONFIG'); } + const { publicKey } = body; + const cookies = req.cookies; + const ssotoken = cookies.ssotoken; + if (!ssotoken) { return void cb('NO_COOKIE'); } + SSOUtils.readRequest(Env, ssotoken, (err, value) => { + if (err) { return void cb('ENOENT'); } + const data = Util.tryParse(value); + if (!data || !data.type || !TYPES[data.type]) { return void cb('INVALID_REQUEST_DATA'); } + console.log('stored', data.publicKey); + console.log('used', publicKey); + if (publicKey !== data.publicKey) { return void cb('WRONG_SIGNATURE_KEYS'); } + cb(); + }); +}; +authCb.complete = function (Env, body, cb, req) { + // If we're here it means a valid cookie was given. We can continue the authentication + const { url } = body; + const cookies = req.cookies; + const ssotoken = cookies.ssotoken; + if (!ssotoken) { return void cb('NO_COOKIE'); } + SSOUtils.readRequest(Env, ssotoken, (err, value) => { + SSOUtils.deleteRequest(Env, ssotoken); + if (err) { return void cb('ENOENT'); } + const data = Util.tryParse(value); + const cfg = getProviderConfig(Env, data.provider); + const idp = TYPES[data.type]; + idp.authCb(Env, cfg, ssotoken, url, (err, obj) => { + if (err) { return void cb(err); } + const {id, idpData} = obj; + console.log(id, idpData); + SSOUtils.makeUser(Env, id, (err, userData) => { + if (err) { return void cb(err); } + + // TODO + // makeTempSession() + + cb(void 0, { state: true }); + }); + + }); + }); +}; + diff --git a/lib/env.js b/lib/env.js index a567b39d4..68591e8ec 100644 --- a/lib/env.js +++ b/lib/env.js @@ -223,6 +223,8 @@ module.exports.create = function (config) { evictionReport: {}, commandTimers: {}, + sso: config.sso, + // initialized as undefined bearerSecret: void 0, curvePrivate: curve.secretKey, diff --git a/lib/http-commands.js b/lib/http-commands.js index 229c27e8b..2c19de250 100644 --- a/lib/http-commands.js +++ b/lib/http-commands.js @@ -73,6 +73,9 @@ COMMANDS.TOTP_REVOKE = TOTP.TOTP_REVOKE; COMMANDS.TOTP_WRITE_BLOCK = TOTP.TOTP_WRITE_BLOCK; COMMANDS.TOTP_REMOVE_BLOCK = TOTP.TOTP_REMOVE_BLOCK; +const SSO = require("./challenge-commands/sso.js"); +COMMANDS.SSO_AUTH = SSO.SSO_AUTH; +COMMANDS.SSO_AUTH_CB = SSO.SSO_AUTH_CB; var randomToken = () => Nacl.util.encodeBase64(Nacl.randomBytes(24)).replace(/\//g, '-'); @@ -141,7 +144,7 @@ var handleCommand = function (Env, req, res) { date: date, }); }); - }); + }, req); } catch (err) { Env.Log.error("CHALLENGE_COMMAND_THROWN_ERROR", { error: Util.serializeError(err), @@ -290,7 +293,7 @@ var handleResponse = function (Env, req, res) { }); } res.status(200).json(content); - }); + }, req, res); }); }; diff --git a/lib/http-worker.js b/lib/http-worker.js index 77cb6909b..8047cdb0d 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -10,6 +10,7 @@ const AuthCommands = require("./http-commands"); const JWT = require("jsonwebtoken"); const MFA = require("./storage/mfa"); const Sessions = require("./storage/sessions"); +const cookieParser = require("cookie-parser"); const DEFAULT_QUERY_TIMEOUT = 5000; const PID = process.pid; @@ -158,6 +159,7 @@ var setHeaders = function (req, res) { const Express = require("express"); var app = Express(); +app.use(cookieParser()); (function () { if (!Env.logFeedback) { return; } @@ -187,7 +189,6 @@ const wsProxy = createProxyMiddleware({ app.use('/cryptpad_websocket', wsProxy); - app.use('/blob', function (req, res, next) { /* Head requests are used to check the size of a blob. Clients can configure a maximum size to download automatically, @@ -484,6 +485,13 @@ var makeRouteCache = function (template, cacheName) { }; }; +const ssoList = Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && + Env.sso.list.map(function (obj) { return obj.name; }); +const ssoCfg = ssoList.length ? { + force: (Env.sso && Env.sso.enforced && 1) || 0, + password: (Env.sso && Env.sso.cpPassword && 1) || 0, + list: ssoList +} : false; var serveConfig = makeRouteCache(function () { return [ 'define(function(){', @@ -510,6 +518,7 @@ var serveConfig = makeRouteCache(function () { shouldUpdateNode: Env.shouldUpdateNode || undefined, listMyInstance: Env.listMyInstance, accounts_api: Env.accounts_api, + sso: ssoCfg }, null, '\t'), '});' ].join(';\n'); diff --git a/lib/load-config.js b/lib/load-config.js index 49dbbf58a..a847f812e 100644 --- a/lib/load-config.js +++ b/lib/load-config.js @@ -42,5 +42,12 @@ if (!isPositiveNumber(config.premiumUploadSize) || config.premiumUploadSize < co delete config.premiumUploadSize; } +config.sso = {}; +try { + config.sso = require("../config/sso"); +} catch (e) { + console.log("SSO config not found"); +} + module.exports = config; diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js new file mode 100644 index 000000000..a61ce0846 --- /dev/null +++ b/lib/plugins/sso/oidc.js @@ -0,0 +1,67 @@ +const OID = require('openid-client'); + +const TYPE = 'oidc'; + +const getClient = (cfg, cb) => { + OID.Issuer.discover(cfg.url).then((issuer) => { // XXX Only once for all users? + console.log('Discovered issuer %s %O', issuer.issuer); + const client = new issuer.Client({ + client_id: cfg.client_id, + client_secret: cfg.client_secret, + redirect_uris: ['http://localhost:3000/ssoauth'], // XXX Use httpUnsafeOrigin or... + response_types: ['code'], + }); + cb(void 0, client); + }, (err) => { + cb(err); + }); +}; +module.exports = { + type: TYPE, + checkConfig: (cfg) => { + return cfg.url && cfg.client_id && cfg.client_secret; + }, + auth: (Env, cfg, cb) => { + getClient(cfg, (err, client) => { + if (err) { return void cb ('E_OIDC_CONNECT'); } + + const generators = OID.generators; + const code_verifier = generators.codeVerifier(); + // store the code_verifier in your framework's session mechanism, if it is a cookie based solution + // it should be httpOnly (not readable by javascript) and encrypted. + + console.log(code_verifier); + const code_challenge = generators.codeChallenge(code_verifier); + const url = client.authorizationUrl({ + scope: 'openid email profile',// https://www.googleapis.com/auth/contacts.readonly', // https://www.google.com/m8/feeds + resource: 'http://localhost:3000/ssoauth/', + access_type: 'offline', + code_challenge, + code_challenge_method: 'S256', + }); + + cb(void 0, { url: url, token: code_verifier }); + }); + }, + authCb: (Env, cfg, token, url, cb) => { + getClient(cfg, (err, client) => { + if (err) { return void cb ('E_OIDC_CONNECT'); } + + const params = client.callbackParams(url); + client.callback('http://localhost:3000/ssoauth', params, { code_verifier: token }) + .then((tokenSet) => { + let j = tokenSet; + let c = tokenSet.claims(); + console.log(j, c); + cb(void 0, { + id: c.sub, + idpData: { + access_token: j.access_token, + refresh_token: j.refresh_token, + id_token: j.id_token + } + }); + }); + }); + } +}; diff --git a/lib/sso-utils.js b/lib/sso-utils.js new file mode 100644 index 000000000..1bad43d5d --- /dev/null +++ b/lib/sso-utils.js @@ -0,0 +1,71 @@ +const SSO = require("./storage/sso"); +const Nacl = require("tweetnacl/nacl-fast"); + +const SSOUtils = module.exports; + +// XXX const SAML = require('node-saml'); // https://www.npmjs.com/package/node-saml +SSOUtils.TYPES = { + oidc: require('./plugins/sso/oidc') +}; + + +SSOUtils.deleteRequest = (Env, id) => { + SSO.request.delete(Env, id, (err) => { + if (!err) { return; } + console.log(`Failed to delete SSO request ${id}`); + // XXX log? + }); +}; +SSOUtils.readRequest = (Env, id, cb) => { + SSO.request.read(Env, id, cb); +}; +SSOUtils.writeRequest = (Env, data, cb) => { + if (!data || !data.id || !data.type) { return void cb ('INVALID_REQUEST'); } + const id = data.id; + const value = { + type: data.type, + register: data.register, + provider: data.provider, + publicKey: data.publicKey, + time: +new Date() + }; + + SSO.request.write(Env, id, JSON.stringify(value), cb); +}; + + +SSOUtils.makeUser = (Env, id, cb) => { + const seed = Nacl.util.encodeBase64(Nacl.util.randomBytes(24)); + SSO.User.write(Env, id, JSON.stringify({ + seed: seed, + password: false // XXX maybe we don't need that flag, we can check if the block exists later + }), (err) => { + if (err) { return void cb(err); } + cb(void 0, { seed }); + }); + +}; + +SSOUtils.makeSession = (Env, publicKey, provider, ssoData, cb) => { + const sessionId = Sessions.randomId(); + // XXX If we already have an OTP session, recover it + Sessions.write(Env, publicKey, sessionId, JSON.stringify({ + sso: { + provider: provider, + data: ssoData + } + }), function (err) { + if (err) { + Env.Log.error("SSO_SESSION_WRITE", { + error: Util.serializeError(err), + publicKey: publicKey, + sessionId: sessionId, + }); + return void cb("SESSION_WRITE_ERROR"); + } + cb(void 0, { + bearer: sessionId, + }); + }); + +}; diff --git a/lib/storage/sso.js b/lib/storage/sso.js new file mode 100644 index 000000000..65110ee30 --- /dev/null +++ b/lib/storage/sso.js @@ -0,0 +1,57 @@ +const Basic = require("./basic"); +const Path = require("node:path"); +const Util = require("../common-util"); + +const SSO = module.exports; +/* This module manages storage related to Single Sign-On (SSO) settings. + +A first part (sso-requests) contains temporary files for sso authentication with a remote service +and a second part (sso users) is a database of accounts registered via SSO. + +The path for requests is based on the "authentication request" token depending on the type of SSO. +The path for the user database is based on their persistent identifier (id) from the SSO. +*/ + +var pathFromId = function (Env, id, subPath) { + if (!id || typeof(id) !== 'string') { return; } + id = Util.escapeKeyCharacters(id); + return Path.join(Env.paths.base, subPath, id.slice(0, 2), `${id}.json`); +}; +var reqPathFromId = function (Env, id) { + return pathFromId(Env, id, 'sso_request'); +}; +var userPathFromId = function (Env, id) { + return pathFromId(Env, id, 'sso'); +}; + +const Req = SSO.request = {}; + +Req.read = function (Env, id, cb) { + var path = reqPathFromId(Env, id); + Basic.read(Env, path, cb); +}; +Req.write = function (Env, id, data, cb) { + var path = reqPathFromId(Env, id); + console.log(path); + Basic.write(Env, path, data, cb); +}; +Req.delete = function (Env, id, cb) { + var path = reqPathFromId(Env, id); + Basic.delete(Env, path, cb); +}; + + +const User = SSO.user = {}; + +User.read = function (Env, id, cb) { + var path = userPathFromId(Env, id); + Basic.read(Env, path, cb); +}; +User.write = function (Env, id, data, cb) { + var path = userPathFromId(Env, id); + Basic.write(Env, path, data, cb); +}; +User.delete = function (Env, id, cb) { + var path = userPathFromId(Env, id); + Basic.delete(Env, path, cb); +}; diff --git a/package-lock.json b/package-lock.json index d97d0d112..e6b12b5bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@mcrowe/minibloom": "^0.2.0", "chainpad-crypto": "^0.2.5", "chainpad-server": "^5.1.0", + "cookie-parser": "^1.4.6", "express": "~4.18.2", "fs-extra": "^7.0.0", "get-folder-size": "^2.0.1", @@ -20,6 +21,7 @@ "netflux-websocket": "^0.1.20", "notp": "^2.0.3", "nthen": "0.1.8", + "openid-client": "^5.4.2", "prompt-confirm": "^2.0.4", "pull-stream": "^3.6.1", "saferphore": "0.0.1", @@ -1011,6 +1013,26 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -1749,25 +1771,15 @@ } }, "node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, "node_modules/glob-to-regexp": { @@ -2220,6 +2232,14 @@ "node": ">=0.10.0" } }, + "node_modules/jose": { + "version": "4.14.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", + "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -2727,6 +2747,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -2758,6 +2786,14 @@ "node": ">=0.10.0" } }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -2778,6 +2814,20 @@ "wrappy": "1" } }, + "node_modules/openid-client": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.4.2.tgz", + "integrity": "sha512-lIhsdPvJ2RneBm3nGBBhQchpe3Uka//xf7WPHTIglery8gnckvW7Bd9IaQzekzXJvWthCMyi/xVEyGW0RFPytw==", + "dependencies": { + "jose": "^4.14.1", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -2808,12 +2858,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -3039,17 +3083,6 @@ "node": ">=0.10.0" } }, - "node_modules/prompt-choices/node_modules/set-value": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-3.0.3.tgz", - "integrity": "sha512-Xsn/XSatoVOGBbp5hs3UylFDs5Bi9i+ArpVJKdHPniZHoEgRniXTqHWrWrGQ0PbEClVT6WtfnBwR8CAHC9sveg==", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=6.0" - } - }, "node_modules/prompt-choices/node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -3391,39 +3424,19 @@ } }, "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.0.1.tgz", + "integrity": "sha512-ayATicCYPVnlNpFmjq2/VmVwhoCQA9+13j8qWp044fmFE3IFphosPtRM+0CJ5xoIx5Uy52fCcwg3XeH2pHbbPQ==", + "funding": [ + "https://github.com/sponsors/jonschlinkert", + "https://paypal.me/jonathanschlinkert", + "https://jonschlinkert.dev/sponsor" + ], "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "is-plain-object": "^2.0.4" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=11.0" } }, "node_modules/setprototypeof": { @@ -4738,7 +4751,7 @@ "get-value": "^2.0.6", "has-value": "^1.0.0", "isobject": "^3.0.1", - "set-value": "^2.0.0", + "set-value": "4.0.1", "to-object-path": "^0.3.0", "union-value": "^1.0.0", "unset-value": "^1.0.0" @@ -4980,6 +4993,22 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, + "cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + } + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -5387,7 +5416,7 @@ "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", + "glob-parent": "5.1.2", "is-glob": "^4.0.0", "merge2": "^1.2.3", "micromatch": "^3.1.10" @@ -5556,24 +5585,12 @@ } }, "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } + "is-glob": "^4.0.1" } }, "glob-to-regexp": { @@ -5907,6 +5924,11 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "jose": { + "version": "4.14.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz", + "integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==" + }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -6309,6 +6331,11 @@ } } }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + }, "object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -6331,6 +6358,11 @@ "isobject": "^3.0.1" } }, + "oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==" + }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -6348,6 +6380,17 @@ "wrappy": "1" } }, + "openid-client": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.4.2.tgz", + "integrity": "sha512-lIhsdPvJ2RneBm3nGBBhQchpe3Uka//xf7WPHTIglery8gnckvW7Bd9IaQzekzXJvWthCMyi/xVEyGW0RFPytw==", + "requires": { + "jose": "^4.14.1", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -6369,12 +6412,6 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -6528,7 +6565,7 @@ "log-utils": "^0.2.1", "pointer-symbol": "^1.0.0", "radio-symbol": "^2.0.0", - "set-value": "^3.0.0", + "set-value": "4.0.1", "strip-color": "^0.1.0", "terminal-paginator": "^2.0.2", "toggle-array": "^1.0.1" @@ -6549,14 +6586,6 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-6.0.0.tgz", "integrity": "sha512-Wu1VHeILBK8KAWJUAiSZQX94GmOE45Rg6/538fKwiloUu21KncEkYGPqob2oSZ5mUT73vLGrHQjKw3KMPwfDzg==" }, - "set-value": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-3.0.3.tgz", - "integrity": "sha512-Xsn/XSatoVOGBbp5hs3UylFDs5Bi9i+ArpVJKdHPniZHoEgRniXTqHWrWrGQ0PbEClVT6WtfnBwR8CAHC9sveg==", - "requires": { - "is-plain-object": "^2.0.4" - } - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -6836,32 +6865,11 @@ } }, "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.0.1.tgz", + "integrity": "sha512-ayATicCYPVnlNpFmjq2/VmVwhoCQA9+13j8qWp044fmFE3IFphosPtRM+0CJ5xoIx5Uy52fCcwg3XeH2pHbbPQ==", "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } + "is-plain-object": "^2.0.4" } }, "setprototypeof": { @@ -7351,7 +7359,7 @@ "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^2.0.1" + "set-value": "4.0.1" }, "dependencies": { "is-extendable": { diff --git a/package.json b/package.json index 5546c1d1c..cda1e4183 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@mcrowe/minibloom": "^0.2.0", "chainpad-crypto": "^0.2.5", "chainpad-server": "^5.1.0", + "cookie-parser": "^1.4.6", "express": "~4.18.2", "fs-extra": "^7.0.0", "get-folder-size": "^2.0.1", @@ -23,6 +24,7 @@ "netflux-websocket": "^0.1.20", "notp": "^2.0.3", "nthen": "0.1.8", + "openid-client": "^5.4.2", "prompt-confirm": "^2.0.4", "pull-stream": "^3.6.1", "saferphore": "0.0.1", diff --git a/www/register/main.js b/www/register/main.js index d772c770f..3900fc855 100644 --- a/www/register/main.js +++ b/www/register/main.js @@ -1,4 +1,5 @@ define([ + '/api/config', 'jquery', '/customize/login.js', '/common/cryptpad-common.js', @@ -14,7 +15,7 @@ define([ '/customize/pages.js', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', -], function ($, Login, Cryptpad, /*Test,*/ Cred, UI, Util, Realtime, Constants, Feedback, LocalStore, h, Pages) { +], function (Config, $, Login, Cryptpad, /*Test,*/ Cred, UI, Util, Realtime, Constants, Feedback, LocalStore, h, Pages) { if (window.top !== window) { return; } var Messages = Cryptpad.Messages; $(function () { @@ -50,6 +51,30 @@ define([ var br = function () { return h('br'); }; Messages.register_nameTooLong = "Usernames must be shorter than {0} characters"; // XXX + if (Config.sso) { + // TODO + // Config.sso.force => no legacy login allowed + // Config.sso.password => cp password required or forbidden + // Config.sso.list => list of configured identity providers + var $sso = $('div.cp-register-sso'); + var list = Config.sso.list.map(function (name) { + var b = h('button.btn.btn-secondary', name); + var $b = $(b).click(function () { + console.log('sso register click:', name); + $b.prop('disabled', 'disabled'); + Login.ssoRegister(name, function (err, data) { + console.error(err, data); + if (data.url) { + window.location.href = data.url; + } + }); + // XXX Server command + }); + return b; + }); + $sso.append(list); + } + var registerClick = function () { var uname = $uname.val().trim(); // trim whitespace surrounding the username since it is otherwise included in key derivation diff --git a/www/ssoauth/index.html b/www/ssoauth/index.html new file mode 100644 index 000000000..a7bdb9b14 --- /dev/null +++ b/www/ssoauth/index.html @@ -0,0 +1,14 @@ + + + + + CryptPad: Collaboration suite, encrypted and open-source + + + + + + + + + diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js new file mode 100644 index 000000000..c556e2814 --- /dev/null +++ b/www/ssoauth/main.js @@ -0,0 +1,3 @@ +define(['/customize/login.js'], function (Login) { + Login.ssoRegisterCb(); +}); From b93b5eae4e10150efcd4e184d9800fe5f9db37ef Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 27 Jun 2023 16:04:32 +0200 Subject: [PATCH 002/283] SSO: OIDC login and register --- customize.dist/login.js | 529 +----------------- customize.dist/pages/login.js | 5 +- customize.dist/pages/ssoauth.js | 57 ++ .../src/less2/pages/page-ssoauth.less | 29 + customize.dist/template.js | 2 + lib/challenge-commands/sso.js | 182 +++++- lib/challenge-commands/totp.js | 36 +- lib/http-commands.js | 4 +- lib/http-worker.js | 151 ++--- lib/plugins/sso/oidc.js | 27 +- lib/sso-utils.js | 107 +++- lib/storage/sessions.js | 8 + lib/storage/sso.js | 23 +- www/common/common-login.js | 520 +++++++++++++++++ www/common/outer/login-block.js | 15 +- www/install/main.js | 3 +- www/login/main.js | 25 +- www/register/main.js | 7 +- www/ssoauth/index.html | 4 +- www/ssoauth/main.js | 143 ++++- 20 files changed, 1171 insertions(+), 706 deletions(-) create mode 100644 customize.dist/pages/ssoauth.js create mode 100644 customize.dist/src/less2/pages/page-ssoauth.less create mode 100644 www/common/common-login.js diff --git a/customize.dist/login.js b/customize.dist/login.js index c0b06fa04..fb9d01365 100644 --- a/customize.dist/login.js +++ b/customize.dist/login.js @@ -4,6 +4,7 @@ define([ '/bower_components/chainpad-crypto/crypto.js', '/common/common-util.js', '/common/outer/network-config.js', + '/common/common-login.js', '/common/common-credential.js', '/bower_components/chainpad/chainpad.dist.js', '/common/common-realtime.js', @@ -19,14 +20,14 @@ define([ '/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/scrypt-async/scrypt-async.min.js', // better load speed -], function ($, Listmap, Crypto, Util, NetConfig, Cred, ChainPad, Realtime, Constants, UI, +], function ($, Listmap, Crypto, Util, NetConfig, Login, Cred, ChainPad, Realtime, Constants, UI, Feedback, LocalStore, Messages, nThen, Block, Hash, ServerCommand) { var Exports = { Cred: Cred, Block: Block, // this is depended on by non-customizable files // be careful when modifying login.js - requiredBytes: 192, + requiredBytes: Login.requiredBytes, }; var Nacl = window.nacl; @@ -39,11 +40,9 @@ define([ redirectTo = newPad.href; } }; - if (window.location.hash) { - setRedirectTo(); - } + if (window.location.hash) { setRedirectTo(); } - Exports.ssoRegister = function (provider, cb) { + Exports.ssoAuth = function (provider, cb) { var keys = Nacl.sign.keyPair(); localStorage.CP_sso_auth = JSON.stringify({ s: Nacl.util.encodeBase64(keys.secretKey), @@ -55,518 +54,17 @@ define([ register: true }, cb); }; - Exports.ssoRegisterCb = function () { - var b64Keys = Util.tryParse(localStorage.CP_sso_auth); - if (!b64Keys) { - throw new Error("MISSING_SIGNATURE_KEYS"); - } - var keys = { - secretKey: Nacl.util.decodeBase64(b64Keys.s), - publicKey: Nacl.util.decodeBase64(b64Keys.p) - }; - ServerCommand(keys, { - command: 'SSO_AUTH_CB', - url: window.location.href - }, function (err, data) { - delete localStorage.CP_sso_auth; - if (data && data.state) { window.location.href = '/register/'; } - }); - }; Exports.ssoLogin = function () { }; - var allocateBytes = Exports.allocateBytes = function (bytes) { - var dispense = Cred.dispenser(bytes); + Exports.allocateBytes = Login.allocateBytes; + Exports.loadUserObject = Login.loadUserObject; - var opt = {}; - - // dispense 18 bytes of entropy for your encryption key - var encryptionSeed = dispense(18); - // 16 bytes for a deterministic channel key - var channelSeed = dispense(16); - // 32 bytes for a curve key - var curveSeed = dispense(32); - - var curvePair = Nacl.box.keyPair.fromSecretKey(new Uint8Array(curveSeed)); - opt.curvePrivate = Nacl.util.encodeBase64(curvePair.secretKey); - opt.curvePublic = Nacl.util.encodeBase64(curvePair.publicKey); - - // 32 more for a signing key - var edSeed = opt.edSeed = dispense(32); - - // 64 more bytes to seed an additional signing key - var blockKeys = opt.blockKeys = Block.genkeys(new Uint8Array(dispense(64))); - opt.blockHash = Block.getBlockHash(blockKeys); - - // derive a private key from the ed seed - var signingKeypair = Nacl.sign.keyPair.fromSeed(new Uint8Array(edSeed)); - - opt.edPrivate = Nacl.util.encodeBase64(signingKeypair.secretKey); - opt.edPublic = Nacl.util.encodeBase64(signingKeypair.publicKey); - - var keys = opt.keys = Crypto.createEditCryptor(null, encryptionSeed); - - // 24 bytes of base64 - keys.editKeyStr = keys.editKeyStr.replace(/\//g, '-'); - - // 32 bytes of hex - var channelHex = opt.channelHex = Util.uint8ArrayToHex(channelSeed); - - // should never happen - if (channelHex.length !== 32) { throw new Error('invalid channel id'); } - - var channel64 = Util.hexToBase64(channelHex); - - // we still generate a v1 hash because this function needs to deterministically - // derive the same values as it always has. New accounts will generate their own - // userHash values - opt.userHash = '/1/edit/' + [channel64, opt.keys.editKeyStr].join('/') + '/'; - - return opt; + var setMergeAnonDrive = function (value) { + Exports.mergeAnonDrive = Boolean(value); }; - - var loginOptionsFromBlock = Exports.loginOptionsFromBlock = function (blockInfo) { - var opt = {}; - var parsed = Hash.getSecrets('pad', blockInfo.User_hash); - opt.channelHex = parsed.channel; - opt.keys = parsed.keys; - opt.edPublic = blockInfo.edPublic; - return opt; - }; - - var loadUserObject = Exports.loadUserObject = function (opt, cb) { - var config = { - websocketURL: NetConfig.getWebsocketURL(), - channel: opt.channelHex, - data: {}, - validateKey: opt.keys.validateKey, // derived validation key - crypto: Crypto.createEncryptor(opt.keys), - logLevel: 1, - classic: true, - ChainPad: ChainPad, - owners: [opt.edPublic] - }; - - var rt = opt.rt = Listmap.create(config); - rt.proxy - .on('ready', function () { - setTimeout(function () { cb(void 0, rt); }); - }) - .on('disconnect', function (info) { - cb('E_DISCONNECT', info); - }); - }; - - var isProxyEmpty = function (proxy) { - var l = Object.keys(proxy).length; - return l === 0 || (l === 2 && proxy._events && proxy.on); - }; - - var setMergeAnonDrive = function () { - Exports.mergeAnonDrive = 1; - }; - - Exports.loginOrRegister = function (uname, passwd, isRegister, shouldImport, onOTP, cb) { - if (typeof(cb) !== 'function') { return; } - - // Usernames are all lowercase. No going back on this one - uname = uname.toLowerCase(); - - // validate inputs - if (!Cred.isValidUsername(uname)) { return void cb('INVAL_USER'); } - if (!Cred.isValidPassword(passwd)) { return void cb('INVAL_PASS'); } - if (isRegister && !Cred.isLongEnoughPassword(passwd)) { - return void cb('PASS_TOO_SHORT'); - } - - // results... - var res = { - register: isRegister, - }; - - var RT, blockKeys, blockHash, blockUrl, Pinpad, rpc, userHash; - - nThen(function (waitFor) { - // derive a predefined number of bytes from the user's inputs, - // and allocate them in a deterministic fashion - Cred.deriveFromPassphrase(uname, passwd, Exports.requiredBytes, waitFor(function (bytes) { - res.opt = allocateBytes(bytes); - blockHash = res.opt.blockHash; - blockKeys = res.opt.blockKeys; - })); - }).nThen(function (waitFor) { - // the allocated bytes can be used either in a legacy fashion, - // or in such a way that a previously unused byte range determines - // the location of a layer of indirection which points users to - // an encrypted block, from which they can recover the location of - // the rest of their data - - // determine where a block for your set of keys would be stored - blockUrl = Block.getBlockUrl(res.opt.blockKeys); - - var TOTP_prompt = function (err, cb) { - onOTP(function (code) { - ServerCommand(res.opt.blockKeys.sign, { - command: 'TOTP_VALIDATE', - code: code, - // TODO optionally allow the user to specify a lifetime for this session? - // this will require a little bit of server work - // and more UI/UX: - // ie. just a simple "remember me" checkbox? - // allow them to specify a lifetime for the session? - // "log me out after one day"? - }, cb); - }, false, err); - }; - - var done = waitFor(); - var responseToDecryptedBlock = function (response, cb) { - response.arrayBuffer().then(arraybuffer => { - arraybuffer = new Uint8Array(arraybuffer); - var decryptedBlock = Block.decrypt(arraybuffer, blockKeys); - if (!decryptedBlock) { - console.error("BLOCK DECRYPTION ERROR"); - return void cb("BLOCK_DECRYPTION_ERROR"); - } - cb(void 0, decryptedBlock); - }); - }; - - var TOTP_response; - nThen(function (w) { - Util.getBlock(blockUrl, { - // request the block without credentials - }, w(function (err, response) { - if (err === 401) { - return void console.log("Block requires 2FA"); - } - - // Some other error? - if (err) { - console.error(err); - w.abort(); - return void done(); - } - - // If the block was returned without requiring authentication - // then we can abort the subsequent steps of this nested nThen - w.abort(); - - // decrypt the response and continue the normal procedure with its payload - responseToDecryptedBlock(response, function (err, decryptedBlock) { - if (err) { - // if a block was present but you were not able to decrypt it... - console.error(err); - waitFor.abort(); - return void cb(err); - } - res.blockInfo = decryptedBlock; - done(); - }); - })); - }).nThen(function (w) { - // if you're here then you need to request a JWT - var done = w(); - var tries = 3; - var ask = function () { - if (!tries) { - w.abort(); - waitFor.abort(); - return void cb('TOTP_ATTEMPTS_EXHAUSTED'); - } - tries--; - TOTP_prompt(tries !== 2, function (err, response) { - // ask again until your number of tries are exhausted - if (err) { - console.error(err); - console.log("Normal failure. Asking again..."); - return void ask(); - } - if (!response || !response.bearer) { - console.log(response); - console.log("Unexpected failure. No bearer token. Asking again"); - return void ask(); - } - console.log("Successfully retrieved a bearer token"); - res.TOTP_token = TOTP_response = response; - done(); - }); - }; - ask(); - }).nThen(function (w) { - Util.getBlock(blockUrl, TOTP_response, function (err, response) { - if (err) { - w.abort(); - console.error(err); - return void cb('BLOCK_ERROR_3'); - } - - responseToDecryptedBlock(response, function (err, decryptedBlock) { - if (err) { - waitFor.abort(); - return void cb(err); - } - res.blockInfo = decryptedBlock; - done(); - }); - }); - }); - }).nThen(function (waitFor) { - // we assume that if there is a block, it was created in a valid manner - // so, just proceed to the next block which handles that stuff - if (res.blockInfo) { return; } - - var opt = res.opt; - - // load the user's object using the legacy credentials - loadUserObject(opt, waitFor(function (err, rt) { - if (err) { - waitFor.abort(); - return void cb(err); - } - - // if a proxy is marked as deprecated, it is because someone had a non-owned drive - // but changed their password, and couldn't delete their old data. - // if they are here, they have entered their old credentials, so we should not - // allow them to proceed. In time, their old drive should get deleted, since - // it will should be pinned by anyone's drive. - if (rt.proxy[Constants.deprecatedKey]) { - waitFor.abort(); - return void cb('NO_SUCH_USER', res); - } - - if (isRegister && isProxyEmpty(rt.proxy)) { - // If they are trying to register, - // and the proxy is empty, then there is no 'legacy user' either - // so we should just shut down this session and disconnect. - //rt.network.disconnect(); - return; // proceed to the next async block - } - - // they tried to just log in but there's no such user - // and since we're here at all there is no modern-block - if (!isRegister && isProxyEmpty(rt.proxy)) { - //rt.network.disconnect(); // clean up after yourself - waitFor.abort(); - return void cb('NO_SUCH_USER', res); - } - - // they tried to register, but those exact credentials exist - if (isRegister && !isProxyEmpty(rt.proxy)) { - //rt.network.disconnect(); - waitFor.abort(); - Feedback.send('LOGIN', true); - return void cb('ALREADY_REGISTERED', res); - } - - // if you are here, then there is no block, the user is trying - // to log in. The proxy is **not** empty. All values assigned here - // should have been deterministically created using their credentials - // so setting them is just a precaution to keep things in good shape - res.proxy = rt.proxy; - res.realtime = rt.realtime; - res.network = rt.network; - - // they're registering... - res.userHash = opt.userHash; - res.userName = uname; - - // export their signing key - res.edPrivate = opt.edPrivate; - res.edPublic = opt.edPublic; - - // export their encryption key - res.curvePrivate = opt.curvePrivate; - res.curvePublic = opt.curvePublic; - - if (shouldImport) { setMergeAnonDrive(); } - - // don't proceed past this async block. - waitFor.abort(); - - // We have to call whenRealtimeSyncs asynchronously here because in the current - // version of listmap, onLocal calls `chainpad.contentUpdate(newValue)` - // asynchronously. - // The following setTimeout is here to make sure whenRealtimeSyncs is called after - // `contentUpdate` so that we have an update userDoc in chainpad. - setTimeout(function () { - Realtime.whenRealtimeSyncs(rt.realtime, function () { - // the following stages are there to initialize a new drive - // if you are registering - LocalStore.login(res.userHash, undefined, res.userName, function () { - setTimeout(function () { cb(void 0, res); }); - }); - }); - }); - })); - }).nThen(function (waitFor) { // MODERN REGISTRATION / LOGIN - var opt; - if (res.blockInfo) { - opt = loginOptionsFromBlock(res.blockInfo); - userHash = res.blockInfo.User_hash; - //console.error(opt, userHash); - } else { - console.log("allocating random bytes for a new user object"); - opt = allocateBytes(Nacl.randomBytes(Exports.requiredBytes)); - // create a random v2 hash, since we don't need backwards compatibility - userHash = opt.userHash = Hash.createRandomHash('drive'); - var secret = Hash.getSecrets('drive', userHash); - opt.keys = secret.keys; - opt.channelHex = secret.channel; - } - - // according to the location derived from the credentials which you entered - loadUserObject(opt, waitFor(function (err, rt) { - if (err) { - waitFor.abort(); - return void cb('MODERN_REGISTRATION_INIT'); - } - - //console.error(JSON.stringify(rt.proxy)); - - // export the realtime object you checked - RT = rt; - - var proxy = rt.proxy; - if (isRegister && !isProxyEmpty(proxy) && (!proxy.edPublic || !proxy.edPrivate)) { - console.error("INVALID KEYS"); - console.log(JSON.stringify(proxy)); - return; - } - - res.proxy = rt.proxy; - res.realtime = rt.realtime; - res.network = rt.network; - - // they're registering... - res.userHash = userHash; - res.userName = uname; - - // somehow they have a block present, but nothing in the user object it specifies - // this shouldn't happen, but let's send feedback if it does - if (!isRegister && isProxyEmpty(rt.proxy)) { - // this really shouldn't happen, but let's handle it anyway - Feedback.send('EMPTY_LOGIN_WITH_BLOCK'); - - //rt.network.disconnect(); // clean up after yourself - waitFor.abort(); - return void cb('NO_SUCH_USER', res); - } - - // they tried to register, but those exact credentials exist - if (isRegister && !isProxyEmpty(rt.proxy)) { - //rt.network.disconnect(); - waitFor.abort(); - res.blockHash = blockHash; - if (shouldImport) { - setMergeAnonDrive(); - } - - return void cb('ALREADY_REGISTERED', res); - } - - if (!isRegister && !isProxyEmpty(rt.proxy)) { - waitFor.abort(); - if (shouldImport) { - setMergeAnonDrive(); - } - var l = Util.find(rt.proxy, ['settings', 'general', 'language']); - var LS_LANG = "CRYPTPAD_LANG"; - if (l) { - localStorage.setItem(LS_LANG, l); - } - - if (res.TOTP_token && res.TOTP_token.bearer) { - LocalStore.setSessionToken(res.TOTP_token.bearer); - } - return void LocalStore.login(undefined, blockHash, uname, function () { - cb(void 0, res); - }); - } - - if (isRegister && isProxyEmpty(rt.proxy)) { - proxy.edPublic = opt.edPublic; - proxy.edPrivate = opt.edPrivate; - proxy.curvePublic = opt.curvePublic; - proxy.curvePrivate = opt.curvePrivate; - proxy.login_name = uname; - proxy[Constants.displayNameKey] = uname; - if (shouldImport) { - setMergeAnonDrive(); - } else { - proxy.version = 11; - } - - Feedback.send('REGISTRATION', true); - } else { - Feedback.send('LOGIN', true); - } - - setTimeout(waitFor(function () { - Realtime.whenRealtimeSyncs(rt.realtime, waitFor()); - })); - })); - }).nThen(function (waitFor) { - require(['/common/pinpad.js'], waitFor(function (_Pinpad) { - console.log("loaded rpc module"); - Pinpad = _Pinpad; - })); - }).nThen(function (waitFor) { - // send an RPC to store the block which you created. - console.log("initializing rpc interface"); - - Pinpad.create(RT.network, Block.keysToRPCFormat(res.opt.blockKeys), waitFor(function (e, _rpc) { - if (e) { - waitFor.abort(); - console.error(e); // INVALID_KEYS - return void cb('RPC_CREATION_ERROR'); - } - rpc = _rpc; - console.log("rpc initialized"); - })); - }).nThen(function (waitFor) { - console.log("creating request to publish a login block"); - - // Finally, create the login block for the object you just created. - var toPublish = {}; - -// XXX I did some basic testing and searching and could not find this attribute -// actually being used anywhere. Including it means either supporting arbitrarily -// large blocks (a DoS vector) or having registration fail for large usernames. -// Can someone please double-check that removing this doesn't break anything? -// --Aaron - //toPublish[Constants.userNameKey] = uname; - toPublish[Constants.userHashKey] = userHash; - toPublish.edPublic = RT.proxy.edPublic; - - Block.writeLoginBlock({ - blockKeys: blockKeys, - content: toPublish - }, waitFor(function (e) { - if (e) { - console.error(e); - waitFor.abort(); - return void cb(e); - } - })); - }).nThen(function (waitFor) { - // confirm that the block was actually written before considering registration successful - Util.fetch(blockUrl, waitFor(function (err /*, block */) { - if (err) { - console.error(err); - waitFor.abort(); - return void cb(err); - } - - console.log("blockInfo available at:", blockHash); - LocalStore.login(undefined, blockHash, uname, function () { - cb(void 0, res); - }); - })); - }); - }; Exports.redirect = function () { if (redirectTo) { var h = redirectTo; @@ -591,6 +89,8 @@ define([ if (hashing) { return void console.log("hashing is already in progress"); } hashing = true; + setMergeAnonDrive(shouldImport); + var proceed = function (result) { hashing = false; // NOTE: test is also use as a cb for the install page @@ -612,7 +112,12 @@ define([ // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed // after hashing the password window.setTimeout(function () { - Exports.loginOrRegister(uname, passwd, isRegister, shouldImport, onOTP, function (err, result) { + Exports.loginOrRegister({ + uname, + passwd, + isRegister, + onOTP + }, function (err, result) { var proxy; if (result) { proxy = result.proxy; } diff --git a/customize.dist/pages/login.js b/customize.dist/pages/login.js index c6774c222..53b569af3 100644 --- a/customize.dist/pages/login.js +++ b/customize.dist/pages/login.js @@ -39,9 +39,8 @@ define([ h('button#register.cp-secondary', Msg.login_register) ), h('button.login', Msg.login_login), - h('br'), - h('button.login', Msg.login_login) - ]) + ]), + Config.sso ? h('div.cp-login-sso') : undefined ]), h('div.col-md-3') ]), diff --git a/customize.dist/pages/ssoauth.js b/customize.dist/pages/ssoauth.js new file mode 100644 index 000000000..691d18470 --- /dev/null +++ b/customize.dist/pages/ssoauth.js @@ -0,0 +1,57 @@ +define([ + '/api/config', + 'jquery', + '/common/hyperscript.js', + '/common/common-interface.js', + '/customize/messages.js', + '/customize/pages.js' +], function (Config, $, h, UI, Msg, Pages) { + + Msg.ssoauth_header = "SSO authentication"; // XXX + Msg.ssoauth_form_hint_register = "Add a CryptPad password for extra security or leave empty and continue"; + Msg.ssoauth_form_hint_login = "Please enter your CryptPad password"; + Msg.continue = "Continue"; + + return function () { + document.title = Msg.ssoauth_header; + + var frame = function (content) { + return [ + h('div#cp-main', [ + Pages.infopageTopbar(), + h('div.container.cp-container', [ + h('div.row.cp-page-title', h('h1', Msg.ssoauth_header)), + ].concat(content)), + Pages.infopageFooter(), + ]), + ]; + }; + + 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.hidden.col-md-3'), + ]) + ]); + }; + +}); + + diff --git a/customize.dist/src/less2/pages/page-ssoauth.less b/customize.dist/src/less2/pages/page-ssoauth.less new file mode 100644 index 000000000..a2c0e0141 --- /dev/null +++ b/customize.dist/src/less2/pages/page-ssoauth.less @@ -0,0 +1,29 @@ +@import (reference) "../include/infopages.less"; +@import (reference) "../include/colortheme-all.less"; +@import (reference) "../include/alertify.less"; +@import (reference) "../include/forms.less"; + +&.cp-page-ssoauth { + .infopages_main(); + .forms_main(); + + .alertify_main(); + + div.cp-ssoauth-pw { + display: none; + } + + &.cp-regsiter { + .login { + display: none; + } + } + &.cp-login { + .register { + display: none; + } + } + +} + + diff --git a/customize.dist/template.js b/customize.dist/template.js index b5eca8b2f..bead8f4a7 100644 --- a/customize.dist/template.js +++ b/customize.dist/template.js @@ -57,6 +57,8 @@ $(function () { require([ '/install/main.js' ], function () {}); } else if (/^\/recovery\//.test(pathname)) { require([ '/recovery/main.js' ], function () {}); + } else if (/^\/ssoauth\//.test(pathname)) { + require([ '/ssoauth/main.js' ], function () {}); } else if (/^\/login\//.test(pathname)) { require([ '/login/main.js' ], function () {}); } else if (/^\/($|^\/index\.html$)/.test(pathname)) { diff --git a/lib/challenge-commands/sso.js b/lib/challenge-commands/sso.js index b00e3a89e..385fa6d70 100644 --- a/lib/challenge-commands/sso.js +++ b/lib/challenge-commands/sso.js @@ -1,28 +1,17 @@ const Util = require("../common-util"); const Commands = module.exports; const SSOUtils = require('../sso-utils'); - -const checkConfig = (Env) => { - return Env && Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && Env.sso.list.length; -}; -const getProviderConfig = (Env, provider) => { - if (!checkConfig) { return; } - if (!provider) { return; } - const data = Env.sso.list.find((cfg) => { return cfg.name === provider; }); - return data; -}; +const nThen = require("nthen"); +const BlockStore = require("../storage/block"); +const Block = require("../commands/block"); const TYPES = SSOUtils.TYPES; +const checkConfig = SSOUtils.checkConfig; +const getProviderConfig = SSOUtils.getProviderConfig; +const isValidConfig = SSOUtils.isValidConfig; -const isValidConfig = (cfg) => { - if (!cfg) { return; } - if (!cfg.type) { return; } - const type = cfg.type.toLowerCase(); - const idp = TYPES[type]; - if (!idp) { return; } - return idp.checkConfig(cfg); -}; +// Create an SSO authentication request const auth = Commands.SSO_AUTH = function (Env, body, cb) { if (!checkConfig(Env)) { return void cb('INVALID_SERVER_CONFIG'); } const { provider } = body; @@ -58,6 +47,8 @@ auth.complete = function (Env, body, cb, req, res) { }); }; +// Receive authentication data from the IdP. +// Read the auth request, create a JWT and get a block seed for this SSO user. const authCb = Commands.SSO_AUTH_CB = function (Env, body, cb, req) { if (!checkConfig(Env)) { return void cb('INVALID_SERVER_CONFIG'); } const { publicKey } = body; @@ -68,8 +59,6 @@ const authCb = Commands.SSO_AUTH_CB = function (Env, body, cb, req) { if (err) { return void cb('ENOENT'); } const data = Util.tryParse(value); if (!data || !data.type || !TYPES[data.type]) { return void cb('INVALID_REQUEST_DATA'); } - console.log('stored', data.publicKey); - console.log('used', publicKey); if (publicKey !== data.publicKey) { return void cb('WRONG_SIGNATURE_KEYS'); } cb(); }); @@ -86,20 +75,155 @@ authCb.complete = function (Env, body, cb, req) { const data = Util.tryParse(value); const cfg = getProviderConfig(Env, data.provider); const idp = TYPES[data.type]; + const register = data.register; idp.authCb(Env, cfg, ssotoken, url, (err, obj) => { if (err) { return void cb(err); } - const {id, idpData} = obj; - console.log(id, idpData); - SSOUtils.makeUser(Env, id, (err, userData) => { - if (err) { return void cb(err); } + const {id, idpData, name} = obj; - // TODO - // makeTempSession() - - cb(void 0, { state: true }); - }); + let next = (user, isRegister) => { + SSOUtils.createJWT(Env, id, data.provider, idpData, (err, jwt) => { + if (err) { return void cb(err); } + cb(void 0, { + jwt: jwt, + name: name, + seed: user.seed, + password: Boolean(user.password), + register: isRegister + }); + }); + }; + if (register) { + SSOUtils.writeUser(Env, id, (err, userData) => { + if (err && err.code === 'EEXIST') { + return void SSOUtils.readUser(Env, id, (err, userData) => { + if (err) { return void cb(err); } + next(userData, false); + }); + } + if (err) { return void cb(err); } + next(userData, true); + }); + } else { + SSOUtils.readUser(Env, id, (err, userData) => { + if (err) { return void cb(err); } + next(userData, false); + }); + } }); }); }; +// XXX write block change-password? should be the same as otp but without otp code +const register = Commands.SSO_WRITE_BLOCK = function (Env, body, cb) { + const { publicKey, content } = body; + + // they must provide a valid block public key + if (!Block.isValidBlockId(publicKey)) { return void cb("INVALID_KEY"); } + if (publicKey !== content.publicKey) { return void cb("INVALID_KEY"); } + const jwt = content.auth; + if (!jwt) { return void cb('NO_JWT'); } + + BlockStore.isAvailable(Env, publicKey, (err, result) => { + if (err || result) { + return void cb(err || 'EEXISTS'); + } + // No block at this location: continue + cb(); + }); +}; +register.complete = function (Env, body, cb) { + const { publicKey, content } = body; + const jwt = content.auth; + const pw = content.hasPassword; + let payload; + let ssoUser; + // XXX UPDATE sso_user add password boolean + nThen((w) => { + SSOUtils.checkJWT(Env, jwt, w((err, _payload) => { + if (err) { + w.abort(); + return void cb('INVALID_JWT_SIGNATURE'); + } + payload = _payload; + })); + }).nThen((w) => { + const { sub } = payload; + SSOUtils.readUser(Env, sub, w((err, user) => { + if (err) { + w.abort(); + console.log(err, sub); + return void cb('SSO_NO_USER'); + } + ssoUser = user; + })); + }).nThen((w) => { + const { sub } = payload; + SSOUtils.writeBlock(Env, publicKey, sub, w((err) => { + if (err) { + w.abort(); + return void cb('SSO_BLOCK_WRITE'); + } + })); + }).nThen((w) => { + Block.writeLoginBlock(Env, content, w((err) => { + if (err) { w.abort(); } + })); + }).nThen((w) => { + if (!pw) { return; } + const { sub } = payload; + ssoUser.password = true; + SSOUtils.updateUser(Env, sub, ssoUser, w()); + }).nThen(() => { + const { data, provider } = payload; + SSOUtils.makeSession(Env, publicKey, provider, data, cb); + }); +}; + +const login = Commands.SSO_VALIDATE = function (Env, body, cb) { + const { publicKey, jwt } = body; + + // they must provide a valid block public key + if (!Block.isValidBlockId(publicKey)) { return void cb("INVALID_KEY"); } + if (!jwt) { return void cb('NO_JWT'); } + + BlockStore.isAvailable(Env, publicKey, (err, result) => { + if (err && !result) { return void cb(err); } + // Block found + cb(); + }); +}; +login.complete = function (Env, body, cb) { + const { publicKey, jwt } = body; + + let payload; + nThen((w) => { + SSOUtils.checkJWT(Env, jwt, w((err, _payload) => { + if (err) { + w.abort(); + return void cb('INVALID_JWT_SIGNATURE'); + } + payload = _payload; + })); + }).nThen((w) => { + const { sub } = payload; + SSOUtils.readUser(Env, sub, w((err) => { + if (err) { + w.abort(); + console.log(err, sub); + return void cb('SSO_NO_USER'); + } + })); + }).nThen((w) => { + SSOUtils.readBlock(Env, publicKey, w((err) => { + if (err) { + w.abort(); + return void cb('SSO_BLOCK_WRITE'); + } + })); + }).nThen(() => { + const { data, provider } = payload; + SSOUtils.makeSession(Env, publicKey, provider, data, cb); + }); + +}; diff --git a/lib/challenge-commands/totp.js b/lib/challenge-commands/totp.js index 45f2cedd6..ddcfb31a5 100644 --- a/lib/challenge-commands/totp.js +++ b/lib/challenge-commands/totp.js @@ -1,7 +1,6 @@ /* globals Buffer */ const B32 = require("thirty-two"); const OTP = require("notp"); -const JWT = require("jsonwebtoken"); const nThen = require("nthen"); const Util = require("../common-util"); @@ -62,43 +61,10 @@ var decode32 = S => { // Allow user settings? var EXPIRATION = 7 * 24 * 3600 * 1000; // Sessions are valid 7 days -var createJWT = function (Env, sessionId, publicKey, cb) { - JWT.sign({ - // this is a custom JWT field (not a standard) - we include a reference to the session - // which is used to look up whether it has been revoked. - ref: sessionId, - // we specify in the token for what resource the token should be valid (their block's public key) - sub: Util.escapeKeyCharacters(publicKey), - exp: (+new Date()) + EXPIRATION - }, Env.bearerSecret, { - // token integrity is ensured with HMAC SHA512 with the server's bearerSecret - // clients can inspect token parameters, but cannot modify them - algorithm: 'HS512', - // if you want it to expire you can set this for an arbitrary number of seconds in the future, but I won't assume that for now - //expiresIn: (60 * 60 * 24 * 7)), - }, function (err, token) { - if (err) { return void cb(err); } - cb(void 0, token); - }); -}; - // Create a session with a token for the given public key const makeSession = (Env, publicKey, cb) => { const sessionId = Sessions.randomId(); - var token; nThen(function (w) { - /*createJWT(Env, sessionId, publicKey, w(function (err, _token) { - if (err) { - Env.Log.error("TOTP_VALIDATE_JWT_SIGN_ERROR", { - error: Util.serializeError(err), - publicKey: publicKey, - }); - w.abort(); - return void cb("TOKEN_ERROR"); - } - token = _token; - }));*/ - }).nThen(function (w) { // store the token Sessions.write(Env, publicKey, sessionId, JSON.stringify({ mfa: { @@ -340,7 +306,7 @@ So, we should: }; // Same as TOTP_VALIDATE but without making a session at the end -const check = Commands.TOTP_CHECK = function (Env, body, cb) { +const check = Commands.TOTP_MFA_CHECK = function (Env, body, cb) { var { publicKey, auth } = body; const code = auth; if (!isValidOTP(code)) { return void cb('E_INVALID'); } diff --git a/lib/http-commands.js b/lib/http-commands.js index 2c19de250..8e397b5b1 100644 --- a/lib/http-commands.js +++ b/lib/http-commands.js @@ -68,7 +68,7 @@ COMMANDS.REMOVE_BLOCK = NOAUTH.REMOVE_BLOCK; const TOTP = require("./challenge-commands/totp.js"); COMMANDS.TOTP_SETUP = TOTP.TOTP_SETUP; COMMANDS.TOTP_VALIDATE = TOTP.TOTP_VALIDATE; -COMMANDS.TOTP_CHECK = TOTP.TOTP_CHECK; +COMMANDS.TOTP_MFA_CHECK = TOTP.TOTP_MFA_CHECK; COMMANDS.TOTP_REVOKE = TOTP.TOTP_REVOKE; COMMANDS.TOTP_WRITE_BLOCK = TOTP.TOTP_WRITE_BLOCK; COMMANDS.TOTP_REMOVE_BLOCK = TOTP.TOTP_REMOVE_BLOCK; @@ -76,6 +76,8 @@ COMMANDS.TOTP_REMOVE_BLOCK = TOTP.TOTP_REMOVE_BLOCK; const SSO = require("./challenge-commands/sso.js"); COMMANDS.SSO_AUTH = SSO.SSO_AUTH; COMMANDS.SSO_AUTH_CB = SSO.SSO_AUTH_CB; +COMMANDS.SSO_WRITE_BLOCK = SSO.SSO_WRITE_BLOCK; +COMMANDS.SSO_VALIDATE = SSO.SSO_VALIDATE; var randomToken = () => Nacl.util.encodeBase64(Nacl.randomBytes(24)).replace(/\//g, '-'); diff --git a/lib/http-worker.js b/lib/http-worker.js index 855062c59..50fba51c0 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -7,8 +7,8 @@ const nThen = require("nthen"); const Util = require("./common-util"); const Logger = require("./log"); const AuthCommands = require("./http-commands"); -const JWT = require("jsonwebtoken"); const MFA = require("./storage/mfa"); +const SSOUtils = require("./sso-utils"); const Sessions = require("./storage/sessions"); const cookieParser = require("cookie-parser"); @@ -272,7 +272,7 @@ app.use('/block/', function (req, res, next) { var authorization = req.headers.authorization; - var mfa_params, jwt_payload; + var mfa_params, sso_params; nThen(function (w) { // First, check whether the block id in question has any MFA settings stored MFA.read(Env, name, w(function (err, content) { @@ -281,8 +281,7 @@ app.use('/block/', function (req, res, next) { // in either case you can abort and fall through // allowing the static webserver to handle either case if (err && err.code === 'ENOENT') { - w.abort(); - return void next(); + return; } // we're not expecting other errors. the sensible thing is to fail @@ -313,10 +312,30 @@ app.use('/block/', function (req, res, next) { }); } })); + + // Same for SSO settings + SSOUtils.readBlock(Env, name, w(function (err, content) { + if (err && err.code === 'ENOENT') { + return; + } + if (err) { + Log.error('GET_BLOCK_METADATA', err); + return void res.status(500).json({ + code: 500, + error: "UNEXPECTED_ERROR", + }); + } + sso_params = content; + })); + }).nThen(function (w) { + if (!mfa_params && !sso_params) { + w.abort(); + next(); + } }).nThen(function (w) { // We should only be able to reach this logic // if we successfully loaded and parsed some JSON - // representing the user's MFA settings. + // representing the user's MFA and/or SSO settings. // Failures at this point relate to insufficient or incorrect authorization. // This function standardizes how we reject such requests. @@ -328,18 +347,18 @@ app.use('/block/', function (req, res, next) { var no = function () { w.abort(); res.status(401).json({ - method: mfa_params.method, + method: (mfa_params && mfa_params.method) || (sso_params && 'SSO'), code: 401 }); }; - // if you are here it is because this block is protected by MFA. + // if you are here it is because this block is protected by MFA or SSO. // they will need to provide a JSON Web Token, so we can reject them outright // if one is not present in their authorization header if (!authorization) { return void no(); } // The authorization header should be of the form - // "Authorization: Bearer " + // "Authorization: Bearer " // We can reject the request if it is malformed. let token = authorization.replace(/^Bearer\s+/, '').trim(); if (!token) { return void no(); } @@ -355,8 +374,12 @@ app.use('/block/', function (req, res, next) { let content = Util.tryParse(contentStr); + if (mfa_params && !content.mfa) { return void no(); } + if (sso_params && !content.sso) { return void no(); } + if (content.mfa && content.mfa.exp && ((+new Date()) > content.mfa.exp)) { - Log.error("OTP_SESSION_EXPIRED", payload); + Log.error("OTP_SESSION_EXPIRED", content.mfa); + // XXX Only delete the mfa part Sessions.delete(Env, name, token, function (err) { if (err) { Log.error('SESSION_DELETE_EXPIRED_ERROR', err); @@ -367,93 +390,34 @@ app.use('/block/', function (req, res, next) { return void no(); } - // we could also check whether the content of the file matches the token, - // but clients don't have any influence over the reference and can only - // request to create tokens that are scoped to a public key they control. - // I don' think there's any practical benefit to such a check. - // So, interpret the existence of a file in that location as the continued - // validity of the session. Fall through and let the built-in webserver - // handle the 404 or serving the file. - next(); - }); - - // Otherwise we attempt to validate the token - // Successful validation implies that the token was issued by the server - // since only the server should possess the current bearer secret (unless it has leaked). - - // It is still possible that the token is not valid for this particular resource, - // so the algorithm (HMAC SHA512) only asserts its integrity, not its validity. - /* - JWT.verify(token, Env.bearerSecret, { - algorithm: 'HS512', - }, w(function (err, payload) { - if (err) { - // the token could not be validated for some reason. - // it might have expired, the server might have rotated secrets, - // it might not be well-formed, etc. - // log and respond. - Log.info('INVALID_JWT', { - error: err, - token: token, - }); - return void no(); - } - - // Now that we have the payload we can inspect its properties - // and reject anything which is obviously wrong without requiring - // any async I/O - - // Tokens are issued with a "reference" - a random id which is - // used alongside the block id to look up whether a given session - // is still valid - - // reject if it does not provide a lookup reference - if (typeof(payload.ref) !== 'string') { - Log.error("JWT_NO_REFERENCE", payload); - return void no(); - } - - // A JWT can optionally indicate a finite lifetime. - // reject if it's too old - if (payload.exp && ((+new Date()) > payload.exp)) { - Log.error("JWT_EXPIRED", payload); - Sessions.delete(Env, name, payload.ref, function (err) { - if (err) { - Log.error('JWT_SESSION_DELETE_EXPIRED_ERROR', err); - return; + if (content.sso) { + SSOUtils.checkSession(Env, content.sso, (err, state, newState) => { + if (err || !state) { + // XXX Only delete the mfa part + Sessions.delete(Env, name, token, function (err) { + if (err) { + Log.error('SSO_SESSION_DELETE_EXPIRED_ERROR', err); + return; + } + Log.info('SSO_SESSION_DELETE_EXPIRED', err); + }); + return void no(); } - Log.info('JWT_SESSION_DELETE_EXPIRED', err); - }); - return void no(); - } - - // A JWT indicates the subject (the block id) for which it is valid - // reject if it does not match the block the client is trying to access - if (payload.sub !== name) { - Log.error("JWT_SUBJECT_MISMATCH", payload); - return void no(); - } - - // otherwise, it seems basically correct. - Log.verbose("VALID_JWT", payload); - - // remember the payload for subsequent asynchronous checks - jwt_payload = payload; - })); - */ - }).nThen(function () { - // Finally, even if the JWT itself seems valid, the database - // is the final authority as to whether the session is still valid, - // as it might have been revoked - /* - Sessions.read(Env, name, jwt_payload.ref, function (err) { - if (err) { - Log.error('JWT_SESSION_READ_ERROR', err); - return res.status(401).json({ - method: mfa_params.method, - code: 401, + if (newState) { + content.sso = newState; + // XXX We should produce a new session ID here and send it back to the user + Sessions.update(Env, name, token, JSON.stringify(content), (err) => { + if (err) { + Log.error('SSO_SESSION_UPDATE_ERROR', err); + return; + } + Log.info('SSO_SESSION_UPDATED', err); + }); + } + next(); }); + return; } // we could also check whether the content of the file matches the token, @@ -466,7 +430,6 @@ app.use('/block/', function (req, res, next) { // handle the 404 or serving the file. next(); }); - */ }); }); diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js index a61ce0846..caa904a85 100644 --- a/lib/plugins/sso/oidc.js +++ b/lib/plugins/sso/oidc.js @@ -27,10 +27,6 @@ module.exports = { const generators = OID.generators; const code_verifier = generators.codeVerifier(); - // store the code_verifier in your framework's session mechanism, if it is a cookie based solution - // it should be httpOnly (not readable by javascript) and encrypted. - - console.log(code_verifier); const code_challenge = generators.codeChallenge(code_verifier); const url = client.authorizationUrl({ scope: 'openid email profile',// https://www.googleapis.com/auth/contacts.readonly', // https://www.google.com/m8/feeds @@ -52,10 +48,11 @@ module.exports = { .then((tokenSet) => { let j = tokenSet; let c = tokenSet.claims(); - console.log(j, c); cb(void 0, { id: c.sub, + name: c.name, idpData: { + expires_at: j.expires_at, access_token: j.access_token, refresh_token: j.refresh_token, id_token: j.id_token @@ -63,5 +60,25 @@ module.exports = { }); }); }); + }, + checkSession: (Env, cfg, data, cb) => { + const { refresh_token } = data; + + let t = new OID.TokenSet(data); + if (!t.expired()) { return void cb(void 0, true); } + getClient(cfg, (err, client) => { + client.refresh(t.refresh_token).then((j) => { + const newData = { + refresh_token: refresh_token, + id_token: j.id_token, + access_token: j.access_token, + expires_at: j.expires_at + }; + cb(void 0, true, newData); + }, () => { + // Error: can't renew token + cb(void 0, false); + }); + }); } }; diff --git a/lib/sso-utils.js b/lib/sso-utils.js index 1bad43d5d..3e11047e2 100644 --- a/lib/sso-utils.js +++ b/lib/sso-utils.js @@ -1,13 +1,39 @@ const SSO = require("./storage/sso"); +const Sessions = require("./storage/sessions"); const Nacl = require("tweetnacl/nacl-fast"); +const JWT = require("jsonwebtoken"); +const Util = require("./common-util"); const SSOUtils = module.exports; // XXX const SAML = require('node-saml'); // https://www.npmjs.com/package/node-saml -SSOUtils.TYPES = { +const TYPES = SSOUtils.TYPES = { oidc: require('./plugins/sso/oidc') }; +const checkConfig = SSOUtils.checkConfig = (Env) => { + return Env && Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && Env.sso.list.length; +}; +const getProviderConfig = SSOUtils.getProviderConfig = (Env, provider) => { + if (!checkConfig(Env)) { return; } + if (!provider) { return; } + const data = Env.sso.list.find((cfg) => { return cfg.name === provider; }); + return data; +}; +SSOUtils.isValidConfig = (cfg) => { + if (!cfg) { return; } + if (!cfg.type) { return; } + const type = cfg.type.toLowerCase(); + const idp = TYPES[type]; + if (!idp) { return; } + return idp.checkConfig(cfg); +}; + +SSOUtils.checkSession = (Env, sessionData, cb) => { + const cfg = getProviderConfig(Env, sessionData.provider); + const idp = TYPES[cfg.type.toLowerCase()]; + idp.checkSession(Env, cfg, sessionData.data, cb); +}; SSOUtils.deleteRequest = (Env, id) => { SSO.request.delete(Env, id, (err) => { @@ -34,15 +60,84 @@ SSOUtils.writeRequest = (Env, data, cb) => { }; -SSOUtils.makeUser = (Env, id, cb) => { - const seed = Nacl.util.encodeBase64(Nacl.util.randomBytes(24)); - SSO.User.write(Env, id, JSON.stringify({ +SSOUtils.writeUser = (Env, id, cb) => { + const seed = Nacl.util.encodeBase64(Nacl.randomBytes(24)); + SSO.user.write(Env, id, JSON.stringify({ seed: seed, - password: false // XXX maybe we don't need that flag, we can check if the block exists later + password: false }), (err) => { if (err) { return void cb(err); } cb(void 0, { seed }); }); +}; +SSOUtils.readUser = (Env, id, cb) => { + SSO.user.read(Env, id, (err, user) => { + if (err) { return void cb(err); } + cb(void 0, Util.tryParse(user)); + }); +}; +SSOUtils.updateUser = (Env, id, data, cb) => { + SSO.user.delete(Env, id, () => { + SSO.user.write(Env, id, JSON.stringify(data), (err) => { + if (err) { return void cb(err); } + cb(); + }); + }); +}; + +SSOUtils.writeBlock = (Env, id, ssoID, cb) => { + SSO.block.write(Env, id, JSON.stringify({ + id: ssoID + }), (err) => { + if (err) { return void cb(err); } + cb(); + }); +}; +SSOUtils.readBlock = (Env, id, cb) => { + SSO.block.read(Env, id, (err, blockData) => { + if (err) { return void cb(err); } + cb(void 0, Util.tryParse(blockData)); + }); +}; + +// Store the SSO data (tokens, etc.) in a JWT while waiting for the user's CryptPad password +SSOUtils.createJWT = (Env, ssoId, provider, data, cb) => { + JWT.sign({ + sub: ssoId, + data: data, + provider: provider + }, Env.bearerSecret, { + // token integrity is ensured with HMAC SHA512 with the server's bearerSecret + // clients can inspect token parameters, but cannot modify them + algorithm: 'HS512', + // if you want it to expire you can set this for an arbitrary number of seconds in the future + expiresIn: 300, + }, function (err, token) { + if (err) { return void cb(err); } + cb(void 0, token); + }); +}; +SSOUtils.checkJWT = (Env, token, cb) => { + JWT.verify(token, Env.bearerSecret, { + algorithm: 'HS512', + }, function (err, payload) { + if (err) { + // the token could not be validated for some reason. + // it might have expired, the server might have rotated secrets, + // it might not be well-formed, etc. + // log and respond. + Env.Log.info('INVALID_JWT', { + error: err, + token: token, + }); + return void cb('INVALID_JWT'); + } + + // otherwise, it seems basically correct. + Env.Log.verbose("VALID_JWT", payload); + + cb(void 0, payload); + }); }; @@ -61,7 +156,7 @@ SSOUtils.makeSession = (Env, publicKey, provider, ssoData, cb) => { publicKey: publicKey, sessionId: sessionId, }); - return void cb("SESSION_WRITE_ERROR"); + return void cb("SSO_NO_SESSION"); } cb(void 0, { bearer: sessionId, diff --git a/lib/storage/sessions.js b/lib/storage/sessions.js index f31151ec8..30283dc47 100644 --- a/lib/storage/sessions.js +++ b/lib/storage/sessions.js @@ -42,6 +42,14 @@ Sessions.delete = function (Env, id, ref, cb) { Basic.delete(Env, path, cb); }; +Sessions.update = function (Env, id, ref, data, cb) { + var path = pathFromId(Env, id, ref); + Basic.delete(Env, path, (err) => { + if (err) { return void cb(err); } + Basic.write(Env, path, data, cb); + }); +}; + Sessions.deleteUser = function (Env, id, cb) { if (!id || typeof(id) !== 'string') { return; } id = Util.escapeKeyCharacters(id); diff --git a/lib/storage/sso.js b/lib/storage/sso.js index 65110ee30..b28203fd5 100644 --- a/lib/storage/sso.js +++ b/lib/storage/sso.js @@ -6,7 +6,8 @@ const SSO = module.exports; /* This module manages storage related to Single Sign-On (SSO) settings. A first part (sso-requests) contains temporary files for sso authentication with a remote service -and a second part (sso users) is a database of accounts registered via SSO. +A second part (sso-users) is a database of accounts registered via SSO (SSO id ==> block seed) +A third part (sso-blocks) is a databse of blocks that are sso-protected (block id ==> SSO id...) The path for requests is based on the "authentication request" token depending on the type of SSO. The path for the user database is based on their persistent identifier (id) from the SSO. @@ -21,7 +22,10 @@ var reqPathFromId = function (Env, id) { return pathFromId(Env, id, 'sso_request'); }; var userPathFromId = function (Env, id) { - return pathFromId(Env, id, 'sso'); + return pathFromId(Env, id, 'sso_user'); +}; +var blockPathFromId = function (Env, id) { + return pathFromId(Env, id, 'sso_block'); }; const Req = SSO.request = {}; @@ -55,3 +59,18 @@ User.delete = function (Env, id, cb) { var path = userPathFromId(Env, id); Basic.delete(Env, path, cb); }; + +const Block = SSO.block = {}; + +Block.read = function (Env, id, cb) { + var path = blockPathFromId(Env, id); + Basic.read(Env, path, cb); +}; +Block.write = function (Env, id, data, cb) { + var path = blockPathFromId(Env, id); + Basic.write(Env, path, data, cb); +}; +Block.delete = function (Env, id, cb) { + var path = blockPathFromId(Env, id); + Basic.delete(Env, path, cb); +}; diff --git a/www/common/common-login.js b/www/common/common-login.js new file mode 100644 index 000000000..007c0bbfc --- /dev/null +++ b/www/common/common-login.js @@ -0,0 +1,520 @@ +define([ + 'chainpad-listmap', + '/bower_components/chainpad-crypto/crypto.js', + '/common/common-util.js', + '/common/outer/network-config.js', + '/common/common-credential.js', + '/bower_components/chainpad/chainpad.dist.js', + '/common/common-realtime.js', + '/common/common-constants.js', + '/common/common-interface.js', + '/common/common-feedback.js', + '/common/outer/local-store.js', + '/customize/messages.js', + '/bower_components/nthen/index.js', + '/common/outer/login-block.js', + '/common/common-hash.js', + '/common/outer/http-command.js', + + '/bower_components/tweetnacl/nacl-fast.min.js', + '/bower_components/scrypt-async/scrypt-async.min.js', // better load speed +], function (Listmap, Crypto, Util, NetConfig, Cred, ChainPad, Realtime, Constants, UI, + Feedback, LocalStore, Messages, nThen, Block, Hash, ServerCommand) { + var Nacl = window.nacl; + + var Exports = { + requiredBytes: 192, + }; + + var allocateBytes = Exports.allocateBytes = function (bytes) { + var dispense = Cred.dispenser(bytes); + + var opt = {}; + + // dispense 18 bytes of entropy for your encryption key + var encryptionSeed = dispense(18); + // 16 bytes for a deterministic channel key + var channelSeed = dispense(16); + // 32 bytes for a curve key + var curveSeed = dispense(32); + + var curvePair = Nacl.box.keyPair.fromSecretKey(new Uint8Array(curveSeed)); + opt.curvePrivate = Nacl.util.encodeBase64(curvePair.secretKey); + opt.curvePublic = Nacl.util.encodeBase64(curvePair.publicKey); + + // 32 more for a signing key + var edSeed = opt.edSeed = dispense(32); + + // 64 more bytes to seed an additional signing key + var blockKeys = opt.blockKeys = Block.genkeys(new Uint8Array(dispense(64))); + opt.blockHash = Block.getBlockHash(blockKeys); + + // derive a private key from the ed seed + var signingKeypair = Nacl.sign.keyPair.fromSeed(new Uint8Array(edSeed)); + + opt.edPrivate = Nacl.util.encodeBase64(signingKeypair.secretKey); + opt.edPublic = Nacl.util.encodeBase64(signingKeypair.publicKey); + + var keys = opt.keys = Crypto.createEditCryptor(null, encryptionSeed); + + // 24 bytes of base64 + keys.editKeyStr = keys.editKeyStr.replace(/\//g, '-'); + + // 32 bytes of hex + var channelHex = opt.channelHex = Util.uint8ArrayToHex(channelSeed); + + // should never happen + if (channelHex.length !== 32) { throw new Error('invalid channel id'); } + + var channel64 = Util.hexToBase64(channelHex); + + // we still generate a v1 hash because this function needs to deterministically + // derive the same values as it always has. New accounts will generate their own + // userHash values + opt.userHash = '/1/edit/' + [channel64, opt.keys.editKeyStr].join('/') + '/'; + + return opt; + }; + + var loginOptionsFromBlock = Exports.loginOptionsFromBlock = function (blockInfo) { + var opt = {}; + var parsed = Hash.getSecrets('pad', blockInfo.User_hash); + opt.channelHex = parsed.channel; + opt.keys = parsed.keys; + opt.edPublic = blockInfo.edPublic; + return opt; + }; + + var loadUserObject = Exports.loadUserObject = function (opt, cb) { + var config = { + websocketURL: NetConfig.getWebsocketURL(), + channel: opt.channelHex, + data: {}, + validateKey: opt.keys.validateKey, // derived validation key + crypto: Crypto.createEncryptor(opt.keys), + logLevel: 1, + classic: true, + ChainPad: ChainPad, + owners: [opt.edPublic] + }; + + var rt = opt.rt = Listmap.create(config); + rt.proxy + .on('ready', function () { + setTimeout(function () { cb(void 0, rt); }); + }) + .on('disconnect', function (info) { + cb('E_DISCONNECT', info); + }); + }; + + var isProxyEmpty = Exports.isProxyEmpty = function (proxy) { + var l = Object.keys(proxy).length; + return l === 0 || (l === 2 && proxy._events && proxy.on); + }; + + var legacyLogin = function (opt, isRegister, cb, res) { + res = res || {}; + loadUserObject(opt, function (err, rt) { + if (err) { return void cb(err); } + + // if a proxy is marked as deprecated, it is because someone had a non-owned drive + // but changed their password, and couldn't delete their old data. + // if they are here, they have entered their old credentials, so we should not + // allow them to proceed. In time, their old drive should get deleted, since + // it will should be pinned by anyone's drive. + if (rt.proxy[Constants.deprecatedKey]) { + return void cb('NO_SUCH_USER'); + } + + if (isRegister && isProxyEmpty(rt.proxy)) { + // If they are trying to register, + // and the proxy is empty, then there is no 'legacy user' either + // so we should just shut down this session and disconnect. + //rt.network.disconnect(); + return void cb(); // proceed to the next async block + } + + // they tried to just log in but there's no such user + // and since we're here at all there is no modern-block + if (!isRegister && isProxyEmpty(rt.proxy)) { + return void cb('NO_SUCH_USER'); + } + + // they tried to register, but those exact credentials exist + if (isRegister && !isProxyEmpty(rt.proxy)) { + Feedback.send('LOGIN', true); + return void cb('ALREADY_REGISTERED'); + } + + // if you are here, then there is no block, the user is trying + // to log in. The proxy is **not** empty. All values assigned here + // should have been deterministically created using their credentials + // so setting them is just a precaution to keep things in good shape + res.proxy = rt.proxy; + res.realtime = rt.realtime; + res.network = rt.network; + + // they're registering... + res.userHash = opt.userHash; + res.userName = res.uname; + + // export their signing key + res.edPrivate = opt.edPrivate; + res.edPublic = opt.edPublic; + + // export their encryption key + res.curvePrivate = opt.curvePrivate; + res.curvePublic = opt.curvePublic; + + // don't proceed past this async block. + + // We have to call whenRealtimeSyncs asynchronously here because in the current + // version of listmap, onLocal calls `chainpad.contentUpdate(newValue)` + // asynchronously. + // The following setTimeout is here to make sure whenRealtimeSyncs is called after + // `contentUpdate` so that we have an update userDoc in chainpad. + setTimeout(function () { + Realtime.whenRealtimeSyncs(rt.realtime, function () { + // the following stages are there to initialize a new drive + // if you are registering + LocalStore.login(res.userHash, undefined, res.userName, function () { + setTimeout(function () { cb(void 0, res); }); + }); + }); + }); + }); + }; + + var getProxyOpt = function (blockInfo) { + var opt; + if (blockInfo) { + opt = loginOptionsFromBlock(blockInfo); + opt.userHash = blockInfo.User_hash; + } else { + console.log("allocating random bytes for a new user object"); + opt = allocateBytes(Nacl.randomBytes(Exports.requiredBytes)); + // create a random v2 hash, since we don't need backwards compatibility + opt.userHash = Hash.createRandomHash('drive'); + var secret = Hash.getSecrets('drive', opt.userHash); + opt.keys = secret.keys; + opt.channelHex = secret.channel; + } + + console.warn(opt); + return opt; + }; + + var modernLoginRegister = function (opt, isRegister, cb, res) { + res = res || {}; + // according to the location derived from the credentials which you entered + loadUserObject(opt, function (err, rt) { + if (err) { return void cb('MODERN_REGISTRATION_INIT'); } + + // export the realtime object you checked + var RT = rt; + + var proxy = rt.proxy; + if (isRegister && !isProxyEmpty(proxy) && (!proxy.edPublic || !proxy.edPrivate)) { + console.error("INVALID KEYS"); + console.log(JSON.stringify(proxy)); + return void cb(void 0, void 0, RT); + } + + res.proxy = rt.proxy; + res.realtime = rt.realtime; + res.network = rt.network; + + // they're registering... + res.userHash = opt.userHash; + res.userName = res.uname; + + // somehow they have a block present, but nothing in the user object it specifies + // this shouldn't happen, but let's send feedback if it does + if (!isRegister && isProxyEmpty(rt.proxy)) { + // this really shouldn't happen, but let's handle it anyway + Feedback.send('EMPTY_LOGIN_WITH_BLOCK'); + return void cb('NO_SUCH_USER'); + } + + // they tried to register, but those exact credentials exist + if (isRegister && !isProxyEmpty(rt.proxy)) { + //rt.network.disconnect(); + return void cb('ALREADY_REGISTERED'); + } + + if (!isRegister && !isProxyEmpty(rt.proxy)) { + var l = Util.find(rt.proxy, ['settings', 'general', 'language']); + var LS_LANG = "CRYPTPAD_LANG"; + if (l) { localStorage.setItem(LS_LANG, l); } + + if (res.auth_token && res.auth_token.bearer) { + LocalStore.setSessionToken(res.auth_token.bearer); + } + return void LocalStore.login(undefined, res.blockHash, res.uname, function () { + cb(void 0, res, RT); + }); + } + + if (isRegister && isProxyEmpty(rt.proxy)) { + proxy.edPublic = opt.edPublic; + proxy.edPrivate = opt.edPrivate; + proxy.curvePublic = opt.curvePublic; + proxy.curvePrivate = opt.curvePrivate; + proxy.login_name = res.uname; + proxy[Constants.displayNameKey] = res.uname; + proxy.version = 11; + + Feedback.send('REGISTRATION', true); + } else { + Feedback.send('LOGIN', true); + } + + setTimeout(function () { + Realtime.whenRealtimeSyncs(rt.realtime, function () { + cb(void 0, void 0, RT); + }); + }); + }); + }; + + Exports.loginOrRegister = function (config, cb) { + let { uname, passwd, isRegister, onOTP, ssoAuth } = config; + if (typeof(cb) !== 'function') { return; } + + // Usernames are all lowercase. No going back on this one + uname = uname.toLowerCase(); + + // validate inputs + if (!Cred.isValidUsername(uname)) { return void cb('INVAL_USER'); } + if (!Cred.isValidPassword(passwd) && !ssoAuth) { return void cb('INVAL_PASS'); } + if (isRegister && !ssoAuth && !Cred.isLongEnoughPassword(passwd)) { + return void cb('PASS_TOO_SHORT'); + } + + // results... + var res = { + register: isRegister, + uname: uname + }; + if (ssoAuth && ssoAuth.name) { res.uname = ssoAuth.name; } + + var RT, blockKeys, blockUrl; + + nThen(function (waitFor) { + // derive a predefined number of bytes from the user's inputs, + // and allocate them in a deterministic fashion + Cred.deriveFromPassphrase(uname, passwd, Exports.requiredBytes, waitFor(function (bytes) { + res.opt = allocateBytes(bytes); + res.blockHash = res.opt.blockHash; + blockKeys = res.opt.blockKeys; + })); + }).nThen(function (waitFor) { + // the allocated bytes can be used either in a legacy fashion, + // or in such a way that a previously unused byte range determines + // the location of a layer of indirection which points users to + // an encrypted block, from which they can recover the location of + // the rest of their data + + // determine where a block for your set of keys would be stored + blockUrl = Block.getBlockUrl(res.opt.blockKeys); + + var TOTP_prompt = function (err, cb) { + onOTP(function (code) { + ServerCommand(res.opt.blockKeys.sign, { + command: 'TOTP_VALIDATE', + code: code, + // TODO optionally allow the user to specify a lifetime for this session? + // this will require a little bit of server work + // and more UI/UX: + // ie. just a simple "remember me" checkbox? + // allow them to specify a lifetime for the session? + // "log me out after one day"? + }, cb); + }, false, err); + }; + + var done = waitFor(); + var responseToDecryptedBlock = function (response, cb) { + response.arrayBuffer().then(arraybuffer => { + arraybuffer = new Uint8Array(arraybuffer); + var decryptedBlock = Block.decrypt(arraybuffer, blockKeys); + if (!decryptedBlock) { + console.error("BLOCK DECRYPTION ERROR"); + return void cb("BLOCK_DECRYPTION_ERROR"); + } + cb(void 0, decryptedBlock); + }); + }; + + var missingAuth; + nThen(function (w) { + Util.getBlock(blockUrl, { + // request the block without credentials + }, w(function (err, response) { + if (err === 401) { + missingAuth = response && response.method; + return void console.log("Block requires 2FA"); + } + + // Some other error? + if (err) { + console.error(err); + w.abort(); + return void done(); + } + + // If the block was returned without requiring authentication + // then we can abort the subsequent steps of this nested nThen + w.abort(); + + // decrypt the response and continue the normal procedure with its payload + responseToDecryptedBlock(response, function (err, decryptedBlock) { + if (err) { + // if a block was present but you were not able to decrypt it... + console.error(err); + waitFor.abort(); + return void cb(err); + } + res.blockInfo = decryptedBlock; + done(); + }); + })); + }).nThen(function (w) { + if (missingAuth !== 'SSO') { return; } // XXX multiple auth + ServerCommand(res.opt.blockKeys.sign, { + command: 'SSO_VALIDATE', + jwt: ssoAuth.data, + }, w(function (err, response) { + if (err) { + // XXX + return; + } + res.auth_token = response; + })); + }).nThen(function (w) { + if (missingAuth !== 'TOTP') { return; } // XXX multiple auth + // if you're here then you need to request a JWT + var done = w(); + var tries = 3; + var ask = function () { + if (!tries) { + w.abort(); + waitFor.abort(); + return void cb('TOTP_ATTEMPTS_EXHAUSTED'); + } + tries--; + TOTP_prompt(tries !== 2, function (err, response) { + // ask again until your number of tries are exhausted + if (err) { + console.error(err); + console.log("Normal failure. Asking again..."); + return void ask(); + } + if (!response || !response.bearer) { + console.log(response); + console.log("Unexpected failure. No bearer token. Asking again"); + return void ask(); + } + console.log("Successfully retrieved a bearer token"); + res.auth_token = response; + done(); + }); + }; + ask(); + }).nThen(function (w) { + Util.getBlock(blockUrl, res.auth_token, function (err, response) { + if (err) { + w.abort(); + console.error(err); + return void cb('BLOCK_ERROR_3'); + } + + responseToDecryptedBlock(response, function (err, decryptedBlock) { + if (err) { + waitFor.abort(); + return void cb(err); + } + res.blockInfo = decryptedBlock; + done(); + }); + }); + }); + }).nThen(function (waitFor) { + + // we assume that if there is a block, it was created in a valid manner + // so, just proceed to the next block which handles that stuff + if (res.blockInfo) { return; } + + var opt = res.opt; + + // load the user's object using the legacy credentials + legacyLogin(opt, isRegister, waitFor(function (err, data) { + if (err) { + waitFor.abort(); + return void cb(err); + } + if (!data) { return; } // Go to next block (modern registration) + + // No error and data: success legacy login + waitFor.abort(); + cb(void 0, data); + }), res); + }).nThen(function (waitFor) { // MODERN REGISTRATION / LOGIN + var opt = getProxyOpt(res.blockInfo); + + modernLoginRegister(opt, isRegister, waitFor(function (err, data, _RT) { + if (err) { + waitFor.abort(); + return void cb(err); + } + RT = _RT; + if (!data) { return; } // Go to next block (modern registration) + + // No error and data: success modern login + waitFor.abort(); + cb(void 0, data); + }), res); + }).nThen(function (waitFor) { + console.log("creating request to publish a login block"); + + // Finally, create the login block for the object you just created. + var toPublish = {}; + toPublish[Constants.userHashKey] = res.userHash; + toPublish.edPublic = RT.proxy.edPublic; + + Block.writeLoginBlock({ + pw: Boolean(passwd), + auth: ssoAuth, + blockKeys: blockKeys, + content: toPublish + }, waitFor(function (e, res) { + if (e === 'SSO_NO_SESSION') { return; } // account created, need re-login + if (e) { + console.error(e); + waitFor.abort(); + return void cb(e); + } + if (res && res.bearer) { + LocalStore.setSessionToken(res.bearer); + } + })); + }).nThen(function (waitFor) { + // confirm that the block was actually written before considering registration successful + Util.getBlock(blockUrl, {}, waitFor(function (err /*, block */) { + if (err && err !== 401) { // 401 is fine + console.error(err); + waitFor.abort(); + return void cb(err); + } + + console.log("blockInfo available at:", res.blockHash); + LocalStore.login(undefined, res.blockHash, uname, function () { + cb(void 0, res); + }); + })); + }); + }; + + return Exports; +}); diff --git a/www/common/outer/login-block.js b/www/common/outer/login-block.js index 67eaaa128..ccddfb780 100644 --- a/www/common/outer/login-block.js +++ b/www/common/outer/login-block.js @@ -165,9 +165,7 @@ define([ const { blockKeys, auth } = data; var command = 'MFA_CHECK'; - if (auth && auth.type === 'TOTP') { - command = 'TOTP_CHECK'; - } + if (auth && auth.type) { command = `${auth.type.toUpperCase()}_` + command; } ServerCommand(blockKeys.sign, { command: command, @@ -175,15 +173,14 @@ define([ }, cb); }; Block.writeLoginBlock = function (data, cb) { - const { content, blockKeys, oldBlockKeys, auth } = data; + const { content, blockKeys, oldBlockKeys, auth, pw } = data; var command = 'WRITE_BLOCK'; - if (auth && auth.type === 'TOTP') { - command = 'TOTP_WRITE_BLOCK'; - } + if (auth && auth.type) { command = `${auth.type.toUpperCase()}_` + command; } var block = Block.serialize(JSON.stringify(content), blockKeys); block.auth = auth && auth.data; + block.hasPassword = pw; block.registrationProof = oldBlockKeys && Block.proveAncestor(oldBlockKeys); ServerCommand(blockKeys.sign, { @@ -195,9 +192,7 @@ define([ const { blockKeys, auth } = data; var command = 'REMOVE_BLOCK'; - if (auth && auth.type === 'TOTP') { - command = 'TOTP_REMOVE_BLOCK'; - } + if (auth && auth.type) { command = `${auth.type.toUpperCase()}_` + command; } ServerCommand(blockKeys.sign, { command: command, diff --git a/www/install/main.js b/www/install/main.js index e7c03e3cd..a8352e588 100644 --- a/www/install/main.js +++ b/www/install/main.js @@ -126,7 +126,8 @@ define([ function (yes) { if (!yes) { return; } - Login.loginOrRegisterUI(uname, passwd, true, shouldImport, false, function (data) { + Login.loginOrRegisterUI(uname, passwd, true, shouldImport, + UI.getOTPScreen, false, function (data) { var proxy = data.proxy; if (!proxy || !proxy.edPublic) { UI.alert(Messages.error); return true; } diff --git a/www/login/main.js b/www/login/main.js index edbc38f16..ad3483533 100644 --- a/www/login/main.js +++ b/www/login/main.js @@ -1,5 +1,7 @@ define([ + '/api/config', 'jquery', + '/common/hyperscript.js', '/common/cryptpad-common.js', '/customize/login.js', '/common/common-interface.js', @@ -9,7 +11,7 @@ define([ //'/common/test.js', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', -], function ($, Cryptpad, Login, UI, Realtime, Feedback, LocalStore/*, Test */) { +], function (Config, $, h, Cryptpad, Login, UI, Realtime, Feedback, LocalStore/*, Test */) { if (window.top !== window) { return; } $(function () { var $checkImport = $('#import-recent'); @@ -19,6 +21,27 @@ define([ return; } + if (Config.sso) { + // TODO + // Config.sso.force => no legacy login allowed + // Config.sso.password => cp password required or forbidden + // Config.sso.list => list of configured identity providers + var $sso = $('div.cp-login-sso'); + var list = Config.sso.list.map(function (name) { + var b = h('button.btn.btn-secondary', name); + var $b = $(b).click(function () { + $b.prop('disabled', 'disabled'); + Login.ssoAuth(name, function (err, data) { + if (data.url) { + window.location.href = data.url; + } + }); + }); + return b; + }); + $sso.append(list); + } + /* Log in UI */ // deferred execution to avoid unnecessary asset loading var loginReady = function (cb) { diff --git a/www/register/main.js b/www/register/main.js index 3900fc855..729518819 100644 --- a/www/register/main.js +++ b/www/register/main.js @@ -62,13 +62,11 @@ define([ var $b = $(b).click(function () { console.log('sso register click:', name); $b.prop('disabled', 'disabled'); - Login.ssoRegister(name, function (err, data) { - console.error(err, data); + Login.ssoAuth(name, function (err, data) { if (data.url) { window.location.href = data.url; } }); - // XXX Server command }); return b; }); @@ -152,7 +150,8 @@ define([ function (yes) { if (!yes) { return; } - Login.loginOrRegisterUI(uname, passwd, true, shouldImport, false /*Test.testing*/, function () { + Login.loginOrRegisterUI(uname, passwd, true, shouldImport, + UI.getOTPScreen, false /*Test.testing*/, function () { if (test) { localStorage.clear(); test.pass(); diff --git a/www/ssoauth/index.html b/www/ssoauth/index.html index a7bdb9b14..11e9eb7b7 100644 --- a/www/ssoauth/index.html +++ b/www/ssoauth/index.html @@ -6,7 +6,9 @@ - + + + diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index c556e2814..4272d87fa 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -1,3 +1,142 @@ -define(['/customize/login.js'], function (Login) { - Login.ssoRegisterCb(); +define([ + '/api/config', + 'jquery', + '/common/hyperscript.js', + '/common/common-util.js', + '/common/common-credential.js', + '/common/common-interface.js', + '/common/common-login.js', + '/common/common-constants.js', + '/common/outer/http-command.js', + '/common/outer/local-store.js', + '/common/outer/login-block.js', + '/customize/messages.js', + + '/bower_components/tweetnacl/nacl-fast.min.js', +], function (ApiConfig, $, h, Util, Cred, UI, Login, Constants, + ServerCommand, LocalStore, Block, Messages) { + if (window.top !== window) { return; } + + let Nacl = window.nacl; + + let ssoAuthCb = function (cb) { + var b64Keys = Util.tryParse(localStorage.CP_sso_auth); + if (!b64Keys) { + UI.errorLoadingScreen("MISSING_SIGNATURE_KEYS"); + return; + } + var keys = { + secretKey: Nacl.util.decodeBase64(b64Keys.s), + publicKey: Nacl.util.decodeBase64(b64Keys.p) + }; + ServerCommand(keys, { + command: 'SSO_AUTH_CB', + url: window.location.href + }, function (err, data) { + delete localStorage.CP_sso_auth; + document.cookie = 'ssotoken=; Max-Age=-99999999;'; + cb(err, data); + }); + }; + let ssoLoginRegister = function (seed, pw, jwt, name, isRegister) { + Login.loginOrRegister({ + uname: seed, + passwd: pw, + isRegister: isRegister, + onOTP: UI.getOTPScreen, + ssoAuth: { + name: name, + type: 'SSO', + data: jwt + } + }, function (err) { + if (err) { + console.error(err); + return void UI.warn(Messages.error); + } + window.location.href = '/drive/'; + }); + }; + + $(function () { + if (!ApiConfig.sso) { return void UI.errorLoadingScreen(Messages.error); } + + UI.addLoadingScreen(); + ssoAuthCb(function (err, data) { + if (err || !data || !data.jwt) { + console.error(err || 'NO_DATA'); + return void UI.warn(Messages.error); + } + let jwt = data.jwt; + let seed = data.seed; + let name = data.name; + $('body').addClass(data.register ? 'cp-register' : 'cp-login'); + + UI.removeLoadingScreen(); + + + // Login with a password OR register and password allowed + let $button = $('button#cp-ssoauth-button'); + let $pw = $('#password'); + let $pw2 = $('#passwordconfirm'); + let next = (pw) => { + // TODO login err ==> re-enable button + + setTimeout(() => { // First setTimeout to remove mobile devices' keyboard + UI.addLoadingScreen({ + loadingText: Messages.login_hashing, + hideTips: true, + }); + setTimeout(function () { // Second timeout for the loading screen befofe Scrypt + ssoLoginRegister(seed, pw, jwt, name, data.register); + }, 100); + }, 100); + + }; + + // Existing account, no CP password, continue + if (!data.register && !data.password) { + return void next(''); + } + + // Registration and CP password disabled, continue + if (data.register && !ApiConfig.sso.password) { + return void next(''); + } + + $('div.cp-ssoauth-pw').show(); + + $button.click(() => { + let pw = $pw.val(); + if (data.register && pw !== $pw2.val()) { + return void UI.warn(Messages.register_passwordsDontMatch); + } + if (data.register && pw && !Cred.isLongEnoughPassword(pw)) { + return void UI.warn(Messages.register_passwordTooShort); + } + $button.prop('disabled', 'disabled'); + + if (data.register) { + var span = h('span', [ + h('h2', [ + h('i.fa.fa-warning'), + ' ', + Messages.register_warning, + ]), + Messages.register_warning_note + ]); + UI.confirm(span, function (yes) { + if (!yes) { + $button.removeAttr('disabled'); + return; + } + next(pw); + }); + return; + } + + next(pw); + }); + }); + }); }); From d6bf625733d1ea43d650167a5b77f3d6625c4962 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 29 Jun 2023 12:32:45 +0200 Subject: [PATCH 003/283] SSO: prototype improvements --- lib/challenge-commands/sso.js | 30 ++++++++++++++----------- lib/http-worker.js | 42 +++++++++-------------------------- lib/plugins/sso/oidc.js | 27 ++++++---------------- lib/sso-utils.js | 23 +++++++++---------- lib/storage/sessions.js | 8 ------- lib/storage/sso.js | 23 ++++++++++--------- 6 files changed, 57 insertions(+), 96 deletions(-) diff --git a/lib/challenge-commands/sso.js b/lib/challenge-commands/sso.js index 385fa6d70..51818d23b 100644 --- a/lib/challenge-commands/sso.js +++ b/lib/challenge-commands/sso.js @@ -76,12 +76,13 @@ authCb.complete = function (Env, body, cb, req) { const cfg = getProviderConfig(Env, data.provider); const idp = TYPES[data.type]; const register = data.register; + const provider = data.provider; idp.authCb(Env, cfg, ssotoken, url, (err, obj) => { if (err) { return void cb(err); } const {id, idpData, name} = obj; let next = (user, isRegister) => { - SSOUtils.createJWT(Env, id, data.provider, idpData, (err, jwt) => { + SSOUtils.createJWT(Env, id, provider, idpData, (err, jwt) => { if (err) { return void cb(err); } cb(void 0, { jwt: jwt, @@ -94,19 +95,22 @@ authCb.complete = function (Env, body, cb, req) { }; if (register) { - SSOUtils.writeUser(Env, id, (err, userData) => { + SSOUtils.writeUser(Env, provider, id, (err, userData) => { if (err && err.code === 'EEXIST') { - return void SSOUtils.readUser(Env, id, (err, userData) => { + return void SSOUtils.readUser(Env, provider, id, (err, userData) => { if (err) { return void cb(err); } - next(userData, false); + next(userData, !userData.complete); }); } if (err) { return void cb(err); } next(userData, true); }); } else { - SSOUtils.readUser(Env, id, (err, userData) => { + SSOUtils.readUser(Env, provider, id, (err, userData) => { if (err) { return void cb(err); } + if (!userData || !userData.complete) { + return void cb('NO_USER'); + } next(userData, false); }); } @@ -148,8 +152,8 @@ register.complete = function (Env, body, cb) { payload = _payload; })); }).nThen((w) => { - const { sub } = payload; - SSOUtils.readUser(Env, sub, w((err, user) => { + const { sub, provider } = payload; + SSOUtils.readUser(Env, provider, sub, w((err, user) => { if (err) { w.abort(); console.log(err, sub); @@ -170,10 +174,10 @@ register.complete = function (Env, body, cb) { if (err) { w.abort(); } })); }).nThen((w) => { - if (!pw) { return; } - const { sub } = payload; - ssoUser.password = true; - SSOUtils.updateUser(Env, sub, ssoUser, w()); + const { sub, provider } = payload; + ssoUser.password = Boolean(pw); + ssoUser.complete = true; + SSOUtils.updateUser(Env, provider, sub, ssoUser, w()); }).nThen(() => { const { data, provider } = payload; SSOUtils.makeSession(Env, publicKey, provider, data, cb); @@ -206,8 +210,8 @@ login.complete = function (Env, body, cb) { payload = _payload; })); }).nThen((w) => { - const { sub } = payload; - SSOUtils.readUser(Env, sub, w((err) => { + const { sub, provider } = payload; + SSOUtils.readUser(Env, provider, sub, w((err) => { if (err) { w.abort(); console.log(err, sub); diff --git a/lib/http-worker.js b/lib/http-worker.js index 50fba51c0..97cff40d6 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -377,7 +377,7 @@ app.use('/block/', function (req, res, next) { if (mfa_params && !content.mfa) { return void no(); } if (sso_params && !content.sso) { return void no(); } - if (content.mfa && content.mfa.exp && ((+new Date()) > content.mfa.exp)) { + if (content.mfa && content.mfa.exp && (+new Date()) > content.mfa.exp) { Log.error("OTP_SESSION_EXPIRED", content.mfa); // XXX Only delete the mfa part Sessions.delete(Env, name, token, function (err) { @@ -391,41 +391,19 @@ app.use('/block/', function (req, res, next) { } - if (content.sso) { - SSOUtils.checkSession(Env, content.sso, (err, state, newState) => { - if (err || !state) { - // XXX Only delete the mfa part - Sessions.delete(Env, name, token, function (err) { - if (err) { - Log.error('SSO_SESSION_DELETE_EXPIRED_ERROR', err); - return; - } - Log.info('SSO_SESSION_DELETE_EXPIRED', err); - }); - return void no(); + if (content.sso && content.sso.exp && (+new Date()) > content.sso.exp) { + Log.error("SSO_SESSION_EXPIRED", content.sso); + Sessions.delete(Env, name, token, function (err) { + if (err) { + Log.error('SSO_SESSION_DELETE_EXPIRED_ERROR', err); + return; } - if (newState) { - content.sso = newState; - // XXX We should produce a new session ID here and send it back to the user - Sessions.update(Env, name, token, JSON.stringify(content), (err) => { - if (err) { - Log.error('SSO_SESSION_UPDATE_ERROR', err); - return; - } - Log.info('SSO_SESSION_UPDATED', err); - }); - } - next(); + Log.info('SSO_SESSION_DELETE_EXPIRED', err); }); - return; + return void no(); } - // we could also check whether the content of the file matches the token, - // but clients don't have any influence over the reference and can only - // request to create tokens that are scoped to a public key they control. - // I don' think there's any practical benefit to such a check. - - // So, interpret the existence of a file in that location as the continued + // Interpret the existence of a file in that location as the continued // validity of the session. Fall through and let the built-in webserver // handle the 404 or serving the file. next(); diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js index caa904a85..8d2d72f3f 100644 --- a/lib/plugins/sso/oidc.js +++ b/lib/plugins/sso/oidc.js @@ -4,7 +4,6 @@ const TYPE = 'oidc'; const getClient = (cfg, cb) => { OID.Issuer.discover(cfg.url).then((issuer) => { // XXX Only once for all users? - console.log('Discovered issuer %s %O', issuer.issuer); const client = new issuer.Client({ client_id: cfg.client_id, client_secret: cfg.client_secret, @@ -55,30 +54,18 @@ module.exports = { expires_at: j.expires_at, access_token: j.access_token, refresh_token: j.refresh_token, - id_token: j.id_token + //id_token: j.id_token // XXX no need to store id_token? } }); }); }); }, - checkSession: (Env, cfg, data, cb) => { - const { refresh_token } = data; - + /* + getData: (Env, cfg, data, cb) => { + // data = { refresh_token, access_token, expires_at } let t = new OID.TokenSet(data); - if (!t.expired()) { return void cb(void 0, true); } - getClient(cfg, (err, client) => { - client.refresh(t.refresh_token).then((j) => { - const newData = { - refresh_token: refresh_token, - id_token: j.id_token, - access_token: j.access_token, - expires_at: j.expires_at - }; - cb(void 0, true, newData); - }, () => { - // Error: can't renew token - cb(void 0, false); - }); - }); + // TODO get userinfo using access_token + // use refresh_token if access expired } + */ }; diff --git a/lib/sso-utils.js b/lib/sso-utils.js index 3e11047e2..9a6a069fb 100644 --- a/lib/sso-utils.js +++ b/lib/sso-utils.js @@ -6,6 +6,8 @@ const Util = require("./common-util"); const SSOUtils = module.exports; +const SESSION_EXPIRATIION = 12 * 3600 * 1000; // XXX Hours? Days? Weeks? Configurable? + // XXX const SAML = require('node-saml'); // https://www.npmjs.com/package/node-saml const TYPES = SSOUtils.TYPES = { oidc: require('./plugins/sso/oidc') @@ -29,12 +31,6 @@ SSOUtils.isValidConfig = (cfg) => { return idp.checkConfig(cfg); }; -SSOUtils.checkSession = (Env, sessionData, cb) => { - const cfg = getProviderConfig(Env, sessionData.provider); - const idp = TYPES[cfg.type.toLowerCase()]; - idp.checkSession(Env, cfg, sessionData.data, cb); -}; - SSOUtils.deleteRequest = (Env, id) => { SSO.request.delete(Env, id, (err) => { if (!err) { return; } @@ -60,9 +56,9 @@ SSOUtils.writeRequest = (Env, data, cb) => { }; -SSOUtils.writeUser = (Env, id, cb) => { +SSOUtils.writeUser = (Env, provider, id, cb) => { const seed = Nacl.util.encodeBase64(Nacl.randomBytes(24)); - SSO.user.write(Env, id, JSON.stringify({ + SSO.user.write(Env, provider, id, JSON.stringify({ seed: seed, password: false }), (err) => { @@ -70,15 +66,15 @@ SSOUtils.writeUser = (Env, id, cb) => { cb(void 0, { seed }); }); }; -SSOUtils.readUser = (Env, id, cb) => { - SSO.user.read(Env, id, (err, user) => { +SSOUtils.readUser = (Env, provider, id, cb) => { + SSO.user.read(Env, provider, id, (err, user) => { if (err) { return void cb(err); } cb(void 0, Util.tryParse(user)); }); }; -SSOUtils.updateUser = (Env, id, data, cb) => { - SSO.user.delete(Env, id, () => { - SSO.user.write(Env, id, JSON.stringify(data), (err) => { +SSOUtils.updateUser = (Env, provider, id, data, cb) => { + SSO.user.delete(Env, provider, id, () => { + SSO.user.write(Env, provider, id, JSON.stringify(data), (err) => { if (err) { return void cb(err); } cb(); }); @@ -146,6 +142,7 @@ SSOUtils.makeSession = (Env, publicKey, provider, ssoData, cb) => { // XXX If we already have an OTP session, recover it Sessions.write(Env, publicKey, sessionId, JSON.stringify({ sso: { + exp: +new Date() + SESSION_EXPIRATIION, provider: provider, data: ssoData } diff --git a/lib/storage/sessions.js b/lib/storage/sessions.js index 30283dc47..f31151ec8 100644 --- a/lib/storage/sessions.js +++ b/lib/storage/sessions.js @@ -42,14 +42,6 @@ Sessions.delete = function (Env, id, ref, cb) { Basic.delete(Env, path, cb); }; -Sessions.update = function (Env, id, ref, data, cb) { - var path = pathFromId(Env, id, ref); - Basic.delete(Env, path, (err) => { - if (err) { return void cb(err); } - Basic.write(Env, path, data, cb); - }); -}; - Sessions.deleteUser = function (Env, id, cb) { if (!id || typeof(id) !== 'string') { return; } id = Util.escapeKeyCharacters(id); diff --git a/lib/storage/sso.js b/lib/storage/sso.js index b28203fd5..3e41bb5d8 100644 --- a/lib/storage/sso.js +++ b/lib/storage/sso.js @@ -21,13 +21,17 @@ var pathFromId = function (Env, id, subPath) { var reqPathFromId = function (Env, id) { return pathFromId(Env, id, 'sso_request'); }; -var userPathFromId = function (Env, id) { - return pathFromId(Env, id, 'sso_user'); -}; var blockPathFromId = function (Env, id) { return pathFromId(Env, id, 'sso_block'); }; +var userPathFromId = function (Env, id, provider) { + if (!id || typeof(id) !== 'string') { return; } + if (!provider || typeof(provider) !== 'string') { return; } + id = Util.escapeKeyCharacters(id); + return Path.join(Env.paths.base, 'sso_user', provider, id.slice(0, 2), `${id}.json`); +}; + const Req = SSO.request = {}; Req.read = function (Env, id, cb) { @@ -36,7 +40,6 @@ Req.read = function (Env, id, cb) { }; Req.write = function (Env, id, data, cb) { var path = reqPathFromId(Env, id); - console.log(path); Basic.write(Env, path, data, cb); }; Req.delete = function (Env, id, cb) { @@ -47,16 +50,16 @@ Req.delete = function (Env, id, cb) { const User = SSO.user = {}; -User.read = function (Env, id, cb) { - var path = userPathFromId(Env, id); +User.read = function (Env, provider, id, cb) { + var path = userPathFromId(Env, id, provider); Basic.read(Env, path, cb); }; -User.write = function (Env, id, data, cb) { - var path = userPathFromId(Env, id); +User.write = function (Env, provider, id, data, cb) { + var path = userPathFromId(Env, id, provider); Basic.write(Env, path, data, cb); }; -User.delete = function (Env, id, cb) { - var path = userPathFromId(Env, id); +User.delete = function (Env, provider, id, cb) { + var path = userPathFromId(Env, id, provider); Basic.delete(Env, path, cb); }; From d1d26571cfdb4ac658f61c47b5bbccf573d832c5 Mon Sep 17 00:00:00 2001 From: yflory Date: Sun, 2 Jul 2023 12:04:21 +0300 Subject: [PATCH 004/283] SSO: fix issue with missing config --- lib/http-worker.js | 2 +- www/common/common-login.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/http-worker.js b/lib/http-worker.js index 97cff40d6..50bb30532 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -465,7 +465,7 @@ var makeRouteCache = function (template, cacheName) { }; const ssoList = Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && - Env.sso.list.map(function (obj) { return obj.name; }); + Env.sso.list.map(function (obj) { return obj.name; }) || []; const ssoCfg = ssoList.length ? { force: (Env.sso && Env.sso.enforced && 1) || 0, password: (Env.sso && Env.sso.cpPassword && 1) || 0, diff --git a/www/common/common-login.js b/www/common/common-login.js index 007c0bbfc..e2287de46 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -297,7 +297,7 @@ define([ register: isRegister, uname: uname }; - if (ssoAuth && ssoAuth.name) { res.uname = ssoAuth.name; } + if (ssoAuth && ssoAuth.name) { uname = res.uname = ssoAuth.name; } var RT, blockKeys, blockUrl; From 82f2d2226f8b0a5ecf12ad6052c80abd9144771c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:27:24 +0200 Subject: [PATCH 005/283] remove .flowconfig file, unused by anyone since 2017 --- .flowconfig | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 .flowconfig diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 4d505b265..000000000 --- a/.flowconfig +++ /dev/null @@ -1,8 +0,0 @@ -[ignore] -.*/components/.* -.*/node_modules/lesshint/* -[include] - -[libs] - -[options] From 337e28c96399685e205481441b48cf14b8015188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:28:29 +0200 Subject: [PATCH 006/283] remove ancient & tiny screen capture and outdated logo --- and_so_it_begins.png | Bin 44825 -> 0 bytes cryptofist.png | Bin 202130 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 and_so_it_begins.png delete mode 100644 cryptofist.png diff --git a/and_so_it_begins.png b/and_so_it_begins.png deleted file mode 100644 index 64f59af175c813c1cfaa4d5ffb294a7222da4f95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44825 zcmY&9l~FAT_-{*n#Xo0hUm71 zgjfPVbi*!H)$~$gKtNoym3-qqOrCiff`AaBn7=f)D49I0Z_Cp9EcyaLl4$wz_-j(D z=pGV6$QraRP219@rw<7Mf7S%t<;u)(J;j9Z@4jf8f8=k2fpD*1cLbB0b(z|7Oe>X0 zAvHK|`C@;~gsi)00YV19c+fTvtSS3E@a?k8EY(BJ7jLv_n``|_SGMVAj_RDt8{s;& z=a|~oC}gsJ?s`#ew-6VQrjK7x`N}BV$Fa$=1_7K_geV)N|J3f?}LsP`+-h3dTjZEScpm$G!CVN~fa|N_UpX zb6)VXZBA=aCyh!P?>dWAb*`nxG7taS8S)G8KT4dY_I4RutpXU`yuS+l|GfwmhU{D? zA+TB*B6p3V=5XjCyUC!S(EcEj*{GozSIH%WL?&vgl_XXv(^k-xRCH58M+hk!6a>;? zD;YJ7f~@|Get6dS$laRe@{05M+}3>LcwH>NRy$2~9CqHC3N~1#?qb)wZ3(J!@$!1D zmWhgq`OuTHuqYoI`BL{(Ge15&pkc*)WE?3=5RSTKeVM|Dd!8CjOG}%bodp7c-ULsh zJ~Nw}f?Ql&Y;1RJh&0E&5M!v}{7SBMJa)?vlkXas5)u-eoSc^L>+6Jq&f;i8H#c2n0~YXkFrsPh z!^eJ5F9AKj{KLY+I@;T3W@ZeHjQIKZEUm0KIXIRsovW&<_V@OVrm10h3yAY>jmF;J z->l!tz0sLfpLBY0}!7ql3r0VMG&d$zFYkx*$y+fOeBRM%aTU*<=j5QWr zU0nx9Vd0+Z>ss?OZY}?+LqNW1_G=uKCc&r*Jw1Ip<}m&Rp)o@;92^|mfUtpLm2nKM zGf6wX>J=_@fZ+2oGTZ+3`uh4k6P0icKNai>`PtdoFi>RA;qmctetsU_4&`GAixRg% z*!g$ir0H-%ym1)G^!UVtTINBAkaq>249S5YaXD)rB_*Yci%XZJxwZA4wT*>E0TYQ8 zmnPw(l%e5HJ;ZQPAS*Q$JssUB1&OMz(`+S!3Xpq67hTia25;{^;Ief?Rip|i6}HGVVZH_NBj zS1W=mJSkKoM~PVu5<3fmzi5s#A`7r3(SQH`JvuVq;~WCpMsF|F{O&hE1f$E`GGfcq zlRK`xc=z)1GLxjVbRf5ofmcs`zfo=u3kOGPW@bhE&%1{QM+J>cX9NF?C+H{Y>K}}Z z&4+TIae|aIa;;3=$VLvqVPSpG&(CUVYQ@!g6myG<^mcUFPpa_WAEiV^q4}7Yx?}wl zs>rywaB(18QZe)9i^t=0b0^QC#hc6x{qY8O1W0S{z|RVVF76V6pw35mPof;yhn`dN z>+We573Aa+w6x$|OXBl#7`oMOa1>c5-wP3N{0q6YBJH}sM&It6&~08_Q!}=z{QXQ> zELS-I)#6AW()Q;H>{{F%6P3qU53?53O={EXv%nPN{r!E_@88=qkp~l`n?~g?oz2Fg zX*?&^A>W@7V7>nai~t?g6kUZ~g-RFq7nMN3?X6SO zR1%)#^W5MBJMOR0TCQ@qUe&6xu`wwncDlcJ*{`v$6l`o*DDdz!3=F{uRlQSFs5ru= zrU&(SP+z{VXX5%jD>}Qm?T*aMD5s7TMir$nGJe&m4}Lo{hHM%K4#JUZv+u4ArF9FB zXfVptr=OBaAq5x^pZD+W6_ZVkk88H8-*SlSc{dQZztFI>ja?D*xN{z%jdwRL_N6WjL5 z{n**^nfDI5pEAnkeSAC2{rtMM38S_K+i&AMET*!H zO9_wXs~Rh9uIH8y!g;UhXX+Lzfoge?dfOT`dfSQOw--ThsM&*g0zTTAk`@{7uqthn zhlErrkoVfuwT4z?6w-?5(tU_cWP4Dh#`D2Q6Puof0GIHIvgF}GYb6vSK3wNom`Zb# zLP4XqA(XXNmp??a^*1bCexD!VOk8kT*jLT#y?*OAYfhy|Mmb}{EH2FFRMsx115w|K z)c3jrzA%mL4OBJv&as+J{#9eEghv*~>N;U1S4j5lW_i9tSnGH_TV_r0$xv`S*!wHv zAivgeTIZ#4NTJ|bOgd#oVmctpy=0ol>vpl#bfmtooj8TW7fpSRlejX0AJ%S*1Zx0- z;2*GMHVQWi$md*zF^>_M>dWQ#lFr)HKysKaBTCAx7-G2N`wPU}9pWNc3E6-fuw}nw z{P82Ifu_#sa8kF~zQ;G{XPU#vJ`V+I4t1Q#k0P<>(8Zg_Pw3kOM$?gv4zI;G!2eoA zzZ#QbGfbAv2xjZv%%I6JY~-+Vk#EoEM?Gp9E@iNsz6_1wvV;@B8Q~`4S{w z6DqL)7Z-ZhXtqo{k|udi7ThyLdVpDLcHMVg*JwAg?^wk4pM*#ST%H*@)LxGlHZyXo zvy^rk>gqamNA|Gen2f(t{)|;PK@CT<9oWGMhoM#RmD_N8Jun>Bc%<AR+W8KcPi z=8nsGwvgF{IFwfKg1lAkd1y6eH;gu;@+Of5xH!1p^c8A&eG%o2Q@c;*=-50961Y$I z?w+A~XXlStu8P=1j6)RjT4kn{LzFM_NRz7Hp_b2%H!JEA@sPsJ<@1>NFq_GqSZeKT z9h=H%{MEqFI)A8Yso2x+e_2>1L_VYAYT*Puqb5UWc&l}$(!dS{XFf)HxzPbE2pGwC z_6zAXzn|Cy8_wlcWT@kt9+BLSAjji{1ab-Iu^Qf}SQky`O2SISpnrxP-Ywx60p!)O ziIi*p+%!!sezed*VW`B2?XsH8A?EYBIXTp4>J68hT?!Jf+CPD<19-)jFa@D+RdcmF zA$#L(CO?GY`R#u@B~oWu;0~Ax5YG;f#*@}uuBdxc8A^R5dFyQ%@L7Q3H8a5mgwj0} zM|@1>HI*Q4EogW$lfEWSb?${f8evkaz>eifw09~E^!=V|pY)%&z(&Ym<62TmEu7E9 zj6#o54>-?%glr4>tYyyp^*LR&Sgl*su37Ul3`NQE+OA?=aoB>3&2cU}?{*brmqFj7 zKC(4iPlu$*@EahdoAyPJTDNg7WOzT|ABJAJ@YVa*)#yaH|5lhDAGM0~DoGT1y)NGl zoz{}Ra&FDa$IH!K1BVr+uQ>%6)*T+Vq3Z(*^_e09YK<;wdKdp3C8TE~vkuSr63YE^ zOzJ|cn_7FotkKt%)sW|#@%n*aMl!}8ZC(AlQFTt}Kbx#&)gQ;LRLUP&{fdI!=6OG}J66(L-L1bE8*E zk#XG+d2kXkjfpsT9^^A!%Vx>a;vYWpFR|`0LNJP&j;_n+mFfb0Bm(rykJIjaFG@}g#9+n;l#|1$+` zMYto0#oC@Q8wGE>!g|}N3>qu_QtK)t{;CNKS`U29Ujm#Pgm<4F{VT$B_I&c7XDKOUA)MnF@vjhR2i~tpSiOFeb&pv4*9V&oSf>HLF$3tdVyTor z@V(81Yxq7#-T${h2)?Ot(WOArs~L5|V%|UBnzcoF;X41;`%N%(pD1~ze)m0!@IT%d zP%#6dINIjVb}#0PdIf!ChhQfJCIPVGTRcp-O`-=8ty=Gylg|5xYu-3Asm}lsuq_W9 zT)tvEn3TBRu~8|yZ6ztJ7$D*ytur&+I`u@S#u#A^WKd?L@r}pDr*$lQ>^a}fWMuJB}d-*-rk5E*GjMom(LXap)pwc5P zXdMl0$u{${a@{ERb!HmO6P%<<+;77|?ouwhBI2d0VHTS=L^RhwsjUVHUn;SH_pbo> zBK9$8PZM8Xl6_lXNDc}1js`pakp~IgCtoki0q)XFncFmM824!Qf#LclO@)$0BS$M zHSUFGUK-+<@#g1N%Du(%dRd@Hm1s*0x@JvL*$c#2BzBh>C(}lD@tD`z%p`&RL->Dh z?sg8KY0UG>)$oxn-mCN=$KYSyYL~F5!dK9W2Z>^p~mq~HnEzF zQy!80K2dh=b?t^-n=+O~D#pa*spB5=8GBUWJy0~o9ylr2#;(RTOfq;2{}P)2GYB^F)8jJEDu)?*;V=ib($ zexLjFy{BQpcOpv_K1o<)iUZ2ba|ifzH>K}51)@tj!I7RX-jp#5)h+=nL)w@U z7C-rqmeDU<-%&LVzK6&&m+-iQ76zb8N1_h2a$Pq;b5mjtxOtCLd>QG5G=n}eIo{!8 z`|Tc#JB}@DkAQn8rE&DlYc#QIk?7Y{9*@C&#|_r`m)Q#o1je-2&XhC9O22*eAiLcR z+0a7G$uwnMo5WY1CFAdGeF8_x=>SxTCXiX6^4-;L&*4zIRDvqjW7VABemO}c!htGv z){n>{G_eBuxs=53L-=YKfI%&jJj%g?3M7jAVC-8g{R-JVSk){C&?CV8_tiizorQl2)|c6~K6^6HhZMfatdLdQ0U%qTsv!CnzX4KuyZP8h7mV*?JZwh@x zJehbnpCw62Nnx|Fz(ZLyb?wR|Yoc`R5(ljMi=9MXlXFo0y{8Y+Ke!OT0)|9I-ZWhb+k%;D?j~RC{CDQkyeqt3T}8?eSfn zb}xCg0W~o>qmMSUCzjhZ`BZXnrDy2!z2R`ZB0lz@1Wng4!bj{6=-QaFzU z_`0OPiWh1~Zdc{?cZz18NJGVF6{>o?6hrTm{3tlPjh3UY+XASgx=5id+eN)zc6Dv$ zIh@rF>AB3S6-mS~0s!lmxZk%w*W-Gw6U(clz7E9@l(8M=`3YnO2SZb*ct5VY*|qGa zV#;%EKX!e-)0SmB-cE2TWOJc2uK9KEHm%xX=4Jc79CIv(+hR=rG)d>Q)9XST9v=Q% z^QB70&V|Nn8t^Le%g+32btBP0!Tss1ek#5erVnXSUre>Xa|K1X|95#M$wE4%bV>ng zFHl(T#3{jt9`OJmBJN_-$cRApYMqdrEb5NW?PzRhXsDyJw$&4a5FSSC>kiJY2$=aB z@ewI#Yp+~w_tkn&urJzED**{ujN$LU3;MRtG_Tus?ret<$F3Y8{b;uzXC7K}7$S6A zcUe3KZTj|o<<#-HpD)Yxv;+tD&af@QS#h;63ZI|II`%y<9LsZLn&rq@oOTCtQRl0m zI6~f3)A+>1o44DkTa<;-6#D0(=m(d4m*c9*&XIquB-$w`hSF>aF9DXr z>Pt2dQ2EK;$Z*8oR{<2R11MbCn^tk<@Ru&iW?7cb&dz9DzeL}am6ZPRUbfF}Y!FqP z5!kgWDX9tPGs`5moo&CeICY~+e!oA0GqEXOb^JzA%0NT*{0+JteUI2UozZb><4h&8 zQR`wH+dG#Yyt`JkI4mIWf{11To$zX)x<-BJ1Hx)sq-{)N-+! z4|BZ|lagK^FKZt9T7C2y7(3>dIl1uxddkP2ugue;C&adb8xRNvqVDM;&Sv&2TMBWi*hDg zYYr(;aPQUGUvvp4CJ0sUejvD$4+{=o>0oiPG1?dyoaSL!QGcD#sja7fFb8Nec|Qe` zb(V$YgUDh)m69@n!$iQpldwwbZks;ECN<$)@?)W(2d=@j7AFK6S#$VU6uEWJ(<(&< z6~+?MNfxc|9M+o7um#HMFuym(Gg#*zU_bi*{KISCOO(-J{5H!D`(d?E$$j21`{e$- zpT^r_wJoB@n--Uj%}61)mY}I1^H*PPr?XX8Zs!{#$r&7Sus*+b+P>mQCze}ruElge zyj(G(VRiN||6u#X5-l;YRA_&~mN`5q9pyw&Rl*)BS+Bg;(n>LkK;93sEGA43k@<`= zZo__f916|CUsZu&WG`xe)YqM7<)S~Q>v2R@>fFoo*DT^nA?!MI*J;gHS!~RA0s~Vg zQ?t+dldUm|Q;jJHTQF6``JWeh*&a9jqN>w+BUk#I{!L3=cII-k-M-T);kM7uAylNA znK8w}(rO`b7FsTIu`>f+ml;63Rvv03?`OSQT17J$>lO-(pAS`9T6h7*51_sN$-xjU z+6yi>9UVjQhfE$eKnUap-5K{ct18J|!1B`!<+%$85Uz5C11+?-^XbkK(PK3pPe)Jh z#tU2N&#sP?lND(6_lq6vM2_1ALQ)SPy38HT@r{FPya6 zIaW?c2SzAOdn1A6J~}eeG6eCNtDhdRoRVpQkS^>RfJT~Y5Wv*`xE&A!r1%qZiA(Zt z8+WeY_iuy;jI2EG8-ytL2eG5SYv}B??Vj)Vi?hGA3d1@yQ~kR|!RaM$uH1-5oxp$F zG96s#Wet@L4efIbO0G*q4s!k=x|oJ8!(-Vvvxm}4N!zi9V&lVCUg^~0ff(Pi>>>5r z<+&$Fhgps%UQhZf@p!*@gO*`_3pt;EPPDmQ`nm*)-mD`zE$y{MMGx=M&3lJUpk2bt zwAmeg){H>A^aG;!?2cuSmj?B5Go%HQ*2C)gyY(G}X`M-%q%Ru}qmhM8nBZl`Ub9r5 z$CnTd`N+rd)sxGsL$fkm+e_M`|1?BD173W_aQd~NaOB>G$>WSkWO+laNdR~OJpCye zdLz->5!AW%wvoP)YT)ujO6WYQkg@1o?F3imx=`1ZR(Fk(=HtdLj5h2Asb!COE=fZ4p*d4t3BXL^yoo+d; zbtjTOzBZ5n845!;5Dlw@RS^UY;eoagB8Ii$_vu3cJO8aw0?D**8XLhqid0^dW8dwn zIFTpU^Mp3Hv_U*`V(dp3gJ&m7teNd-c#LaE0|OBq4QREmjmOC!;rjE+z<||qa{g>CBIHpt?pGLP!;_UcH1LZ!lBhTszu!|E> zqcaC5?Ya+ZbMx z?K)zkP;l@h<52TO>*-HuU^1w2lj2Ac;unmt<0##5@QbL)G zUb?lGHo>W`s>-0<5MC--HVH0Yc-p4Muw`O;WiViCr}}`sLdG>YIXN|*a#Y=mt#Z=7 zR=#;m2zU>gDjg{6(py<+@aUvA@wHXC_bSrC8^fot`)Ou){2@iw^Ez+A_ZA<+IZiPtes-;&uh_1J7y{YPJLAm_#~p?pE% zx){KixF?%J0VjnKLd-8fniAn`Y3bcJ)vLhZV*lQgm(U-bI0+zsgpSBd_~oNWoxx&MLIjyG(SLH(0Bhk6n~sN7bwZgU zirU#UV@T9E>6i0SK^Vr116B6WvFMRL?0`I4f5>#4M8|67E_jIFL|0`j04bLjoqJA=-V$|8>}nzHKGaKEj}WG&i(sqjCG}+aCwdcR; zH6tecQM(0j?QoVNE^?T){3%7nEc-XSUiv3GTfeknwRvF@OTLjb1%8;adTqK3GdzHi zF_*&zzZm8xgHAJ(WfroCTIMzBWbvfGZ!C+lm9;?a(lDObq;NMT!>O+4aY=UW79De8 z9^?&J(9{I|A?<}i-H4k|KixfqSE*2egiK_el;Z`EpHFe0nwpxDfrCRxHkAax)RNyv zRVXIqml%RVhlL4oruhiBofQ4#;4G7G3?znmKJhxk2D!46lt@#e|IcE3Sl8)zoUgx7 ziYd~@@ln#qmqQHkg4q!MWl{bLs0EHJN@c=L0O9VqT6s(}Itm(oj3FRhgxA!M^mQlr zC@v*roAM_~>gD}P#wpggXA9dC^Ii>WQN%p&4gV&gu<=z;K zx#g2`a>9Ry`9ak(v&nd1Ia2nycYK*yw?J>=RnSi${2^R;R%$&F8T}NYKZk4aISIH; z(m`O<7(8Sb(4QZ|+)cuXQ$AQ%=R zD6FWiwlz1;N5$;IE&8`+a!p}rpB!sGY*kg9LoO)z*?v1o4pEDAKP32pu1*p=_V2LV z=Ho=8%aAh3gS0Gw8&c46j^>4%T1C?!Sgs%VY(FeG4DL_nMJzt1uQDJSNkZTu5%P?NR~^xp zgF(THKTZ5q@a~v;i}us+@0>k3*H!L#RQth7Vv$J}0HP(&zJ5Yz^bQXRGCr`swi6uo z0s|mct|nN?cXh83`UWR`eDo~e_Ut-3HxU2l1h2`+;x03N_HHWe?Qf#^1hiD2l2Hgp z{nft-Sl$_M*o1YbpBk24`SMfBF;qH{Jl>ko^YT)YS_YTHus2ZcR3HD?@%`S3fTI@( z33^1k10Vd=wZt;^iG@W0ahlSFfL#?+jjrbjyC*56!Ctnb`Y8dghqL8GYQ&L#c$M#7 zeJrrtSk#`>%JM|4BEd)*eu_4+-ROzgOT~uS=)c60F>Tuqdf}5NLqpvOL)Zh!6+}y+ zdiA`6?IeE+z9V;|p)X@GQt-LpqcIvse(!_{y}CiHkR!S$N?}M#(BhbPca4W6Zu!=M zmG2T_>FDXZ4_6vpXn<9y5Z&5Aj&LFE_;AScrBV`!``FZislZeOoPk$`7Q!zn(P?%5 zop>is@v88Bn-qYNC^Ygr?27Wz`dUbgMJrhTmtwt~sje}SNr2wegfjowpKNme>we7N z*b1AKX5V7OClf?U7E9KQgq4J+iAOIk#y070fBl5bjobV-{R&LSd->ww4X~+GT}^z{ zQSOcY>Z08AO`71_a_YU4Z?D-6F3Pd_ErCT|S4(4zD~fiOk0Z9i^YC*Kn=QD|)(1so z*H@ohLSu3a<=ZC<9Fx~~$`?g_9-0xuw@V>V`k4fcK0gnjOh~xu*UZ}FF*Key%B6+M zqOm@Z$(5uma*^j0`m)6La#V!My@wWx>NsCOQQ?@c^+8DzphnXZA?HhBIGN2oUY)MS z)*GR`0svQP`E{3wT_Y?`~9-~hl0zourqjZ zoe0l@$sj1UDiY%nmBSSS;DgqLH91uuzW{zTY1Xb)`97fklf zA%Au8xRfPkHfF+QF?)K(h6VW?~J`CqVL%h|(%6d$BG?2KXYoW}eYOqTbs zCixlY$9*f05mWz74FgknHRo?8Ckn z?45!&#`wQ%PYD)igEdzoJ~v%_mFj%+-vsV5>gR^GTJHa)cILm+s4JUGr3q12C#zT`&aP9aD5+nP7CNo7c4U4NC#BFmk@4eTrArXLrH)DM zEljPbpu?z5X(y5(L;O8Ds18LoxsY8Y>_;=tNwkL{80?6S_wt5Wfemx3ejRHl63X~2 zhtFd(9>@JKA|Ta#c(2wmFO}qEyLq6q@LBJszMeoJj5VpSyoq7T3QN>C4u%*UZm|?) zWSn=`IrPLCgz{FfrsUfG2JDK?yvyf!r3y=&+f`7e@B#fKHB=>!OBlpFg7>uI)ANGu zDh&d`X|)eOj5H31FFv2Y{5FO1GMdL@IY&opM%+h9XUL0a!@`HCPZ$ud)y?nk9=0qz z7zS8_D+#%Z@U!sSyjmA8lY!x;o$=gX{-w0i&1vq?)~4({34wETCj7rF)0hkMW;gRea3n zIT8;X^f3v*yKips2f2OOaB$~^wF884V#1@)cHZnP)NFig;3Gmv3=8oC;Z3b~2mj-7IXh zHx;(@HPExN^+jRl<>Y1M4a&^T5YNdKhzZm$kFEz zzBoq#cvJTN&>SGnJO0`KbI)DIRERlaWGdo!M8pUJ=Q;w4_R|$F2XkmLwb)-%ad8Pp z&_*osX@_jk&!Cp5zMwBlW|zd>pkhJP@LQ78IiY1DPiUGJS;T-=y5 z#wlkXaBy4^BL@QGMUb>3>6)bxTSbI5Xu=WMx%g;cjQ;1RDTY|V76q-OBodPBpZd1h zirDJd=J^rB+7J36;7vyIh^(XZxBb#P<${O{x{9H|>S-g=lA)OkM3~~VI?vL{>g)`P z+VL$SIfX{I29R45Ylf`f%0};vX>Fq3N9-t|8Qf_`LcC!puzXI9raq@`g`9z@euZac z+|tJGUR4GtV_vJtunN>%)qIdO6;avSD;=g~Bc+S0&8Me`4w=ajl9X|VkrCFg$LI`D z2(-rzE{+WJjn_1N3N?1JV(m0Asn+&ho|^&h(kvO{Xm+)lBLF|%eHA7yhT5CJ>L>-jDU7_4}j|aT7uS-dAyRWY2 zD~+tbhGGd?R0zc6bH9uUR#1brg4Mq$&oojA0ShLhv0a z2+jQPhPJ5E_1KO4G&6}rWAiD^(g2eeDgHf6)AsmUb8+DVQi?|Kc&S~pHsb1uv z(lVFMpg&@@+rx__C_%J>j$C@$zbyC$M${xzV+d`@y#%Lf7ho?${*k^BEL$Cd{dKC<8 ztEl-?SyT0kC4(UQ4o3>(`f@;Xf*p{M+QzS`uKw_1^<&-Vu*#)zUsF()s-7l81U#=* z%W4qU^ZQJ13~ux6dnA3e`%}T|$tj(s)u@%#Xu7PaQsM@glwnm9I6~U!NzB114&hzj zu6n)b_(ES++L}CKj6<(-3g{ivc7W~3x||JcF#g48ih9BhNWr;q{${79kus;6fPZMaMn+;A0)lRFUzy68A`t;{|dwTeoSrApe6 zhA@WV>}-p(gmii%3CE9wv=~7lC1M;*8i>cqr5&8@->IsIw5p)10jRTN$a>PNO#?3~ z-BMD!mNCFGqT~&pu{QV)d%$6U2ur2k4SZblp;wnT8JHiCrb^2AWw)Id)1Q_Ov~7XW zSKRQvl{+m{MztG)xIQ$5kfgUu*vDr*|}VTv>Z<%wG0E;^5uKu<=eiGue~;`h>bQ)6Q*Ww{6DGO(BgQP4#{i2me1cDtOTO;H;X3|K?n65c zg~{cJ15tUKBV8Dmbbm4~R@rWdNnE9GKBmZWsub{&7)&y!`9`=fn5Cdnu`YB|?7lJX zx6GnP_IX8>uSY?-t(&!-Cnr0~>o|`ZhuNR}Zm*!OcN_bGhpf%F1J2ItuLX;LYC0`J ztNXIzY)$$JrjAI4Qcf;SSfD$NAk|467Lm~dX;UP#sNQDPb{Bhksudo#Bh;Tk>+7&^ z&(JSkFfg895wD3^xctfe5k(!=Hto8*Av@lD;5s?zoSpl#e!{}NzM_~{5j$DgPS|Md zG>u zHZMKfn!a;Ba-oX;XtU;j#v{D{~=0h8r=C zZ@*Dd*g6TVuW#>BFzSUuxKz1!3q_$&b4Z>8us>ooutS6GDoUD?JcWP$edHU zkU+^~Kgs>VfcRpt!Xk;kQEWRfmqnrcc7gE52-jhn5^-xR4+ENRNQ&%Qoh%R>&XSUn zf8*|^!4MLz91w1rvF$|FN`==?8{WN*HmB90V6U|5e7l)RVgqS92H{OUYqTvhCq9u5_5<) zmoTTMK&vvU3o$U$bVudc)YFR6D#AQ{1xsGyGWW;h*>xhztn6;;(I%*^OW)5HBZL{I ze$qlW8mM!qqQFln>nM&@#Xcm1@vEl&22o)l_rxV*O*s;IS6F1C0iZ!yU>`+7DlMXp zxlwB*;nlp42&lcOW6`h`i;00?C4>RU{Jre{;2#o;<97cgn3rca#5SAkAoKmr`g8T4 zk$Yt=^s6&PtE_Frp9b$|$A5-glnvT8C%VFm;DVIIxJ0PnAn(*|hpcT2706#bYR%Fb zEOXyQ3J^Sox|$lPvP&8e8Sa(un+M-j;X>|YD!?|UQc0&3#G}QLP@gYtyGdZv8VXNm$l>-tzuuHG6Dm(kk zLPd~_9@fzv+7`6|H}uULPN!>O_|VQ~i3Lmmsv+8j-g_VvtZVe5iKC2n5op6xhAkMj zfKpCsZ`st;R66XBM$N(XawR@V>XVhfFMx9h7*N$!dmDlog#qB=jQ*$OE%w zfv*I+*1J42z7_~f1b_V{5`p$srwdiEE&J#5W&<}Ry~X5Vs06iyu3o~vo%OVy039Y` zL>AYEiRF{oSM1V4ya=>RQ*opgHBVH{w)*)vm7M<|jqD7?jo~+hwTg{JGQZZM@^-NWI~mA@R--**;x!^mBwO z;;V(Mq9-10f(l1%%X8dU**3>kKK`ONS);{vU)z+c#olgN`+QI&&J7DS{jBX~Q(tGt z#A+3gqokzDo18D2clox3vJdAAnhQMT8l1(NOOw#t58rDfqFS%}lK~k=T{?Ff$)e|% z7gJ;7bVrZ4?Nr~d?u#Wcx>ntP@P^1nm+DNSgl+FnXV>+#j>n6ChFM~KvX$v?3Xn?# z%RN68%_S$_mz40jopHHuL8!znrlm5-Xumu(JMg!5z3d>ZQwkLnAST?Qz#OgpKP=gq^9q*GJ3wR(V3jeT>VQKqbxXZ zfw5Y(7!ZRY;7GPvZRNH+%W}ThUc(6P9~$D-7_vvwO+=-qrInJFR?hjmtF0gOF#Qv? zq@={rN-JlbgPmt?$GkuZ!DIgG3xAuRPNjpsA?^|n zy%~`l3TV)_bNr)Z2iHn;!D5J;nw5;fAYwiSPQj5w*b(2gtlhwJ4gy<^>M#*K-iwlkCvgmu8rTyB0A= z83&mNgzZ#uS$GhK%}VhUfNPumuiK^GkEjW`?3k<);j|@cUbjlU#>jXQT%$HBRwoU$ z6i%*g`Bd7Fi(fPL!((=5(Mg_p?a@o{#5Bhqe_y5H5##!f#jTz)pGgTw9I zRX8*-VO=jH4;Q8l!&TQ7Kl9Ymssi;KbG4me#V}%ocb%`vm4-IEXl(S)nMXv?@)*za zqqzKZ7X<*6$TCXrc3Huo2kwirp!4r|`F+<=gimFnkZzn- z?Fi^bH{$Rl4s%BU27{Ga^%R8rj15bHG%H|4j?V}F?#_;?;0q-Omju>rv}ftu^q1z6 z{@_fQSZt7_Ev+r-s69?kRJx+*mHsFoKQSS9Cz=>TyL#|?Vf@}0DkAv%NQ_cLGkjkkpw|-4R3>;UYcefO8U&q?kdYiR5>a&7T?0QTa{y5w?V{P1Xw!~?zN{Ob zj@)(r3oMGgby%P>Fs6~Kngd%J5cs&y*Kn{8szxQnO1HV!b_{WYjDvS5i$eWHvx}R=;LGH)25;}< z{N9Xsl-`fhmf}wo_4M@kA~xUs3zpaDFOB_yLNa{-bdzpCP9s?ekc=uA81B|Nw^``R zh=>AH(4-~ja^KnE)q`Eac5{1kbGv}EcbKp*EhBS{zZAA<*u8us-p20O&qOE|swqB5 z_Z5^K<96@+rrMec96jO0e2>KDpdq(Cz^!|<{I%fD5V7s2RliNZIWUdzk`@ftXF_8e zaqC9&gK-=`$xph>%q@-=24R1Hek^S=cX^`apGTwF=_KJ;RIMn(s@s7wzaY(8MFX{% z@KiK@YT_-o346mYKL8&F{_r%<~T9>++~sQ($~RywshiEpsVMj z@yF!c2|SFGlaojos(xy6aBUy7Fv>|et4J8|dNE6fF^q~RG$x8jSEoNGeb#rip>_vV z9ZB>K+7{u@oPbSFAk5VlypWxk>y|+bjA9DDpp|^#AY}PB<;&5L|4I>xq@EB6vbK-_ z4clW?D%B)VaW7^P=&q%N1z1F`Cm{>(rQI--n0UV0#7!)0sd+y_&HFv_PZa^DHAz8A zBh{^f(*c^`II!)Z>7QfRy950D=}(z#z`^F-}~bxn(}rH zJV9*u;BuX|p^kgsQQoxmU5%18lV>1l@=nq+8AGgT%oOi(`D%UJP|4@dNnw$--|kkp zwZa8O?30YN9aOdsU;F6}F(l@73^wNMkuLkkfe%NZ~{;fQD zx)`TCR`Y9t{WIyO+}?6xSHtb@y?ysjTeoLG@Cx}(Tg50W?d2r8*X6mtqzC&E!wu_z zJ>Sh&U~UAK?|dya6=x!sJx7^EHx~#65RW$*OGVExpxB}GRR-Vg$xb<)#G`$OFYph8 zpGu^Z*&AB#%@s*29^yHdrlA4_Yl=5h8j8G|fY`8I)J#M~uPQ};iKYcy*ekYM(xT&hPeDB9{=Ah>5``z~eS$^X#48?t}XB=Jj|of{-2xlw>_x{$(1K2-d{_bpqesB0eDUJRbbr^*BO^;FI9T0FCz3n!V%+7ILN&WfGl zC8p|{_UfP(mqt(0rBR-~&YdJtasrMaZF1{Ijhtp|es+$z!0$#;2f*GFg_T>JLEbCu z#&O7|Kh(-YVx6EH(cKB8tivgtrt@2?vHD!PtSN?UKonHI6ktey?_9ZPnDMVZGjQTA0A<2fUo*zw`#T|*X(NiA=jP1aSCVALGK==-qP^})Uw z2Y1!ImwM`$5FF@|8Wjw*yio@STIjad5(0nyY9b?VPJ-Zc008#=5o#j8j~25$pMztw zTwiHqA8%XvSkPj3S)S(&xOrPLZ=>TEHrxOXKzn%3$Wj8&p$Y!X9rY}S$!Vnvw>-h1 zo|4nylvpQbxBZj~#CS>lW)d?dxXEPLG$%Z!KL4yG%iCJO9fjPzX_dLeTo@1>l z=L-pRfPdM0Q-Pt6^Bhp9_K#!KCSyoiFy3BjFrIXJr{Mr1Q6#lO?%R@4+=#HIh}Fb9 z#$WWEqSd7(O&>Fvu845-7;)+;$BeZXP7B!P5X>6znKxx?zSxM$4(||WP{mTSJS9&| zt)TWxo(~Sjcj&xU{?G5QCEZI6zf~3v4ys3oudX{O6Y^NSQiHUYmzPfF{{%w$#G??z z8*ya=Fn)D-c6vW4#w6h5(W_U^ZR1?F4phlxl_hQ^WXBBRPg0_aTHoNkQMfeQAB#8%sZ zF#X8;lJc%N96UQ;=X9K{f`P{5!vXIGMIO%tli-(*<)(H=ulWz%lzon^NX?(hI#po# zUjLc@W$DcGN|*7?47-?nqfTD!Hv_e81VJWRB(eIQ{fDJBLPV2ym}ZxyjGl63%Es*^ zuY8*(x6e2jul&s}iPk~W$L4p;VP@euwXNU7V5lImQJGlV&Ek*p!9qvvGp3YyLZ4k6 zd>$^`O~SN4wEvH%w+yJN>jHHZ>F(|hHw^+3N_Y3BOOP(fX#KzV(2zNrOh9TpJQCX$F0tsI-C9WMK8D|Y9|dPN(_$T$mp(m&GW9E< zvo=z#>rprGAsL(aNsx6-505rsNH85Hi{0$~VxJV|vY3y=gkB6%S9+a>fkBJgS?-6t z69lbg9ZKXeeA7IdrEwxPiTl&<)%@V9_vv|QV^W`bLD%Nq_HWawTYP8jJ=Kq++HzO; zxh^E?X(ycojTy!eB8d3$&y4Xbb&ruX9G6x)hU~RYcHUmkqY4x3*~(&s@#b%LadL$y zNM2lM;XI*cr^pE)UvS>@aFqXbvEme^;S3BNK~c%Hq|89 zN_A(Ch=`~Tx#Ug?Tu%712?VeZZ`f%$M&SLe#EH~{3;$kh4M7-0%Qj<_gdb?d$cx1p zPGknQ6zr%17agKxhI&B?2@FiB#=+n()=tmCFHg5H#labKVdzMu={Qjr);9kP%wyB! zr*xCrR_1|jWQlvbbTCwq`0nsxcAmv=XJ!QvlFF*^2=RNmTZnf1)rm9LpA{`F0*b%I z-NNrx@w!Q|%a?$?ST${ZO)!NrGLIf%x(>Dn>e2JL(b>u9vV8hPuofJA8U4|q%DXo2 zd7EKM_{qlI{l3n)59+>!_QUsK%&;(h$dyJ=`hq+gM8+R_p-XZeXa2hUaG>ND2^spm zm@#&ix%x<8HP~9hq{ukHnccRdw_RRUC7%ZtOpQf+qWP{3#}MeVPZK_}|F<-TgiEXT zM{^aA^>jCcp1^Ko*@=rahRAoDuX< zhZW{sL0>4V9-qCfo#sY+bKTF0)XWAGqqmwqP(%yW0ygjdUY^T7T})=1TB*EoFWTYP zi;Z*&*0t}ISnX;tY4F632aK2{zBH!<*ole;aHHG!)11Sg{$OG|D@_3l=8&&;Dlxdq z97L6eNjZd{2|eI;KVGR04Z8!D@|5%5$Ksb77N3j_bOIq;^_etwjUWZ|LHF%944nw_(l$b65b-&T@ek_|H93qpXq z7*R+~Ur-r5!6n@uGD#fW!FF-%yJ|R){;MEPq#p#{ECq@Vr7x8PK60D}Fp1AR-ktq& zIZz#`|5;j!{ZH+Ina1@KZc|}lA>l9B_)!}5**J=qeW_?^`gQ>>h(90N;rw?cmI-1_VEq?1&OKOLs0Tx&(#J^D zIr$?-SNJ=1mp|#bYlh-K#D`Zltk!N*gALsNo$^8m9g{acYTm7 zNlwPqi0fcHSn{}OM#a})eKLUcQFuL$<5(x}w5KNs`Cpk@41U$yI zh_gHQ8@Sl#x0T=v4!oTbZ(V1h*U!egk1wmb=H_(C3-iA)gp$CV4P4VS&vT2IEqMmS z{%d}3FN`0UHpJl24td)oQRd_7C~$DZBphz>vUSDNF3*PpID|7f`V_}N0jXGaj$xLq z64YvaAVE;Rc|B}#>53wGt&rcX{5Nfb91I&z-O@Gw+9(qFRDylfA6jj6Tj+{$uP*Di zpV0Izoz5Tj@}zdg!_0Nq_)m{rkz~ED_j^hw-KM-E^t5JCLM+%q@#L^+HL zOQIETT_pcoT-vyNVpx_HJ%rFwT&#>b*sYDJHVPDiMl?h2_w3k4C_(loNH9*#)u7Pt zRFNr3_7>GPcLOln3Rj)SRxe5X@%y$@yDtW=PO>aka_TyIKoOWgWyjJQ5;#+p;N)(K z_ImH=Xsk-L85d5=;G$=S&&5O*7$gli0-TX5+it2a&P^Xh+DAZlMKdu%K^KAcQC$;}ErFORLC zvNmNWsh-?Hf+g3Jj3|M?*6;=YYh&I^^m2|KgPb?g_-aUM<|G{!K+&*hs=IQIx{+3} zb8Wq-R&z=C2J>oo+J9oq+qi~i=X$iDAntbBASIZ7F!z&7Nyk%p+d0iRGV|Btd@bQ3 zfKTb46HT6?9FS;Gq$I?7ZvET%=%OkdG#J=c6>kkS$jJlW!#=JiN<1pq5q(OfTkWzY zFmzq)xEi-`lFOG!$>inZ;7&o!;&Y^aS;yvA8vLFm*N;vIC0Y|tcKqja$00q#PhmK+ z`FDW}3`>TZa4i`Er_=CX#i;4^@%D;n5*T2<0P&tfcEGx{(`#FG-!MZE-PGNh&-zs3 z#%t%(?ggp3H|1?~1r%aKgao8xxrl6g?&_e_*xFcQrBM0oZ1FOrlT4PWxLzj@f-)}63* z4^5<3QgUE_J0bA-hW@SfZZgN-V*KUd>GW>xDM=(E5AnM7W^snm0VV7D+x7y0p>W>T zY-(I?yvyot`01@dl9Wg1#L%DrOJv>E>#6@}X2!e0!D*I<@MVervfjEMEB@TN!olQ{ zX3ycx;p5g$6WVk2aCM;kkk5}SaH73i&eaqM9`xKNQJQ@C+iiE%R7NEpKwGRYMx%@Q zc9L5cTnF_;4G5ToegMd|(@@MFMzWz0WX*u&?=)K<5P zdCKW}%9UH#rt)XHc&AYE7? z6fBQsGag$5)OHNCn=~&?>);NEa$Z(Xfo!}RrB`LeX}Y{3>4jNi^!0M;j?Y*;Xvwd4 zPpPhN+lz5der|NzuD~ftia3hX5k{uMeJ9Vd6!nWuJn?r6xm04AktA3 zwUhpL7WU+uI2*T4Kam%sF+tOcB-mS+RZ-4@Y|V9J$poX7akWsm-i+d}wF+EQ@@?wa zPN8F7sBaakbb-HmC9S6JUvy`!4!5(xQ6W^_dztCpOeNHs*9L4%AYz= zB7a!uigoc#FPy#erY&TLL=w zZ!x@|v$jPn2e_i&s3qcu+@btCB&Tu{M0PINX*}B)aiVNF{G5e#`cmiB#6C@`5|eoC zbO#bO2k!L0$AxQ93l1XG)H?aJl62feJn!3P9ow(hWAFBP&)YA0kE*Zq*i-Y}xd7rS< zK(mL;D45E3Rm$w|?BG5K$IDAFm|jHixUM}`(!5y^^Famg+t&?l?d~SIYSzB#vwZh5 zAP_VMRv%X|Wg_TEiNA3}Gpt&Fgle$*(UXi{QJN4!S(b^QKY~uk_WSo}HQRW|*VU7F zvxO>HK_=dk`e52E+4E{aG|9wj@UP3?TC%!HjczcG3t3x-nI&30LGp0MckHH8=$S6} zAa0(|4oA(pIN=2~kz)S+{v3Ghg$mNSB@vT>0J_Yzi z7gWnXoRpl-QKy+Y>66an>~E_k{NUjzlMO#wW<3XympPG`gb=hlSyq#d4SoXQ=kq>y zDR+DWmX9Z0fszf=QVR0;_-C9{Hzoub|B<m*&(n15#Teh?>&dlvA}j@hl7kP`-9%NZdcVPoLv-KA7lTlv!mxvr~(jel&- zC?%7@o7mOBGi`lGGcc(`Y*va%w@(1i!8;8JHgDEAre}hEr=Z-ATvmd|{Vo=FHB&L( zuTDW!37JcQWu2c>;60KfW|4hl0vcUldU_Wn5$z&{ovkI-0c+>vD1siWT|K+#dFY^{ z>$Hi{??dJ1am)`Gl1XHre;fntpFmQ3iS@^1C=(*;dtt2TSOpp1J2yXqE;4?n;E5!v zg`mI2*2X%6e&+~&Uu2j8NY&nAoKjTHw_K0i7D}lA@Q)55H@ld-&rdCWbkHUty$AK; zTf+{mHL{}#(%1s(FJi|BfoYh=#C?nKUO8(Q^&tb6HnaRUT48rY-js9oV+NYtoh?5r z=(M4@d`?W~gZvoNAxP{|*0eN`;~X-pHVv(xIT;I&RAd+T{rhG8=zlhoUe3G|1Hg&O z*_;(HP6DRZNNqRw)&}nmuM-O|t*>#IIU7_+OyXN0}IXi{=hBMKDp1gA-L3zH}E6VDH6V+%_K^R zRRhs4@}T5NGmdrP039*q1OIH~lE+1&>cS~oYpXwnIcyo|;7Ek=&k)P-p4KnM!6>fX zOm00tDKCNUbl+SDc0tRiqjEw$;V{P74M@x4@Fkax^It36MP8#Wk)~rymKbrPMS9!cuqsQ)n(5i1+yM z)bMlPZF7nS1zpZf-Y!>8joh;}khFs2tlN`^j`loiv#d9ZIWki3Hel98m&333}nvLW^8;lekRqsC#pp0(8Sa8 zZQw4THYyE&u%v}#w=<)^ALnk^N3t;+ud5`2NY4^!I>~bPaJ=+ zL?7zmTryJQMoOE-!8HBFty+d4rsnyl0byJOG7R6_xQ#72yshQCqs3ljwx!Wm7vkE1 zg&#gFB;1BPr|9wuwBK`5Y|SZ&D9Bc@!M>*v6Ny@rO*E9o%?5!a(61P?&UT4+l)sJ|M8()|MTN z>H}%>F=#~Elyhavt-kj}leKpdY4c$lU4|@qkb=gkbSVRlg2aoTQxt*2M^fbYlCSWK z)Q(ZlZl3tx5`O%Mn&-4bQh?W&ZETrVC*JvK@;+F6avi0Vcxk`{cciS?0PKK}joIoj zN6-5vG4MN8P=Pwg19!gXs55+3RAe8mQlK1##ta-o33s?uZyNB$Uz<8Ik9hpMMT>k6oPmHSM*#+O14Vcc zQyKC?-Lu4T3BIIT;#&H2e_aS?f?fy{N!+#3EyHwxzya-4rRso_2$oy{fJTI_N`TJc1Xt#aEYY!(w)hTzjETKU~G7 z`cRIHIqRERP`I=|U;9`q3aqSdG(8M=7aT1P(Kl=@;4TCyja45Wx}EdjM36iOIQ^;E z#D750LOwA4Lo0NzYGbyfd)8UMCC}tm885t#D4KAYO%s&HR58* z2Qx@phm5R3rK8tfr%%}@_m$6DSylF9tghnTK=c@U)`Z!S5#yAjsfn)OIosytMD59lJ^afC;Z_zTQR@|eXC3BV#ESnx&Fwy@s0fx<9-J;B!?E-2{iB{gel(~R zxfZP~V6*$GD~$El{!cqPu{U5O^v<+4@bU^@B$zI361(0PT||iUt~y=2Y~h@*R#a3B zF2XWBeAp?|=&5eCdilU8o259u>Y=xg`VkJskzdTeBho@=(*7dgT!1%!3>S|g@ge*N zkA@&jzLcJ5`uaz%-a@SDrVt0&N5=>7$h-Xad1MbLDidGR;tRi&8kyY{^GdRhA{G+$ zZ%;TIk4u~N9*hea3AahKDIZ2xH+ez1beg~8!Q)D@A&L>e=b(}B`a6tTXViyyeEflg zk`oqMu{gj^h}wEK^?E$TY%0)jfr%}?q5iQ7$M3HrN{=xAF4^Z6A&OOZEtkJ!i;#aO zhL3Sj(~isD>HuHEyvDzaN0+w(j+^*7hmTfwlA7Ir8=s=Ro(_b?F}n5ET>JMQ{*VNq zT;On2wQY)6k@LOCOjAofN}0H)T-}Abow;1EvjB@!R+f#lmbs3RT=ZjOHIgJMpt{;K z>B0E`kxt}SekYym+w{5s~1s29Q9_)2oN3Z?2RHGe@X zRrIL;{KIJ*QBB^%!AFr1^$+5Hz--TNkHq}_k)q`}B*6In2GyvGSu9xG!kR`_KESNv zmt!c$H~Uu2rq}CQNVd7w!CwRh#{CBJ#uNUEWT_PXdiACENm680kuOAe{!< zA=~>D17QpHnbx>x6SI4h{0y9guMGDz<>lo8OhG_m2ywDr5*~#R2|g&CT|BQJgg2+F zO%SxB#)0*UT{9!`x82mafTF@sEU8MS*2uz*)ohI8d?G@( zYSmXR-}gUpsvU18c2)4Iur2!7Fyo~v1xv)kToYGkCs=qxEVOLCb1#1}z5&j2`XZW& z-}uCkYR#-;R7oCITjJM_l97Cd9Y?lc+|Z2Maqi3@QRETjQkKT&YW$#FS93Ili~qam z8zR-eE=Yd$1W^%$GS$ED@$HWjx+UZc*ZF~n_FX>U3`hdYvc!M{LU3rEW;jol&qJAh z$6o<}f_$9qNUSDxBMg!T-29uJZT#5uCG)3ULuu<*JDd4`eB^I0WnCaCyMe;QqPbl> zGIFiBwFSv~!U~LWeOte&wsHgS<^ng@m=7ZV1ozfh?)~dye(HHmc`17D|N6rpyqJyx ziKXy+^6S=CmRlXo!VQ-CeNyZEy2V*1g(Y&4#OBE%7kld!493p#;s~SK`l_KZkE0|Q z5H7AMvAWXX#-?AX9%ttJM&8`h;Oc;H{^oM*)CPgG_PfbDgV$mPTo_ ze0}eOn9{}~;(DErrVAQAAfWrssA%3UY&ul>SI0kZl{mj%LDnb6pwucGBH1{17XUe+ z4%|5JBy+!7d$l+94?v)NM9bh{vTa~TQR}x!9Wd!pN0>~Rp;!j%N?$Q+>%!S>NQ+Bt z1-*EzeRBHv>q$~qZv%ujNx&?STYKzY(BPajd7>r&u{x4$2uxtHtm;Q;I2BkJ>UWWA@iDIrGOyvV<(4XIy0=iE*!Z2LTgN)` z-JWpgU`9@t;jY&=i#;#$p#=Nxhslf_uCuwP+&e-0rwz|;tQPDCwKr&J>#LzBQK%J* z6x#<=ELGfVnPWUFbiKUvbnVp?tUL+cq5b``AHB#qQKDMxlOILg&;38i`VP$u2M<<^#pd((M>H+uFuCl1_v5%AK*A`OLVHLyH#P7C{kKTEaDpo2q0LnHRAe5gf|=_=U2MaOx~ z98i{5BeQ;Zq9bH4<3;sj79n-+NM@g3?J0Sa)p!|wB!bRmy^QDiJ>MR2{~N>Tlm4RFW$I}I3s*E`H=6@D+R(!j=n>qk) zkmcmI;fw$Uie46ms4L9xlPaMfVguEmC=BxL%ITsfvnT(4#3%u=FJ$5dJD^}*bUfz}_F zQdYXbSeFNYmpt@y4(DCy)aydskE0x#AYx*lJ+JA8q2CI)pXYyqgr-BD(TF7tr)i+bS6!w<=%}6*V|W`K zCiQDp|b+}QJ&BD-ssqw5Y#^Hip~MX ziXDp1l(c-T@c_hvW13Kz@4+JAGY*&Hbdivh8)nC0fT(<7mZKJ{&=IaNThu3~uV2f4 zm1;~VmjdbCiPW#j4^w~n35M8NT?5cJU{8jo=ksU~jsOU<*^-+1+vCkq8M^9_&)w-7 zmaolE0c8K>WlnpdP!8125Pj`7C-Z_|xyASxsUUD@54NAtPrlrev9 zM2wf!O~nhkF1gFB|7LvIi8mvfYzyX^VhkH#m(WvwMpwF!(jOoCXN6?-EWr9uQXd@=M>rt&A?SO z8sSCGn~r4Ny=oS@%ZbiLzxwsDbIwpeVWOkV|3md;@>mBFs?xa`*M72xTJHY`!99dC zTnHZ?`+^7Uoacs`n4o4pe&$3ivhT$Eo&SXa;BIKHvmUTFr}kk7qV3?F^JhZYou0Eph9*7JlB%PB_7@}E?`|Hj3J zc0r+B_C$lgCeylQyemIkPV7i%1KMeqAoh9i)m@jD^`=AF$unlqM>|4E;>Rg4=P6K- z6QZ7ooP$e!nk_y^$idkB5XCjTCYA;MshHywUpLap^X8K~v)193H*=Q<32c}CJ+|N% zDb@p&C9S{X+_hh8cWu|M{pAXfTp7%{BO#IhW;*|yt%&`=6#1B_xzEmPiE3J5$hXPt z1VwMNcR$`7_@lD<24Msgm&~ASMiL6Zvjn=Xx=zbD?w=lN zzFGS!yUS5E1Me3!h?>TZ!Sz(>HX~o%-CvlpF5of$c_l^eq^~Z$(nL7_;CrzNhqGk? z-Guspgjgb72M!OLw(qHmCj<7ZVY+m#f_lMJ@y_?>8%uPfV>9t`LkFgVYpsr^dI#_c zcVF9Z5RgbF!Hv$1(SM;=zZ6UR5$elb4Na#aP4w&ASG00ioxq2r{;6*E3(xN^Qb}=9 zk!M7!{1lt&R>M8- z_bTb;VD5)r=!~38veq){U?}Pc$pE3H%NUB&gwR#gt`jJpE z?L(@Eeo!)$SsEBLDTk=vo~}jZM5+&-PK9C7a#LkMx+i?MC?snC)d`1q-8J78#+b~* z*~(elykimeaMka+ckEE8unJbJ_-+e`)f9$XSXeD^Nrq+ zU*sWoGVpqP_L4J6ioZnCylq64p($Qu8yMCfz#_l*5V-BFun*nRX%ii@LGll^t^}bJ zx8`zEygrZDmw!@@qH$Y+jI)njPWeBGnJBJkPBLR$r9d5wHT3n4HLh^`{BnijKs? zc9+*(Xjm9{hk5n^peD!Ts@mEmSweF@yFt5sND^Q7fdW@y-{Y>Z ze5lToAm3tV!A8vna;ZA+#{rXh#egj6l43ob(>!u$H*i&~;7?fVuy< zjK60y`zTuNq>YXf)Hbcr?zjbCYMVRc(4gq`eKinmH zj_Q~C&eQc>&@?X^p!wFc4fbR;Ecv|e>kOiI?~`RJsnjV5?1c!3Bfnn%DOb~n&|5VZ zjDX{TIZx?YKFs}8GA{>g-Y(x4T~k{2Fr{3<2)_!_L5+wvXLuB=Z6BkBDxDiRy_m1l zOu<8CbD(t|!99mntSJt8moD>8maBHzw4}U1osJ(MW_yV+{5126%>m0= zqsrAiHiOPq)1lafnYvGI3fnD%$uN;St_VW*1whgCB_BQs_v2H~m!ue&8z9K8Z+k#g zYxs+GY6u#W7;^@wjyUmjbso#h1-5^F#w0mcDQTrz$e zLX<5ljMp8_KmVjw)H(qgsK3$ysWhpkR9YmkC43fx25u4WW6(BG##=$B%!ZO}sgvpO>1G42Re< z7OGmcnF{Q*2GQH*qOWtVk<lD<1h`S1Ps$||B25C^~cFawb}-5(^r~i$xGua|7sC6ciI4s#AEGW8=|C> z)iy5M@UzF3g-|pSJqRxyT4pDm9?_^(zk`-?p%^S$JcK)|PD`)jM>S2}IyRjLzs*k@lW7Jt!41jp0-wW6ihbN?RBT9%HdbJH2v21A69OS zTChq}+Z1x#yA)*({(GpH#S4--*LOYS_P{FL(pfiJ?Rz(7d+EO6dqL#ADjYqcO=3Ix zcbtk2gs1Vzq_3Ya)=5xooMW`)^Y``tgyfH=0jr=P*pPJ|FTh+gkeE)7FV>|^)YN!d zX1?=4(XxO8L*PD=O9;3C>SzMEMhst|vocly`I3RZFnMl>S!?z)9Ko=nci3{cnrRGqWX87k__ejcNxqDy?8>@{!J#d%VJ#BPZb3tND&5Z10>; zr{2pX(HGbnV_$Z=M%MO^v1D}O3Pkb>negh8cqeLog*v_Tc~t!F8E*!(!RJy0vI-cz zv2>YJkDEgck1RZ({(fEzBcxs}0V$MpL46PSvXHS9vDt>z{fRciQ>}j*zVd;2z!Tb zs3(H6xW5irb+iQkcZIYKj{rC78e!^%7F0wkBlqRzki_O@`zo->wUf@5icEkm{_{f4 zI}a3E+s406GTSK^kIJdG7X^Mm=PI3HoO~9~@o{(nWoFUWBuFp|3x5pZDI!{tyhFOCI=#&dPXv4e*H# zxnI({uHHp$4PV~-SUFGf?{)H7@ovB_5Rrb-Bt$ST;GX1fkg*DRS$208CDCSB_=+|1 z6p++AnjM@FGQ4jzgaj9i*Xk`YHOIrHt~6t{+ph9*aONYXFm-fzsCD+Q_RzKY6PL5y z6%@-CT4*O7>Q=9tqUGJ4?tb{E9N%7MBRzolm*Rb6-`FlUwYQdfZo9cez^^7Hey3vXsy9z>8$qt>+o6Rvj4sJQpHR_4dHf zOZ>k+=>s#C>$9eU?lNIg{eyp;swO>hY~w<78GgZOr+s%7C0X_jY3o(pPV@N)N1jTz znCZLSGZ+lX{@Y1G6eD=waoR2ySo}qL47r++1JhvphmyOad`nUo>a{B`d#8k(`LT4$ zY#2g=zl$dPhYaUUNrmT})(`Z1NMvOnf}}s>Drb?|Y0M;Y&i?-9u_6gKwg_L7G!!j( zv@Jsj&T;XMfoB!cQp@(er|K-x&4F&e>w>R&{EjTD>&u*9|B#PK1l4UYi{NP`Ks4)2 zV8CzR z2m&M9>MMes*hcyl^D<7)=_k$-$lm9A2r?dvf4!ACiMN7*`Y6;}ogq2H{gocj!0 zb5!#HciSK8$3jULq#&m>ejf4D`EQy%GmHDn=Fzxiq~h z*aacAIMA_cuGGdT-`159inXq9ZX7LBRS=blt!ORe zq2=FQO`JT+g48L2IlqT~x3dd1a^hA*v~MG0pskhpeXOk9!H{aZD<1j#lDieb{5O0w&gHmloeUAoh+^mUtlZil7=U{0nm?QNo@ea6gq_;N{YuwU*@MI8=9r7X z=DJSywhKz|B!m`rSp3}|L_jAeELMGQYr#c=5BCk$-pRQ73+yIHXJ7c-T~3lr2QOFb zT)PklYNBDd4H$tF)Jp#iPT?m>Y-NUSwsf`b$We7w)``hd=Ps8z@hyj8?_wbmk43(- zBy0oJuF1;Vm@#1kYyvaA%(iGKV6yFvqq|QY`zJisjuoFt(#@`c&08nfM2z4;=9O9Dh=D ztv@IpN50z3k0u6H+(cywZy{x3dmm-%z`Ji0JPQ0)3=VS~xgkKoSG-)OBM>2Fi#e`l z6&exsP~iL?%(Lp`ydi^cVZ+Bw?opX0BGHil?#6iPT}OR_B+N1Lk!tm6Eyi1l!IytT zN_!**P;8U?i#R{h;VcOE866WV>+S&8|B zM*K`-W#$jus1|xDKca7YB!`ZonOUErwF6YvFH$k_Cilk-UmKFty*zxaA1-%H2f?8b zRQsFrpVE%h@bGQ#7D{y2TDjZeFY%j2Z*Oj7!g21OQ@`w=13=BKlRt`sNak;bZ;y-g z(AmCoeAc3G_HoRP)T$o9TIiVow^)U5a+3SFvl)n{nMd=0NI zDCo)by^4m;11|)q=mc;wsw_5yHQ3Ur>a1Lac57Kb&Gz5+i z4}32ZmCfB*GHxFd2r(Pl*xp?kjhq!_iozSJEw4Bun-o@F)-+Vh2v5TwjJ0O^nB%CR zp+DzOa%&}PnzzKG(3gzX^as>NZ$SFlKwDsI_fWE8BNY;RYwu^dqi{7E8Oy@Vn10@s zc%b#R-Sg{L+2um_&>lWwH_*Fkpgi|NY)@vnrtG>#hokf&iTqPB+VG{3rkQ)p@|EjMgQndoT3UCH^6^ziIwbQ+-KHsZX2f&^`Ys81vH*zs z1%TB<{=L24{n|jYHv*9u{BhVx(drEu62%yifv0#{8shE{x*F%&^lm)ypBvi^1bPUI zYd-*|ASYdKY5ix!m$D(GgAe>M5L#b>m+LvOt}b8jZwX;zOLyzClFYmc#_CnU;#mcI zAM>{M+MA@u;;k|(8AswLZu-C9E&6R-S(gRZvmvo39+r+XjA(E)j2$obY!;Ub(>N#$ z+MTYq4ZA@vX#d{!?2)?@Vr9niRxQ{P~H$3Z<}FIPTItxz!ed+0O~td%FB)Mx3(q zA-Hqp0c7tHmBcNQCx`31!(!N@F`{z46}+)s?XIxKQ|B*)Y(Htnik>*U#ILDG&c-&u z$ZRmny&Vo&sfe6A1ZS-O`WUWJr6{mftwk)EBOg5=kBq{}eiElo)Y*J9iUoZ$&g{!sh+HCG@Q|uDC+46exe3#YH{$ zoE{vYHYs|)V_35Vz+ZZRveUeYVTZDlU+#X6xUDu5Q#$i7aaC3x-6;k3_+qX1n^EEUvdJb!B6szZu8;sY@m8&_Aqobc6b^m2yKpW^lj?`hzM$zvJnL(hP#&Nuj zp^M$~1>=84;UriBF|xb2Y(R3+ic4S@ENZ!v$dF%&C3 z)rR{(z!Md$8^oVpfq=;4zLd!5FTUOV)&I2_v7;~hWG^v=8e-^~1z(Rhx zDuhoWxNA*54zz4VXG-R9_>sO%Tl2v2N^^n2sQJ!&{vI83H=a}YN3>C0n|BdZJtBCn zDWxSP^(_n#__f~y@&X~0?*tctr~{(OI*6LK;;zE}H?pN^)ATQ9K6s(?RE=Ku&+_p0 z9t$$pgXc7v{Qo-6y1jtZg75dGxw$@f+~UgvTs}v{ES6KLp93MAue0b zbGBq(l9DhJP3q%^HSenlZh8n?vB2kA@`V!ZwI%wYr7Cabp?F5ezv4i9-LcO9w?ZX7Gobhg^pFkW#^zqYAH-uu*KQtte1mjk{bR_XN_{8e88> zq&UH@RwG#Fyj6Q34BwZMpwxQAfFtF8bmY9a7X-19k;@*A$G_Jh#qS)j-fP9$oy2V@ zu*;r|x1WZ|hOwT$*K$29|EW43f0HMA`Sj2WJDB++#ao`XY6;WnD@-n2ag~ld{Q!2%GQV zYP*_!oCBGK=Y85PdnOn4x$|%EkSA}Io*s7N7=uecSnYMz&jr`sw(a2W!!8Isi_O4U z77~wdhw{c~UC?WgjOlgJG?amyeCr`7`9Ny`t6T94(FO+sVv~aMSEUgy70*Ce|q^&_;3ic&LOFqz{D4&sf-z6fF~JIF-xRi7_KAF=rdC~2dOE~7A+5@DApV^vTkF+ee7?8_b5S>EL;vl zz%vqGxlQ}^Oh>m4RAuykd^iUR=g+^8w0wU8%S$v1AUBf9t-KdV!+!WgmfYGE%bjqo zBP<lI7hZdchV~#WhC);Vo%0LO&_(5v^Hg}JA~Y4C<4ENb{o94%cscutlAF-_hvL}{ zw0Z;Kry(HoBJ#96wb`8!vbj@P2jiRl=Ue7lqhe_W(FiT8UY92i(K!%uD(V@LH$I*T z;`NoQPDkfYhFN^vqIl!m_-Lr}Dd*Z+OMpjjAM-qQC%JJ$jN%bfW2fBtaQqi4N$=|R zvT0HiJOv?(njhVNp77vyFBq*-{Q-SvppgZ6tT zPbWXt96H86zzS}nrRdX{M;2MdQBdAfxETR6Zu~>h6WM1=kn@p z%+(ldeXP~SVz|5B^NF9rH|0PP$EYwlZ2(q9Sy(2N~)t^Yy5rC_avAh z^UI>7NXGy|EV{lE0D8xOaW1-%>;Mw9q{+x-={;#n9=4uZClMACnJqU))Dj3mky)mY z|JoXlx!eXHXt9DeRk=KL2~y9+{*fxfQfapyRt6^tJIRZnnu)MY` zv?~>YE~J*w;x!_)cJL64kVn57iD}(bNd(Z7Z>DG0mZ|{4RC8L~d?;|USax$ee#u65c{k&hioCX3*x=5&hy#^Gg zh@WuHJGRo}Gr8G>>ObaMzd}$pEEHG2zvqr`I??-}s6&nP*WNbl592q#26@N3?E|Bx zmS6w#*@2*Q(}y%AS@kK&h`%j#OxH(%GLf~J|IR(V)w-D-YmtWt_yWQ0v^05+s1*eK zP}Q-ooh@$aF6!h_c=&0lQ)SZXHHz&!poQf+YF4@vgH4W4of_^^S1M7E*yHYwDoV1s z#n3E>?q6NoPuas?kmc2vWVxeN<&f62yKm@K5^Hb*FN)BZ+@_a*L!jJqE)MSiNI9a| zZybl9hM$Hq>2w-&s>z9+GVs3q3WBwdw!FK)HDv-ea)S`E5W77*QJ>WPQ0iF0Nm~w? zKk~6)1f?cpSs0H`6+Q?l7Me{67fdoFFJ6UFRZe>jM$uB2o6&kiiK+Ka@6d&CAlFuAq+@{GNKQ}_{PESQCld99O4{0;SziGbcZiVSUoCR zsdM!mH+W(`pf4~SKlr3Z4=tu29!gP65He>gt8?DmlGTPLL4KSq+jeY-^9dL|OyDRJ z>lhlcVVSLGzF#o6b|PgJt%kK9;j6I7W4}xl=lYYIt-qV}#w1U<#?pR~YSaojC7wWT z<*MMt@EBvT`P*5%YG597o}YAs2`yWrP%-xHKXV?o~M3y#cdD^)|JT&pPM-@I@cWjop}p*lTvJKid3&}u>9N+ZJmMq zE1h(NK)XsuIbF~I%N*XKH9V0btPxc@^F zeWDj~U0d-!)5tGd>gC94l<=|SPF8|Gz6F2s$WL~e)n?vjP4GJbDEoSNwcaj8vo0I@5Gw=HE6)(1U&}F-o zDSHJv*b92M;$JAdb-`Gf^1~y_FHH&~@UC5xc!;~Nh-A5V%I_+NJyl|*}|lpWf7EdEB`wRtl3JPYkxx1M}|Bf0#Mj2u?4d@FNF z*@{8!!yWRF52ZmIzWAyV5+5EBvPjflJFJ;o?=(d?obGp_*47U%f-qgirjveW=)*}` zyHJpG9u)*HsUorVQ(46b$*npXh|X|!GJMWPaul(&r3`7 zt@aYaJH_Kvh=|dhBum~;%eU|%Q|xR6JT}JetQu?DBo4e*{On)g4;^Hd$vbHNp0f7S zjX4szAmnt82-g zJ?%rE^){1lcjG#;7nJbjSV>#gc=9vJO!&&=pSB|J`dRTUmVL_Lx<7U6zG_}tyI|sU z3oN`l*)~Ri%`{n63Lg)ztzM&HrlWOd*X!gk;V^BHIZ4?H(%QE7=Mb0j7Z?|6%NU(h~{Ss^@>Ylb>X z4nBD`w<9aAd+CfiOY~+Ym1@-V(W7;H+GTL6bX`W%oi?qle;}zsfKrxtpzob-J?GYe zI$QqY0WPZ5x{apcTRkkF&@ALvB{H}IHvZ8Gl*FJ&dLl(;(ZAhzYq%+p*x;~zm2sT} z#UruEYEq_}bnGc%MT%0LrgyMsTt|e<3OLcZvTiY2D(sswSEZKKrG@}$<#%zj;BADT2X}Af z0%TDB?Soc{Ji;x4n&~m3FMqfQBKSW~MVoZ_Q#0N^{+T*uPxW_Z?HJ09NVv=VGGf_d zFgiuK{5cn;dehn9ql$q+m|nY)3AE^;4GF58jNz6nV!Xn~go0W&IcwYb{KTok^X!PX zHe!H-`2O;^9YN>~5;)V}&qFJ72tkOc<_mQ^C5j>hoN2t#IEg${cV1V&(#$BybIOpf zPZ6Ji=J7s%_Su}9q_ONGbrhL%!k;Nc42;Pi@K7#|6MLl(6ogd_NLVJ@ygc0o)pmw;l zhAzRLr;SS_SJ&EbMDA}l1d(l}cO&L8bVQLJZT&dNy~ozKf3z5B={1Ln)u~-RKy9f~ zb`27*2AIn)qJrS?kAr~w;v>3bm4dHr3wt+F=S|;we0IDG7|}n;qxC?n)!(|!^PyW* z*KL%{`d?;E*-Lxhin0=%a=kh)BtJZ7CZ4PF=xBQuFhLw!WrunIq5Cgj2j(X-gN-80 zq2>?a9}gPx{Q8psTIB~e)`qpfT1P{}^?*~Zv$BA;Pl!o0p8Gq>JL8fCvN*&f=9fR; zxAF?dZ(d%WZI5w?WL(Q+_=%G9{5dGnXO}D4skkcf*@IjmFmo~hc zcL;~et&@Mx`=jHW(U{ozXGjtKcDT9h{jOv|?rLFa52xchb3nNxhJQBT1Y7Oy4CjML zJAg_D#7r0vc&@UOuf@8*Nr#6Vv1S+PXaffF>@s6n(1l=S4N;Cf*ODpepJ zUIajEVX`g@=+e?B3$5Ij8mF^v`zuQRi6oMf_jlsaYU!oFF&IIc@pg46Yse+D0;v9` z;XMCb&u+&IS6+lR2yHX*{M7BmsDsnUPNIS&$xi$y)Esi@E)wtop1$j;SN)SMpA4%0 zDUY`4f)rd(J5c(d@_lW4AKoOt9}pbV1I?+BSR=Abu39i%x(jSferT3Cs4IpEO3j_b zuLv=HCiHC~q=41^8x1O8^0o~SePFmO9urtoT`g26UG3BB!-_($oB2l-v;^Qr)Ayigs)=alNJC3XK?VH zp@XjcjX5v1DpDJCFUzN+o~%?#_=EyOL1^9D{qqm~1Xmoz2w4Y>EHjsW?H4?Q46sNa z>KS2Fj(VCkd-q4yjNz?vK}@UWC17q%HEChtp5;@ABs1LWZq*2i%ai(7_~HF+9^ z7a(0G47d!p%j358Da)Ieb{*n~jhaKf3{fwFvMKW1 zz4&`TR7{XSZzR)naFNUmW4@Yg0Q}zTbX{=aw_ydamm@#_*!cN7&fe~qk@?4$y^e93 zf`xhI2Fr%fmGsWoS!oflH1EC6yl9LLw21}eAcZeNQEg@(+5Oser;VClYV_|Z%>uBY zM%eJ+H5|mJf>&bs$#OwV4LqB08nBJ6&L2g}&iwPXfPJYiryEG+qwJ&ENbz#35lOG^ zq5PS>30rf3!Uw+%Ej*%VkQE2esr0XmewN-%D8n3b?r7eHy^%>plF$5ECHYqEwZRfI zMSOx^^dMa_1*1mkK7ZGQ{CMtW=W?|85}!R zqea-FB|tlsNP2NEFn_>xa2Jn|=_B%Y_@7W8Kac4LHROJ?O?G6lPl@u>eoh1DX!(_ z5CC?O5Lriq~%(7*sp2bLmz!H`)J4@JxN+l=QmVX|)x3KWiSrK(D1e z+e7Nb1k(jKE=x_mPG!i{h~c)Z)c%-<*}CIn_c+iRrrZ0TDJKRZ{!UUjtJ`T3YNYQE_1 zgXhM6U^d-8q3(CYJt%}3?YsO!;r=P!Z$8*De%PkemBimBH`|~Ox)2{~m6*yG4t=QRBP&j`{Znd4QPEg(rF8KNv~t8a1m2wQlN8H>$(#?ZnIA?WlX0d!B8#;eDjs zYWX=*V#a@$LFvHshcN>Q;@x(aA6%&wH20R+f9Sh=qz6f}GS+*v^jE{EG=@!aG%Aj} zX79fEcMAf4G|LS}1o?Zd(6M?^NHgdlhX&EJRy zp&1UlfF6YJGqdlYx%*h)j`zHTnHROSGz4o8dRL(|G4Y;WgN8TEP1@jJd`&K=a3*_n zdtP4`U9mTMvGMMQZVf0s36g^x%(pFiGZteo0vDdr&qbi{^04&UlNHXXmbjW+%n9R; za9-mZtfhRNi(3162J#q8I2&YsGOZ+;rT!B8`+M@!hEX`atd^x~Q|%Zqn?w5EDG~Ce zUO6SFpm;$l8@q8b55?<;8kZ0a1KK>CSFnYH$V2hffqV-7$4>tLTvrtbZy$dsD znFh67<#|BBc1|PVwjZ~h3k908MLAv}tbPsHvN<4&U0wGI^lC=Y(Jl$Rr}Y(7UVQm2 zTm2?Bnx-o=3G**93x0yZw!`s$<8Ftady6EM>JT~x+EYB|N(D)ArW@mx0DDaaQ463s znQ*ds5KA$Jj(1ti`@fTXL+Vua4*g2}zJv$Ay}{?T)qn#s7+T(dY$LSpdBawk>LehYi#c$=ds(%77=~5a;{MBPFbk zS+ba=s2QW}ez0cnB$nzKG0P>YHH@mMFpXq73I#T);eI!ZibfKj?SNpP_Q$DzHTM$ww_CXh+jZeCFCc~qVi_m;K9U^ivpJ8tDc61Jf6ViQ^ETUVMd zgm{*RS~n#+j^sp%$;wB&#FVJpgsVeEOyP5cl;P>YdI`*=Z1ZovrB(Om=T01b?@U1u zU2(RZHPS_>I@C`6hbGC093;m~B#d5MjHwaGB?F=*kVv`wEXJh?QfNHs@;o`;ipkXe zubk)Rk7I+@;<|E*l~Zs?|0F-`a5n>?_XI9odv~AwP&!|*(5wNNivk?@ z52IrZv}3BU+&G01ptI_rw970;1RmToyJZucnQ_vbbK4bofjfgiBupZCGPHQ##IHQBgkhTfa(dyTj&0y!f)E(CO3M_13T>mLSJ6 zjl#y#hgX)n%In+>B)%90F%&d0j$Z3xq7!l95e`a9TSIDl-2?}??ug#A>#j}GT$X(s zwZV^+RJwps?s~XJ&Tr1rLx)o=qs;)c=OU?(5cRVET4jL5rXs>3IU|(>w4)&DW zODg)IH)ZarW`%9K{%G|)b)|b9FkoZAs!s*1DSRB~bW38)*J1;1hSLh!Cer{tFB7!f zHS0+)a7#a-`ni3R57o)gcZw4do^2gB_~Psa@-6TeE(`;jFwzeON&)DzyLazwOjI9d zI86oh8#YHl7!{o|fp5ux$Q7Rkg;F~?@w)m0Z+YHGf>ir}jK!#^(}OX@BX6@w7j{ zYVHO~71EwK5rs%;-eEeTdG5FbYM{6R)_hP?qH%B7;Emy}>iwq`QRS7q6zf*BPlZZ2 z7W^5^rT+E*tt2)ot;fnoK0bQ-=e`4GftMyVtK;1L=_8fm7x@HZVOGH6u7h5(v)>Iv z$U7Am8i513Q)pshvYjlsUFc;F>HR*c=wAd(x*wXH4c;#5P!Bk}qH{!FB)?-g1wdLz z!!3K=h3hx9Uil+#ID{WlJbNBW8d9iJIkV_w*F&LRB96_@Ac83cc#B?shEyC>T+f7= z7=a^8rC&rS*-kueBwCHo>AEM^yFL&+r*KKfPav{|XfVt0Ss{|ni(atCJhTF$Qd%U~ zKr8GV2ICWkg~@$mIiI1pH|p)Y-0MG=S!0Iy5P}Cxpdj$?#RV_f_{ayI=TbCfj)E3SnuHR z!i`v%A!>xr?>^%)zP)Z=AQ3-aS^;E}gwmDsn)7q90esc~ z35JBjKM();XH^o@RfL1ly|1F{Wr4TbO1!;;;a-&1^~&a7ROUO5#U#YW9`%jj)?=HH zwZj>CcGRz(9dT|#E(_n<;$ilA%|#yY|7x9<9GG{4#NM`FEZ|CjxP-o6fS&f+6keR4 zTH0}vUzw?3&RJon72{<GIT( zzi)jOPZTUS8xe1*EWPv@A~Jm3n*Mt7bn!(0goa-WKVptz2YWV%D)x6Q?<^1^_9^5a zxj{}*Cg#^H7i;BW;7@X?6Me8g)~B6HB9a<<)NL|YpeyY4hTJ5m{_2nx`CwWGKK7MB zH$WpF*yn)(7&kk&rJvAB2zvW4ie!zH``w;OgCFkIA!chtlE84BUg1xPKRVs+4yk1w zt_B-r-qw$pM0mB1w(IA!?C-dGS4#o=1&N>*`2CI1R`k|yNLQNp)Mth5&o$o&X5c&# zhSr)Z3w_14SY9u2c%60{obxjXU^RL_4ZWgV15pLAU6=mJzMn3SR|TfYef zz3lBm9?f!WO1GR?q#VpW=qA+q$>*t@w|zxdhT%s27u%b$d4V>St8uIG4ZeCcZX>Wz zubmxG(^>gVEO6by7~jtOgRT7!htJ*T!B6bW*!W_aV9%1pFX-lkT$EZtCYnktGte#I zsklx`A1JCWV-WZSO5g6#d^&yx&W@(^5Wz|98aF5W5Was^oBeB7Wrac1Xx-P9Vyo#y zUZWq1XpL*?UbX~~5xWlV=#L^;r~eb`#^%y!t*85(U#kQI#m8KgoV(&}K;(~qYUWD9 z)4ttA;9r@9Ib{8?BN6ozcK3g5D~eqvOHLD4%Pj_ei{}#R9X8mpEx*2xe`V#zIVgx_ z%6o>sWK426PfvmTpW)~6*1vx<Y08qj=g+xpm5W?kX>jl(6kC zWQD~|(VM=KWazz`lr7;X%7a8ZM1#NU@FvlNQ>mI3OXL7y50yc9{ro9(z z8~1S;prM~4=*1PPB@s?auLw3KYlKaN|6S4B(??*SR34F#sNM2M5!b5^EH>z{0q*XdC*Tn{RaV{ba#cSk=Y^287nDb`GEY z@k4@1t4Sg{Tuu_Gi3`glci=t9y7~{;G(Ymt2TnyW50e!Bm2(`ju0tbeBlm`Mb8-bF zZ-I0BNDl0>34}QcbSmvZ{zBm02ll#JqdgP+&TE=*LJVoW>$Gs6Wu22W@a%v?7Ek3r z^0z+9SoaoUu@W>E+U}3CB#9xS;$v2P;bDwY2Ua2pg*_Z%p)Z+s0kbaJO~%BpT(g%Z zFXnF-0?5du@tgys!h9A)(Bb_OiaUgal$rOjx>45sdlQs3JXxpM7>{e)uQWuO+w|k2)D?6F^Y`Ihl9$T5u9TK&%tKRu`lkwl5wF zBD7p(eD4q?I%6jcizspgIF5TBP6Wz!aJD>W4=r|~sZ&f7vr~xNGbG{=etZwBeX$7T zZ=&*do}thkcb0~RW^VM>M|X?{a_4OeHPEOtffd&LY*!MIdl!qEK$yv4+H~4wh^a~R zFv#lJHT*(aUImKoV{t=Q>^uN!hMRpMyJl^XK~uolz3m#4@^1&CSafgaA>xtZ5g^Kt z9a6r+9H{}^44^?_m!N?~%O0c%9&3}JG&Ne*rhe!R7 zqGT?9DqvIrYHSg7qE$UEmP;`g?GK~NXB9FO zF5S2?Z5esV-AT1Js!J~fINULYptD>;`+iC`!{ePYIYkowekc%{%*f|11el(34BNlc zn@359m7UtzyrpgRPzdx#x5}A|WlIQo2=;BkPRO6hAWX#&GvY?(UKQrY&9Z2%aIRKY=%9W4tz*_omVbg~afIFCCH z+@1{F`f?C#LEU_SF0)(>eWwN40U$Nd z&%LPjc6Jj`H{dkf_KS3M3K&$iZR};i0EL@Ff~?Gcgjeot4Z;yMuvON{xo&BDV%BnS zB0k!I8(w(2%&xG9vK?P`q_+*Xk!q1VIFwVq!A>S06OAwR(!%A=A2R>O^f$B8 z;rWu&Zx;SvTx)+DTadG)cc}x;`um zQ87P%bCu6F6c?7UnWb2fO}x6fA_Y(x0dY~vAMSy>U<`6QW_wpKAw8;)VYQ0;DPMYV?mj_WvZ8>P=V4GF+9;4 zhLkd|4=NAz&PyI?(MQ({L@?#!_`?MwY(rfe!D0P4dlu<>wg@Pfh-&rvM9iWI}Qs3=$Gf1$=NC05J zUU+90Ibx2!3J-;gvRySjKR=w(_uL<_Pnsg4Q#x8lP0?L0@99nQE4rlF9BYw`8L|kQ zXSXOY!YQ>P7TpV=VPABGt?l!tgtOT;ds^`^2FY-v8X+o-9j*JcBA0&T=?n#Gt@QWH zqWF?kG8+<`>A~;~A)C+AFYRec9ZQt;z0dc#>&^^sRGzz19sZ5aV(S}UdebkjJD-cd zEBQ(tuB#el5+Odi&4}r%-6H~~gj_Vd+9YG&W!LYIy;Wvaf9>R_>FBO) zU)bb+PIj6uf<@Di|Dxw;}amMjRWMp0RmWv)% zP6#;O_e>OEY>Dlgp1V3wma_=g(Aip#cAiij&sQ`+S@J#Sv<ZX#0!Hn&m-MG(GNg{*C!o3IW79Do@gLY8E)EC)zc8H;4CD^)*UY- z&w5w0O@J@`!cLgCZB$uiPithZJZoyNMm@`L%vqoyZ#6w=Bvk>nqHwyUUeqP{e(`0x zKhX2bLUHGeDff62;Q|UjCGERo6WUt8*!U5ZJx0~=h0}e)3{*ujH7aPM2RcaFCEg7} zYxvxUF6SVyvHL>oE8LADokh<+rr7)GH*S@~ff{v-e7Ll8V%fLev6#3@(b`skKB_6JrTZBh0XWT&r*{*h-faBUX z_8rg5OUDcETvyPT>tuDCEs=g4nnFEhNRQLH2_Gq-U*FNryL|WH?2Pkms&z`50R4K1 z%^5`K+aRn;4f;R)q~kvi^Sh_$2bTh34`d%J{X;~RY<@pu)IEpW2=q0TzNLy; zG1GC3v78F7=iR&z`DXxfWfx*-EvgSt^yxwAsgp_!59)y~ZSM>Y7l^+wfhWk32 ziinE10ocsQ$-A@C*cFo_#~}2g(P3u|hH-m+Q6+D*gVcHSkx}Ya%3^_WB|(?jd_c9u z8}O=975l%&m31u$xW&UYTRBRlG{d>S(JJDOg%>-kDq64`oqFI|wR7&B(16cge#vjXz-D8dT7`uIo80zF^$VM#<+y0=t->h_C z)#_=v3@yW+-;4-~-7lF8DYDL7?Ehe>@2qiIw>ppB7@nOv8+2SRhZ^kGHJzLvu0FZ< zWjyxZ(FKox9&HvQvRJ6=k7D^~|74smdr>vN?P=550JMvVe|-XOV@@A7A}Zim^Ci{n ze9tDV+w!@_cyD<@H|giG&ns`}i^V7y#ytzU3Z>lkvIVn=_)K3Fj%$m*ACOu+Tw)#B z_icoZGd3a>X9xF0C~~^=H%0i|+OHc{}Uu@2EBHJ&CWq_d?(^#St(j*#QOPIPrS^ zt`1-;f?X?Hn9MU|u%w#2gjm|&v{?_MD^47%be1KuR+BY}&hV_Lt<5sq2qCVkC0Fmm zTvLA6#x+zzC>&@|)j^Owv2!vgjmoag{cKS5gC$1redv`I2pAU})~+wx91w1$bu$Qv ziA{<1jDZ!DIIh|kb-W76roU5T-#vg?Thy>J_{Wtg&`xi~tY!biP0~7)j`F}>6}Vh3 zIcmPMJsP>33L!d!q}mO&D}l3|@^r$D3ZIuDY=mA(=l{YdC*D)P$IMI7zB$*xpI0yi KsRGHjAO8n6s8*K% diff --git a/cryptofist.png b/cryptofist.png deleted file mode 100644 index ce480a1b59718b6b782054340dc914cc1ed74f0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 202130 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 z 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 OWSOU{pUXO@geCye1EXUA From 185fa019dbb3a6fe962cb8015429a6a9f7d0bc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:29:15 +0200 Subject: [PATCH 007/283] remove .editorconfig file, who added this to the repo? --- .editorconfig | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 11cacc2fa..000000000 --- a/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 4 -charset = utf-8 From bda2308b7853fcc694af296a4994b09788a01d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 22 Sep 2023 14:54:22 +0200 Subject: [PATCH 008/283] remove debugging.md, almost empty file --- docs/debugging.md | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 docs/debugging.md diff --git a/docs/debugging.md b/docs/debugging.md deleted file mode 100644 index 5d9cfd580..000000000 --- a/docs/debugging.md +++ /dev/null @@ -1,2 +0,0 @@ -* compare your conf against `cryptpad/docs/example.nginx.conf` -* From bd62461347d907c88c46af26fda5d4dcac7c130e Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 12 Oct 2023 14:59:17 +0200 Subject: [PATCH 009/283] Fix broken dependencies after merging main --- www/common/common-login.js | 10 +++++----- www/ssoauth/index.html | 2 +- www/ssoauth/main.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/www/common/common-login.js b/www/common/common-login.js index fc45bc643..b9ec62da2 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -1,23 +1,23 @@ define([ 'chainpad-listmap', - '/bower_components/chainpad-crypto/crypto.js', + '/components/chainpad-crypto/crypto.js', '/common/common-util.js', '/common/outer/network-config.js', '/common/common-credential.js', - '/bower_components/chainpad/chainpad.dist.js', + '/components/chainpad/chainpad.dist.js', '/common/common-realtime.js', '/common/common-constants.js', '/common/common-interface.js', '/common/common-feedback.js', '/common/outer/local-store.js', '/customize/messages.js', - '/bower_components/nthen/index.js', + '/components/nthen/index.js', '/common/outer/login-block.js', '/common/common-hash.js', '/common/outer/http-command.js', - '/bower_components/tweetnacl/nacl-fast.min.js', - '/bower_components/scrypt-async/scrypt-async.min.js', // better load speed + '/components/tweetnacl/nacl-fast.min.js', + '/components/scrypt-async/scrypt-async.min.js', // better load speed ], function (Listmap, Crypto, Util, NetConfig, Cred, ChainPad, Realtime, Constants, UI, Feedback, LocalStore, Messages, nThen, Block, Hash, ServerCommand) { var Nacl = window.nacl; diff --git a/www/ssoauth/index.html b/www/ssoauth/index.html index 11e9eb7b7..71677f72b 100644 --- a/www/ssoauth/index.html +++ b/www/ssoauth/index.html @@ -8,7 +8,7 @@ - + diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index 4272d87fa..3c5056ef5 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -12,7 +12,7 @@ define([ '/common/outer/login-block.js', '/customize/messages.js', - '/bower_components/tweetnacl/nacl-fast.min.js', + '/components/tweetnacl/nacl-fast.min.js', ], function (ApiConfig, $, h, Util, Cred, UI, Login, Constants, ServerCommand, LocalStore, Block, Messages) { if (window.top !== window) { return; } From bbb836412975d339e1f5117d5719f8daa20cff7d Mon Sep 17 00:00:00 2001 From: DianaXWiki Date: Thu, 12 Oct 2023 19:43:59 +0300 Subject: [PATCH 010/283] Make userlist and chat go on top of content #1102 --- www/pad/app-pad.less | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less index ffa417143..d7d4cb96d 100644 --- a/www/pad/app-pad.less +++ b/www/pad/app-pad.less @@ -22,6 +22,16 @@ body.cp-app-pad { flex-flow: row; height: 100%; overflow: hidden; + position: relative; + + .cp-toolbar-chat-drawer, .cp-toolbar-userlist-drawer{ + @media screen and (max-width: @browser_media-medium-screen){ + position: absolute; + right: 0; + height: 90%; + + } + } } @media screen and (max-height: @browser_media-medium-screen), @@ -152,6 +162,7 @@ body.cp-app-pad { .cke_toolbar { height: 28px; padding: 2px 0; + display: flex; } .cp-app-pad-wordCount { float: right; @@ -169,6 +180,15 @@ body.cp-app-pad { border-color: @toolbar-bg-active; } .cke_button, .cke_combo_button { + .cke_combo_open{ + display: flex; + flex-flow: row; + .cke_combo_arrow{ + @media (max-width: 360px){ + display:none; + } + } + } .tools_unselectable(); &.cke_button_on, &.cke_combo_button:hover, &.cke_button_off:hover { background-color: @toolbar-bg-active; From d0e80dd11be5a1de6f532bbd24fda4b6cbc55793 Mon Sep 17 00:00:00 2001 From: Guillaume Kulakowski Date: Fri, 13 Oct 2023 17:46:52 +0200 Subject: [PATCH 011/283] Add healthcheck --- Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Dockerfile b/Dockerfile index 0d75a0f24..d3f4c5bde 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,6 +11,11 @@ COPY . /cryptpad RUN sed -i "s@//httpAddress: '::'@httpAddress: '0.0.0.0'@" /cryptpad/config/config.example.js RUN sed -i "s@installMethod: 'unspecified'@installMethod: 'docker'@" /cryptpad/config/config.example.js +# Install wget for healthcheck +RUN apt-get update && apt-get install --no-install-recommends -y wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + # Install dependencies RUN npm install --production \ && npm run install:components @@ -44,6 +49,9 @@ VOLUME /cryptpad/datastore ENTRYPOINT ["/bin/bash", "/cryptpad/docker-entrypoint.sh"] +# Healthcheck +HEALTHCHECK --interval=1m CMD wget --no-verbose --tries=1 http://localhost:3000/ -q -O /dev/null || exit 1 + # Ports EXPOSE 3000 3001 3003 From a8d8c98e9faedebfabf8fb725913c839f4449109 Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Mon, 16 Oct 2023 18:42:19 +0300 Subject: [PATCH 012/283] Add comm modal improvement on small screens #1271 --- www/pad/app-pad.less | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less index d7d4cb96d..4e9734444 100644 --- a/www/pad/app-pad.less +++ b/www/pad/app-pad.less @@ -22,8 +22,6 @@ body.cp-app-pad { flex-flow: row; height: 100%; overflow: hidden; - position: relative; - .cp-toolbar-chat-drawer, .cp-toolbar-userlist-drawer{ @media screen and (max-width: @browser_media-medium-screen){ position: absolute; @@ -82,9 +80,13 @@ body.cp-app-pad { border-color: @cryptpad_color_red; } } + .cp-pad-show { line-height: 0px; } + .h2{ + text-align: center; + } } #cp-app-pad-resize { order: 2; @@ -143,7 +145,7 @@ body.cp-app-pad { } h2 { font-size: 1.5rem; - text-align: right; + text-align: center; } .comments_main(); } @@ -154,6 +156,10 @@ body.cp-app-pad { h2 { text-align: left; } + p.msg{ + overflow: hidden; + align-self: center; + } } .cke_toolbox_main { From e8d719c438f773c6442d7ff17cabfef99e343fab Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 18 Oct 2023 15:39:54 +0200 Subject: [PATCH 013/283] Fix OIDC sso issues --- config/sso.example.js | 3 +- customize.dist/login.js | 4 +- lib/plugins/sso/oidc.js | 54 +++++--- lib/sso-utils.js | 12 +- package-lock.json | 249 +++++++++++++++++++++++++++++++++++++ package.json | 1 + www/common/common-login.js | 2 +- www/ssoauth/main.js | 8 +- 8 files changed, 306 insertions(+), 27 deletions(-) diff --git a/config/sso.example.js b/config/sso.example.js index a1b7289ab..35d1f2b98 100644 --- a/config/sso.example.js +++ b/config/sso.example.js @@ -13,7 +13,8 @@ module.exports = { type: 'oidc', url: 'https://accounts.google.com', client_id: "{your_client_id}", - client_secret: "{your_client_secret}" + client_secret: "{your_client_secret}", + jwt_alg: 'RS256' (optional) } */ ] diff --git a/customize.dist/login.js b/customize.dist/login.js index 60559fc31..0f102023a 100644 --- a/customize.dist/login.js +++ b/customize.dist/login.js @@ -113,8 +113,8 @@ define([ // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed // after hashing the password window.setTimeout(function () { - Exports.loginOrRegister({ - uname, + Login.loginOrRegister({ + uname, passwd, isRegister, onOTP diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js index 8d2d72f3f..380c214b8 100644 --- a/lib/plugins/sso/oidc.js +++ b/lib/plugins/sso/oidc.js @@ -1,14 +1,22 @@ const OID = require('openid-client'); +const SSOUtils = require('../../sso-utils'); const TYPE = 'oidc'; +const opts = SSOUtils.getoptions(); const getClient = (cfg, cb) => { OID.Issuer.discover(cfg.url).then((issuer) => { // XXX Only once for all users? + let alg = cfg.jwt_alg || 'PS256'; + if (Array.isArray(issuer.id_token_signing_alg_values_supported) && + !issuer.id_token_signing_alg_values_supported.includes(alg)) { + alg = issuer.id_token_signing_alg_values_supported[0] || 'RS256'; + } const client = new issuer.Client({ client_id: cfg.client_id, client_secret: cfg.client_secret, - redirect_uris: ['http://localhost:3000/ssoauth'], // XXX Use httpUnsafeOrigin or... + redirect_uris: [opts.callbackURL], response_types: ['code'], + id_token_signed_response_alg: alg }); cb(void 0, client); }, (err) => { @@ -28,8 +36,8 @@ module.exports = { const code_verifier = generators.codeVerifier(); const code_challenge = generators.codeChallenge(code_verifier); const url = client.authorizationUrl({ - scope: 'openid email profile',// https://www.googleapis.com/auth/contacts.readonly', // https://www.google.com/m8/feeds - resource: 'http://localhost:3000/ssoauth/', + scope: 'openid email profile', + resource: opts.callbackURL, access_type: 'offline', code_challenge, code_challenge_method: 'S256', @@ -43,29 +51,35 @@ module.exports = { if (err) { return void cb ('E_OIDC_CONNECT'); } const params = client.callbackParams(url); + delete params.state; client.callback('http://localhost:3000/ssoauth', params, { code_verifier: token }) .then((tokenSet) => { let j = tokenSet; let c = tokenSet.claims(); - cb(void 0, { - id: c.sub, - name: c.name, - idpData: { - expires_at: j.expires_at, - access_token: j.access_token, - refresh_token: j.refresh_token, - //id_token: j.id_token // XXX no need to store id_token? - } + let name = c.name; + const end = () => { + cb(void 0, { + id: c.sub, + name: name, + idpData: { + expires_at: j.expires_at, + access_token: j.access_token, + refresh_token: j.refresh_token, + //id_token: j.id_token // XXX no need to store id_token? + } + }); + }; + if (name) { return void end(); } + let t = client.userinfo(j.access_token).then((data) => { + name = data.name; + end(); + console.log(t); + }, (err) => { + console.error(err); + name = 'Unknown'; // XXX + end(); }); }); }); }, - /* - getData: (Env, cfg, data, cb) => { - // data = { refresh_token, access_token, expires_at } - let t = new OID.TokenSet(data); - // TODO get userinfo using access_token - // use refresh_token if access expired - } - */ }; diff --git a/lib/sso-utils.js b/lib/sso-utils.js index 9a6a069fb..61db7eb73 100644 --- a/lib/sso-utils.js +++ b/lib/sso-utils.js @@ -3,14 +3,24 @@ const Sessions = require("./storage/sessions"); const Nacl = require("tweetnacl/nacl-fast"); const JWT = require("jsonwebtoken"); const Util = require("./common-util"); +const config = require("./lib/load-config"); const SSOUtils = module.exports; const SESSION_EXPIRATIION = 12 * 3600 * 1000; // XXX Hours? Days? Weeks? Configurable? + + +SSOUtils.getOptions = () => { + return { + callbackURL: config.httpUnsafeOrigin + '/ssoauth' + }; +}; + // XXX const SAML = require('node-saml'); // https://www.npmjs.com/package/node-saml const TYPES = SSOUtils.TYPES = { - oidc: require('./plugins/sso/oidc') + oidc: require('./plugins/sso/oidc'), + saml: require('./plugins/sso/saml') }; const checkConfig = SSOUtils.checkConfig = (Env) => { diff --git a/package-lock.json b/package-lock.json index a13c658a4..0f4c0c109 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "AGPL-3.0+", "dependencies": { "@mcrowe/minibloom": "^0.2.0", + "@node-saml/node-saml": "^4.0.5", "alertify.js": "1.0.11", "bootstrap": "^4.0.0", "bootstrap-tokenfield": "^0.12.0", @@ -88,6 +89,48 @@ "node": ">=4" } }, + "node_modules/@node-saml/node-saml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@node-saml/node-saml/-/node-saml-4.0.5.tgz", + "integrity": "sha512-J5DglElbY1tjOuaR1NPtjOXkXY5bpUhDoKVoeucYN98A3w4fwgjIOPqIGcb6cQsqFq2zZ6vTCeKn5C/hvefSaw==", + "dependencies": { + "@types/debug": "^4.1.7", + "@types/passport": "^1.0.11", + "@types/xml-crypto": "^1.4.2", + "@types/xml-encryption": "^1.2.1", + "@types/xml2js": "^0.4.11", + "@xmldom/xmldom": "^0.8.6", + "debug": "^4.3.4", + "xml-crypto": "^3.0.1", + "xml-encryption": "^3.0.2", + "xml2js": "^0.5.0", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@node-saml/node-saml/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@node-saml/node-saml/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/@nodelib/fs.stat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", @@ -97,6 +140,53 @@ "node": ">= 6" } }, + "node_modules/@types/body-parser": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.4.tgz", + "integrity": "sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.37.tgz", + "integrity": "sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", + "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", + "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.38", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.38.tgz", + "integrity": "sha512-hXOtc0tuDHZPFwwhuBJXPbjemWtXnJjbvuuyNH2Y5Z6in+iXc63c4eXYDc7GGGqHy+iwYqAJMdaItqdnbcBKmg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -107,6 +197,11 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.3.tgz", + "integrity": "sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==" + }, "node_modules/@types/http-proxy": { "version": "1.17.12", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.12.tgz", @@ -115,17 +210,89 @@ "@types/node": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", + "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==" + }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.33", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", + "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==" + }, "node_modules/@types/node": { "version": "20.6.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==" }, + "node_modules/@types/passport": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.14.tgz", + "integrity": "sha512-D6p2ygR2S7Cq5PO7iUaEIQu/5WrM0tONu6Lxgk0C9r3lafQIlVpWCo3V/KI9To3OqHBxcfQaOeK+8AvwW5RYmw==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.6.tgz", + "integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==" + }, + "node_modules/@types/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", + "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", + "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/xml-crypto": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/xml-crypto/-/xml-crypto-1.4.3.tgz", + "integrity": "sha512-pnvKYb7vUsUIMc+C6JM/j779YWQgOMcwjnqHJ9cdaWXwWEBE1hAqthzeszRx62V5RWMvS+XS9w9tXMOYyUc8zg==", + "dependencies": { + "@types/node": "*", + "xpath": "0.0.27" + } + }, + "node_modules/@types/xml-encryption": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/xml-encryption/-/xml-encryption-1.2.2.tgz", + "integrity": "sha512-UeuYOqW3ZzUQfwb/mb3GNZ2/DlVdh5mjJNmB/yFXgQr8/pwlVJ9I2w+AHPfRDzLshe7YpgUB4T1//qgbk6U87Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/xml2js": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.12.tgz", + "integrity": "sha512-CZPpQKBZ8db66EP5hCjwvYrLThgZvnyZrPXK2W+UI1oOaWezGt34iOaUCX4Jah2X8+rQqjvl9VKEIT8TR1I0rA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -3939,6 +4106,11 @@ "resolved": "https://registry.npmjs.org/saferphore/-/saferphore-0.0.1.tgz", "integrity": "sha512-/KaXQyumYbALQwhl4/Qov6voayHwtBD12AWRI3zxYBW7cY3Mjtkk7PLttZPq+25nyfu/k3APHUptPLZI9A7yHA==" }, + "node_modules/sax": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + }, "node_modules/scrypt-async": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-1.2.0.tgz", @@ -4869,6 +5041,83 @@ "node": "*" } }, + "node_modules/xml-crypto": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-3.2.0.tgz", + "integrity": "sha512-qVurBUOQrmvlgmZqIVBqmb06TD2a/PpEUfFPgD7BuBfjmoH4zgkqaWSIJrnymlCvM2GGt9x+XtJFA+ttoAufqg==", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "xpath": "0.0.32" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml-crypto/node_modules/xpath": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/xml-encryption": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/xml-encryption/-/xml-encryption-3.0.2.tgz", + "integrity": "sha512-VxYXPvsWB01/aqVLd6ZMPWZ+qaj0aIdF+cStrVJMcFj3iymwZeI0ABzB3VqMYv48DkSpRhnrXqTUkR34j+UDyg==", + "dependencies": { + "@xmldom/xmldom": "^0.8.5", + "escape-html": "^1.0.3", + "xpath": "0.0.32" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/xml-encryption/node_modules/xpath": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz", + "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==", + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==", + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index 58278be02..9cba9046e 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "notp": "^2.0.3", "nthen": "0.1.8", "openid-client": "^5.4.2", + "@node-saml/node-saml": "^4.0.5", "prompt-confirm": "^2.0.4", "pull-stream": "^3.6.1", "saferphore": "0.0.1", diff --git a/www/common/common-login.js b/www/common/common-login.js index b9ec62da2..d2776dcb7 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -301,7 +301,6 @@ define([ register: isRegister, uname: uname }; - if (ssoAuth && ssoAuth.name) { uname = res.uname = ssoAuth.name; } var RT, blockKeys, blockUrl; @@ -312,6 +311,7 @@ define([ res.opt = allocateBytes(bytes); res.blockHash = res.opt.blockHash; blockKeys = res.opt.blockKeys; + if (ssoAuth && ssoAuth.name) { uname = res.uname = ssoAuth.name; } })); }).nThen(function (waitFor) { // the allocated bytes can be used either in a legacy fashion, diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index 3c5056ef5..758e823ce 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -51,8 +51,12 @@ define([ } }, function (err) { if (err) { - console.error(err); - return void UI.warn(Messages.error); + UI.removeLoadingScreen(); + var msg = Messages.error; + if (err === 'NO_SUCH_USER') { msg = Messages.drive_sfPasswordError; } + let $button = $('button#cp-ssoauth-button'); + $button.prop('disabled', ''); + return void UI.warn(msg); } window.location.href = '/drive/'; }); From 9b367a0468b8a5353d81211f559ff532ad227f89 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 18 Oct 2023 18:20:49 +0200 Subject: [PATCH 014/283] SSO SAML test --- lib/http-worker.js | 17 +++++++++++++ lib/plugins/sso/oidc.js | 2 +- lib/plugins/sso/saml.js | 49 +++++++++++++++++++++++++++++++++++++ lib/sso-utils.js | 2 +- package-lock.json | 54 +++++++++++++++++++++++++++++++++++------ package.json | 1 + 6 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 lib/plugins/sso/saml.js diff --git a/lib/http-worker.js b/lib/http-worker.js index 29acf13fa..c86b1df2c 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -11,6 +11,7 @@ const MFA = require("./storage/mfa"); const SSOUtils = require("./sso-utils"); const Sessions = require("./storage/sessions"); const cookieParser = require("cookie-parser"); +const bodyParser = require('body-parser'); const BlobStore = require("./storage/blob"); const BlockStore = require("./storage/block"); @@ -161,6 +162,10 @@ var setHeaders = function (req, res) { const Express = require("express"); var app = Express(); + +app.use(bodyParser.urlencoded({ + extended: true +})); app.use(cookieParser()); (function () { @@ -198,6 +203,17 @@ const wsProxy = createProxyMiddleware({ app.use('/cryptpad_websocket', wsProxy); +app.use('/ssoauth', (req, res, next) => { + console.log(req.body.SAMLResponse); + req.method = 'GET'; + //res.sendFile(__dirname + '/../www' + req.url + '/index.html'); + // XXX XXX XXX + // Here, redirect to /ssoauth with params? + // Check how we can handle data in the client + next(); +}); + + app.use('/blob', function (req, res, next) { /* Head requests are used to check the size of a blob. Clients can configure a maximum size to download automatically, @@ -262,6 +278,7 @@ app.use(function (req, res, next) { next(); }); + // serve custom app content from the customize directory // useful for testing pages customized with opengraph data app.use(Express.static(Path.resolve('./customize/www'))); diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js index 380c214b8..73e16d03a 100644 --- a/lib/plugins/sso/oidc.js +++ b/lib/plugins/sso/oidc.js @@ -3,7 +3,7 @@ const SSOUtils = require('../../sso-utils'); const TYPE = 'oidc'; -const opts = SSOUtils.getoptions(); +const opts = SSOUtils.getOptions(); const getClient = (cfg, cb) => { OID.Issuer.discover(cfg.url).then((issuer) => { // XXX Only once for all users? let alg = cfg.jwt_alg || 'PS256'; diff --git a/lib/plugins/sso/saml.js b/lib/plugins/sso/saml.js new file mode 100644 index 000000000..e376af735 --- /dev/null +++ b/lib/plugins/sso/saml.js @@ -0,0 +1,49 @@ +const { SAML } = require('@node-saml/node-saml'); +const SSOUtils = require('../../sso-utils'); + +const TYPE = 'saml'; + +/* +// XXX XXX XXX SAML TEST + +* get metadata with "saml.generateServiceProviderMetadata()" +* test site: https://samltest.id/upload.php + * upload metadata there +* redirected to cryptpad with a POST to /ssoauth handled in http-worker.js + + + + + +*/ + + + +const opts = SSOUtils.getOptions(); +const getClient = (cfg, cb) => { + console.log(SAML); + const saml = new SAML({ + callbackUrl: opts.callbackURL, + entryPoint: cfg.url, + issuer: cfg.issuer, + cert: cfg.cert, + }); + cb(void 0, saml); +}; +module.exports = { + type: TYPE, + checkConfig: (cfg) => { + return cfg.url && cfg.issuer && cfg.cert; + }, + auth: (Env, cfg, cb) => { + getClient(cfg, (err, client) => { + if (err) { return void cb ('E_OIDC_CONNECT'); } + client.getAuthorizeUrlAsync().then((url) => { + console.log(url); // XXX XXX XXX write_request not useful here? + cb(void 0, { url: url/*, token: code_verifier*/ }); + }); + }); + }, + authCb: (Env, cfg, token, url, cb) => { + }, +}; diff --git a/lib/sso-utils.js b/lib/sso-utils.js index 61db7eb73..795c5f5a2 100644 --- a/lib/sso-utils.js +++ b/lib/sso-utils.js @@ -3,7 +3,7 @@ const Sessions = require("./storage/sessions"); const Nacl = require("tweetnacl/nacl-fast"); const JWT = require("jsonwebtoken"); const Util = require("./common-util"); -const config = require("./lib/load-config"); +const config = require("./load-config"); const SSOUtils = module.exports; diff --git a/package-lock.json b/package-lock.json index 0f4c0c109..8b0b3081c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@mcrowe/minibloom": "^0.2.0", "@node-saml/node-saml": "^4.0.5", "alertify.js": "1.0.11", + "body-parser": "^1.20.2", "bootstrap": "^4.0.0", "bootstrap-tokenfield": "^0.12.0", "chainpad": "^5.2.6", @@ -850,12 +851,12 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -863,7 +864,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -1753,6 +1754,43 @@ "node": ">= 0.10.0" } }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -3876,9 +3914,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", diff --git a/package.json b/package.json index 9cba9046e..3eea3fdbf 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "chainpad-crypto": "^0.2.5", "chainpad-server": "^5.1.0", "cookie-parser": "^1.4.6", + "body-parser": "^1.20.2", "express": "~4.18.2", "fs-extra": "^7.0.0", "get-folder-size": "^2.0.1", From 49f6b69db50abf4a5d3520509db8837a63835b3a Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 20 Oct 2023 18:20:31 +0200 Subject: [PATCH 015/283] SAML SSO login/registration --- lib/challenge-commands/sso.js | 8 +++++--- lib/http-worker.js | 25 ++++++++++++++++++++----- lib/plugins/sso/oidc.js | 2 +- lib/plugins/sso/saml.js | 31 +++++++++++++++++++++++++++---- lib/sso-utils.js | 4 ++-- 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/lib/challenge-commands/sso.js b/lib/challenge-commands/sso.js index 51818d23b..72a324432 100644 --- a/lib/challenge-commands/sso.js +++ b/lib/challenge-commands/sso.js @@ -29,7 +29,9 @@ auth.complete = function (Env, body, cb, req, res) { idp.auth(Env, cfg, (err, obj) => { if (err) { return void cb(err); } // TODO log - const { url, token } = obj; + let { url, token } = obj; + + if (!token) { token = Util.uid() + Util.uid(); } SSOUtils.writeRequest(Env, { id: token, @@ -59,7 +61,7 @@ const authCb = Commands.SSO_AUTH_CB = function (Env, body, cb, req) { if (err) { return void cb('ENOENT'); } const data = Util.tryParse(value); if (!data || !data.type || !TYPES[data.type]) { return void cb('INVALID_REQUEST_DATA'); } - if (publicKey !== data.publicKey) { return void cb('WRONG_SIGNATURE_KEYS'); } + if (data.type !== 'saml' && publicKey !== data.publicKey) { return void cb('WRONG_SIGNATURE_KEYS'); } cb(); }); }; @@ -77,7 +79,7 @@ authCb.complete = function (Env, body, cb, req) { const idp = TYPES[data.type]; const register = data.register; const provider = data.provider; - idp.authCb(Env, cfg, ssotoken, url, (err, obj) => { + idp.authCb(Env, cfg, ssotoken, url, cookies, (err, obj) => { if (err) { return void cb(err); } const {id, idpData, name} = obj; diff --git a/lib/http-worker.js b/lib/http-worker.js index c86b1df2c..90b0babfe 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -205,11 +205,26 @@ app.use('/cryptpad_websocket', wsProxy); app.use('/ssoauth', (req, res, next) => { console.log(req.body.SAMLResponse); - req.method = 'GET'; - //res.sendFile(__dirname + '/../www' + req.url + '/index.html'); - // XXX XXX XXX - // Here, redirect to /ssoauth with params? - // Check how we can handle data in the client + if (req && req.body && req.body.SAMLResponse) { + req.method = 'GET'; + + let token = Util.uid(); + let smres = req.body.SAMLResponse; + return SSOUtils.writeRequest(Env, { + id: token, + type: 'saml', + content: smres + }, (err) => { + if (err) { + Log.error('E_SSO_WRITE_REQ', err); + return res.sendStatus(500); + } + let value = `samltoken="${token}"; SameSite=Strict; HttpOnly`; + res.setHeader('Set-Cookie', value); + next(); + }); + + } next(); }); diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js index 73e16d03a..5fc8bc052 100644 --- a/lib/plugins/sso/oidc.js +++ b/lib/plugins/sso/oidc.js @@ -46,7 +46,7 @@ module.exports = { cb(void 0, { url: url, token: code_verifier }); }); }, - authCb: (Env, cfg, token, url, cb) => { + authCb: (Env, cfg, token, url, cookies, cb) => { getClient(cfg, (err, client) => { if (err) { return void cb ('E_OIDC_CONNECT'); } diff --git a/lib/plugins/sso/saml.js b/lib/plugins/sso/saml.js index e376af735..7f7d7edfb 100644 --- a/lib/plugins/sso/saml.js +++ b/lib/plugins/sso/saml.js @@ -1,5 +1,6 @@ const { SAML } = require('@node-saml/node-saml'); const SSOUtils = require('../../sso-utils'); +const Util = require("../../common-util"); const TYPE = 'saml'; @@ -17,11 +18,11 @@ const TYPE = 'saml'; */ +const nameRef = 'urn:oid:2.16.840.1.113730.3.1.241'; const opts = SSOUtils.getOptions(); const getClient = (cfg, cb) => { - console.log(SAML); const saml = new SAML({ callbackUrl: opts.callbackURL, entryPoint: cfg.url, @@ -39,11 +40,33 @@ module.exports = { getClient(cfg, (err, client) => { if (err) { return void cb ('E_OIDC_CONNECT'); } client.getAuthorizeUrlAsync().then((url) => { - console.log(url); // XXX XXX XXX write_request not useful here? - cb(void 0, { url: url/*, token: code_verifier*/ }); + cb(void 0, { url: url }); }); }); }, - authCb: (Env, cfg, token, url, cb) => { + authCb: (Env, cfg, token, url, cookies, cb) => { + const samltoken = cookies.samltoken; + if (!samltoken) { return void cb('NO_COOKIE'); } + SSOUtils.readRequest(Env, samltoken, (err, value) => { + SSOUtils.deleteRequest(Env, samltoken); + if (err || !value) { return void cb('EINVAL'); } + const data = Util.tryParse(value); + + getClient(cfg, (err, client) => { + if (err) { return void cb ('E_OIDC_CONNECT'); } + client.validatePostResponseAsync({ + SAMLResponse: data.content + }).then((data) => { + if (!data || data.loggedOut || !data.profile || !data.profile.nameID) { + return void cb('EINVAL'); + } + cb(void 0, { + id: data.profile.nameID, + name: data.profile[nameRef] || data.profile.nameID, + idpData: {} + }); + }); + }); + }); }, }; diff --git a/lib/sso-utils.js b/lib/sso-utils.js index 795c5f5a2..b1fa2f8f6 100644 --- a/lib/sso-utils.js +++ b/lib/sso-utils.js @@ -26,7 +26,7 @@ const TYPES = SSOUtils.TYPES = { const checkConfig = SSOUtils.checkConfig = (Env) => { return Env && Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && Env.sso.list.length; }; -const getProviderConfig = SSOUtils.getProviderConfig = (Env, provider) => { +SSOUtils.getProviderConfig = (Env, provider) => { if (!checkConfig(Env)) { return; } if (!provider) { return; } const data = Env.sso.list.find((cfg) => { return cfg.name === provider; }); @@ -61,11 +61,11 @@ SSOUtils.writeRequest = (Env, data, cb) => { publicKey: data.publicKey, time: +new Date() }; + if (data.content) { value.content = data.content; } SSO.request.write(Env, id, JSON.stringify(value), cb); }; - SSOUtils.writeUser = (Env, provider, id, cb) => { const seed = Nacl.util.encodeBase64(Nacl.randomBytes(24)); SSO.user.write(Env, provider, id, JSON.stringify({ From 3bf045ce001382e9881fbbf389695b2a50380145 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 23 Oct 2023 14:44:18 +0200 Subject: [PATCH 016/283] enabled flatpickr on mobile --- www/form/inner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/form/inner.js b/www/form/inner.js index 624ce7d50..b3ebcbb19 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4787,6 +4787,7 @@ define([ // Otherwise add it var datePicker = h('input'); var picker = Flatpickr(datePicker, { + disableMobile: true, enableTime: true, time_24hr: is24h, dateFormat: dateFormat, From 2f67beff1c6853283c00961427fca5674435d2b1 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Tue, 24 Oct 2023 15:28:16 +0200 Subject: [PATCH 017/283] changed positioning of kanban tag container on smaller screen widths --- www/kanban/app-kanban.less | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/www/kanban/app-kanban.less b/www/kanban/app-kanban.less index 9e1a80ac5..b3f37bbef 100644 --- a/www/kanban/app-kanban.less +++ b/www/kanban/app-kanban.less @@ -426,7 +426,9 @@ position: relative; min-height: 50px; .cp-kanban-filterTags { - display: inline-flex; + @media (min-width: 505px) { + display: inline-flex; + } align-items: center; flex: 1; //max-width: 80%; @@ -434,6 +436,9 @@ .cp-kanban-filterTags-toggle { min-width: 100px; display: flex; + @media (max-width: 505px) { + margin-left: 10px; + } flex-flow: column; flex-shrink: 0; & > * { From ee7373e4d9ed240d14ef1d461b8dcf566af56b46 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Tue, 24 Oct 2023 22:04:25 +0200 Subject: [PATCH 018/283] fixed poll time option flatpickr on mobile --- www/form/app-form.less | 3 +++ www/form/inner.js | 1 + 2 files changed, 4 insertions(+) diff --git a/www/form/app-form.less b/www/form/app-form.less index e4a75a2aa..7783aba12 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -774,6 +774,9 @@ &.sortable-drag { opacity: 0.9 !important; } display: flex; width: 400px; + @media (max-width:460px) { + width: 300px + } input { flex: 1; min-width: 100px; diff --git a/www/form/inner.js b/www/form/inner.js index b3ebcbb19..2ece04dc2 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -297,6 +297,7 @@ define([ if (v.type && v.type !== 'text') { if (v.type === 'time') { Flatpickr(input, { + disableMobile: true, enableTime: true, time_24hr: is24h, dateFormat: dateFormat, From 5d83cf34275810de20d22a599821e363ebbf824b Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:40:59 +0300 Subject: [PATCH 019/283] Delete unnecessary stuff+reduce padding for comm --- www/pad/app-pad.less | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less index 4e9734444..3ecaf13da 100644 --- a/www/pad/app-pad.less +++ b/www/pad/app-pad.less @@ -84,9 +84,6 @@ body.cp-app-pad { .cp-pad-show { line-height: 0px; } - .h2{ - text-align: center; - } } #cp-app-pad-resize { order: 2; @@ -157,8 +154,11 @@ body.cp-app-pad { text-align: left; } p.msg{ - overflow: hidden; align-self: center; + padding: 0; + } + .dialog.nav{ + padding: 10px; } } From 58b0f5042298d54763c1d75865292e0a72c4adb3 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 25 Oct 2023 23:17:49 +0200 Subject: [PATCH 020/283] fixing poll input issues --- www/form/inner.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 2ece04dc2..42f103bdf 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -258,7 +258,9 @@ define([ }, content: Messages['form_poll_'+t] }; + }); + var dropdownConfig = { text: '', // Button initial text options: options, // Entries displayed in the menu @@ -294,7 +296,7 @@ define([ if (uid) { $input.data('uid', uid); } // If the input is a date, initialize flatpickr - if (v.type && v.type !== 'text') { + if (v.type === 'time') { Flatpickr(input, { disableMobile: true, @@ -303,12 +305,7 @@ define([ dateFormat: dateFormat, defaultDate: val ? new Date(val) : undefined }); - } else if (v.type === 'day') { - /*Flatpickr(input, { - defaultDate: val ? new Date(val) : undefined - });*/ - } - } + } // if this element was active before the remote change, restore cursor var setCursor = function () { @@ -499,7 +496,8 @@ define([ } else { $(addMultiple).hide(); } - } else { + } + else { $(addMultiple).hide(); $calendar.show(); $container.hide(); @@ -515,6 +513,7 @@ define([ setTimeout(evOnSave.fire); if (val !== "text") { $container.find('.cp-form-edit-block-input').remove(); + if (val === "time") { var time = new Date(); time.setHours(14); @@ -525,11 +524,12 @@ define([ $add.before(el); $(el).find('input').focus(); return; - } + } $(add).click(); return; } $container.find('input').each(function (i, input) { + $container.find('input')[0].value = '' if (input._flatpickr) { input._flatpickr.destroy(); delete input._flatpickr; @@ -2532,6 +2532,7 @@ define([ poll: { defaultOpts: { type: 'text', // Text or Days or Time + values: [1, 2, 3].map(function (i) { return { uid: Util.uid(), @@ -2619,6 +2620,7 @@ define([ }, edit: function (cb, tmp) { var v = Util.clone(opts); + return editOptions(v, isDefaultOpts, setCursorGetter, cb, tmp); }, getCursor: function () { return cursorGetter(); }, From 7d3f67cd864fee183d922fd5ffad86a22801f4a9 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 26 Oct 2023 17:55:54 +0200 Subject: [PATCH 021/283] SSO + OTP account deletion and password change --- lib/archive-account.js | 11 +++++ lib/challenge-commands/base.js | 13 +++++- lib/challenge-commands/sso.js | 82 ++++++++++++++++++++++++++++++--- lib/challenge-commands/totp.js | 50 +++++++++++++++----- lib/commands/admin-rpc.js | 6 +++ lib/commands/block.js | 13 ++++++ lib/http-commands.js | 7 +-- lib/http-worker.js | 8 ++-- lib/sso-utils.js | 64 ++++++++++++++++++++++--- lib/storage/basic.js | 16 ++++++- lib/storage/sessions.js | 13 ++++++ lib/storage/sso.js | 29 +++++++++++- www/common/common-constants.js | 1 + www/common/common-login.js | 31 +++++++++---- www/common/cryptpad-common.js | 28 ++++++++++- www/common/outer/async-store.js | 2 + www/common/outer/local-store.js | 10 +++- www/common/outer/login-block.js | 16 ++++++- www/settings/inner.js | 29 ++++++++++-- www/settings/main.js | 12 ++++- www/ssoauth/main.js | 1 + 21 files changed, 389 insertions(+), 53 deletions(-) diff --git a/lib/archive-account.js b/lib/archive-account.js index b714bffed..56d90ba7f 100644 --- a/lib/archive-account.js +++ b/lib/archive-account.js @@ -9,6 +9,7 @@ const Core = require("./commands/core"); const Metadata = require("./commands/metadata"); const Meta = require("./metadata"); const Logger = require("./log"); +const SSOUtils = require('./sso-utils'); const Path = require("path"); const Fse = require("fs-extra"); @@ -196,6 +197,11 @@ COMMANDS.start = (edPublic, blockId, reason) => { } Log.info('MODERATION_ACCOUNT_BLOCK', safeKey, waitFor()); })); + SSOUtils.deleteAccount(Env, blockId, waitFor((err) => { + if (err) { + return Log.error('MODERATION_ACCOUNT_BLOCK_SSO', err, waitFor()); + } + })); })); }).nThen((waitFor) => { var report = { @@ -285,6 +291,11 @@ COMMANDS.restore = (edPublic) => { } Log.info('MODERATION_ACCOUNT_BLOCK_RESTORE', safeKey, waitFor()); })); + SSOUtils.restoreAccount(Env, blockId, waitFor(function (err) { + if (err) { + return Log.error('MODERATION_ACCOUNT_BLOCK_RESTORE_SSO', err, waitFor()); + } + })); })); }).nThen((waitFor) => { deleteReport(Env, safeKey, waitFor((err) => { diff --git a/lib/challenge-commands/base.js b/lib/challenge-commands/base.js index a1c55ff3f..d7fe3536b 100644 --- a/lib/challenge-commands/base.js +++ b/lib/challenge-commands/base.js @@ -1,6 +1,7 @@ const Block = require("../commands/block"); const MFA = require("../storage/mfa"); const Util = require("../common-util"); +const Sessions = require("../storage/sessions"); const Commands = module.exports; @@ -51,8 +52,16 @@ const writeBlock = Commands.WRITE_BLOCK = function (Env, body, cb) { }; writeBlock.complete = function (Env, body, cb) { - const { content } = body; - Block.writeLoginBlock(Env, content, cb); + const { publicKey, content, session } = body; + Block.writeLoginBlock(Env, content, (err) => { + if (err) { return void cb(err); } + + if (!session) { return void cb(); } + + const proof = Util.tryParse(content.registrationProof); + const oldKey = proof && proof[0]; + Sessions.update(Env, publicKey, oldKey, session, "", cb); + }); }; // Remove a login block IFF diff --git a/lib/challenge-commands/sso.js b/lib/challenge-commands/sso.js index 72a324432..fe1dcf266 100644 --- a/lib/challenge-commands/sso.js +++ b/lib/challenge-commands/sso.js @@ -164,8 +164,8 @@ register.complete = function (Env, body, cb) { ssoUser = user; })); }).nThen((w) => { - const { sub } = payload; - SSOUtils.writeBlock(Env, publicKey, sub, w((err) => { + const { sub, provider } = payload; + SSOUtils.writeBlock(Env, publicKey, provider, sub, w((err) => { if (err) { w.abort(); return void cb('SSO_BLOCK_WRITE'); @@ -181,8 +181,10 @@ register.complete = function (Env, body, cb) { ssoUser.complete = true; SSOUtils.updateUser(Env, provider, sub, ssoUser, w()); }).nThen(() => { - const { data, provider } = payload; - SSOUtils.makeSession(Env, publicKey, provider, data, cb); + const { data, sub, provider } = payload; + let session = Util.clone(data); + session.id = sub; + SSOUtils.makeSession(Env, publicKey, provider, session, cb); }); }; @@ -228,8 +230,74 @@ login.complete = function (Env, body, cb) { } })); }).nThen(() => { - const { data, provider } = payload; - SSOUtils.makeSession(Env, publicKey, provider, data, cb); + const { data, sub, provider } = payload; + let session = Util.clone(data); + session.id = sub; + SSOUtils.makeSession(Env, publicKey, provider, session, cb); + }); +}; + +const update = Commands.SSO_UPDATE_BLOCK = function (Env, body, cb) { + const { publicKey, ancestorProof } = body; + + // they must provide a valid block public key + if (!Block.isValidBlockId(publicKey)) { return void cb("INVALID_KEY"); } + + let oldKey; + nThen((w) => { + BlockStore.isAvailable(Env, publicKey, w((err, result) => { + if (err && !result) { + w.abort(); + return void cb(err); + } + // Block found: next + })); + }).nThen((w) => { + Block.validateAncestorProof(Env, ancestorProof, w((err, provenKey) => { + if (err) { + w.abort(); + return void cb(err); + } + // Ancestor found and proven + oldKey = provenKey; + })); + }).nThen(() => { + SSOUtils.readBlock(Env, oldKey, (err) => { + if (err) { + return void cb('INVALID_OLD_BLOCK'); + } + cb(); + }); + }); +}; +update.complete = function (Env, body, cb) { + const { publicKey, ancestorProof } = body; + + // We've already proven that the "proof" is valid so we can extract its key + const proof = Util.tryParse(ancestorProof); + const oldKey = proof && proof[0]; + + let oldBlock; + nThen((w) => { + SSOUtils.readBlock(Env, oldKey, w((err, data) => { + if (err || !data) { + w.abort(); + return void cb('INVALID_OLD_BLOCK'); + } + if (!data.id) { + w.abort(); + return void cb('INVALID_SSO_BLOCK_CONTENT'); + } + oldBlock = data; + })); + }).nThen((w) => { + SSOUtils.writeBlock(Env, publicKey, oldBlock.provider, oldBlock.id, w((err) => { + if (err) { + w.abort(); + return void cb('SSO_UPDATE_BLOCK_WRITE'); + } + })); + }).nThen(() => { + cb(); }); - }; diff --git a/lib/challenge-commands/totp.js b/lib/challenge-commands/totp.js index 21a070895..b0761ca44 100644 --- a/lib/challenge-commands/totp.js +++ b/lib/challenge-commands/totp.js @@ -8,6 +8,7 @@ const MFA = require("../storage/mfa"); const Sessions = require("../storage/sessions"); const BlockStore = require("../storage/block"); const Block = require("../commands/block"); +const SSOUtils = require("../sso-utils"); const Commands = module.exports; @@ -62,16 +63,35 @@ var decode32 = S => { var EXPIRATION = 7 * 24 * 3600 * 1000; // Sessions are valid 7 days // Create a session with a token for the given public key -const makeSession = (Env, publicKey, cb) => { - const sessionId = Sessions.randomId(); +const makeSession = (Env, publicKey, oldKey, ssoSession, cb) => { + const sessionId = ssoSession || Sessions.randomId(); + + // 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 + oldKey = oldKey || publicKey; // use the current block if no old key + + let isUpdate = false; nThen(function (w) { + if (!ssoSession) { return; } + // If we have an session token, confirm this is an sso account + SSOUtils.readBlock(Env, oldKey, w((err) => { + if (err === 'ENOENT') { return; } // No sso block, no need to update the session + if (err) { + w.abort(); + return void cb('TOTP_VALIDATE_READ_SSO'); + } + // We have an existing session for an SSO account: update the existing session + isUpdate = true; + })); + }).nThen(function (w) { // store the token - Sessions.write(Env, publicKey, sessionId, JSON.stringify({ + let sessionData = { mfa: { type: 'otp', exp: (+new Date()) + EXPIRATION } - }), w(function (err) { + }; + var then = w(function (err) { if (err) { Env.Log.error("TOTP_VALIDATE_SESSION_WRITE", { error: Util.serializeError(err), @@ -82,7 +102,12 @@ const makeSession = (Env, publicKey, cb) => { return void cb("SESSION_WRITE_ERROR"); } // else continue - })); + }); + if (isUpdate) { + Sessions.update(Env, publicKey, oldKey, sessionId, JSON.stringify(sessionData), then); + } else { + Sessions.write(Env, publicKey, sessionId, JSON.stringify(sessionData), then); + } }).nThen(function () { cb(void 0, { bearer: sessionId, @@ -203,7 +228,7 @@ const TOTP_SETUP = Commands.TOTP_SETUP = function (Env, body, cb) { // There's still a little bit more to do and it could still fail. TOTP_SETUP.complete = function (Env, body, cb) { // the OTP code should have already been validated - var { publicKey, secret, contact } = body; + var { publicKey, secret, contact, session } = body; // the device from which they configure MFA settings // is assumed to be safe, so we'll respond with a JWT token @@ -253,7 +278,7 @@ TOTP_SETUP.complete = function (Env, body, cb) { // we have already stored the MFA data, which will cause access to the resource to be restricted to the provided TOTP secret. // we attempt to create a session as a matter of convenience - so if it fails // that just means they'll be forced to authenticate - makeSession(Env, publicKey, cb); + makeSession(Env, publicKey, null, session, cb); }); }; @@ -301,8 +326,8 @@ So, we should: 2. send them the token */ - var { publicKey } = body; - makeSession(Env, publicKey, cb); + var { publicKey, session } = body; + makeSession(Env, publicKey, null, session, cb); }; // Same as TOTP_VALIDATE but without making a session at the end @@ -432,7 +457,8 @@ const writeBlock = Commands.TOTP_WRITE_BLOCK = function (Env, body, cb) { writeBlock.complete = function (Env, body, cb) { - const { publicKey, content } = body; + const { publicKey, content, session } = body; + let oldKey; nThen(function (w) { // Write new block Block.writeLoginBlock(Env, content, w((err) => { @@ -444,7 +470,7 @@ writeBlock.complete = function (Env, body, cb) { }).nThen(function (w) { // Copy MFA settings const proof = Util.tryParse(content.registrationProof); - const oldKey = proof && proof[0]; + oldKey = proof && proof[0]; if (!oldKey) { w.abort(); return void cb('INVALID_ANCESTOR'); @@ -452,7 +478,7 @@ writeBlock.complete = function (Env, body, cb) { MFA.copy(Env, oldKey, publicKey, w()); }).nThen(function () { // Create a session for the current user - makeSession(Env, publicKey, cb); + makeSession(Env, publicKey, oldKey, session, cb); }); }; diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 512fd001b..4e9ed319e 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -11,6 +11,7 @@ const Channel = require("./channel"); const BlockStore = require("../storage/block"); const MFA = require("../storage/mfa"); const ArchiveAccount = require('../archive-account'); +const SSOUtils = require("../sso-utils"); /* jshint ignore:start */ const { Worker } = require('node:worker_threads'); /* jshint ignore:end */ @@ -722,6 +723,7 @@ var archiveBlock = function (Env, Server, cb, data) { }); cb(err); }); + SSOUtils.deleteAccount(Env, key, () => {}); }; var restoreArchivedBlock = function (Env, Server, cb, data) { @@ -736,6 +738,10 @@ var restoreArchivedBlock = function (Env, Server, cb, data) { key: key, reason: reason || '', }); + + // Also restore SSO data + SSOUtils.restoreAccount(Env, key, () => {}); + cb(err); }); }; diff --git a/lib/commands/block.js b/lib/commands/block.js index ca4a77e1e..2fffb998a 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -5,6 +5,7 @@ const Nacl = require("tweetnacl/nacl-fast"); const nThen = require("nthen"); const Util = require("../common-util"); const BlockStore = require("../storage/block"); +const SSOUtils = require("../sso-utils"); var isString = s => typeof(s) === 'string'; Block.isValidBlockId = id => { @@ -182,5 +183,17 @@ Block.removeLoginBlock = function (Env, publicKey, reason, _cb) { }); cb(err); }); + + + // We should also try to remove the SSO data. Errors will be logged + // but they don't have to be shown to the user. The account data + // is already deleted anyway. + + // If this is NOT a password change, also delete sso user. + if (reason !== 'PASSWORD_CHANGE') { + SSOUtils.deleteAccount(Env, publicKey, () => {}); + } else { + SSOUtils.deleteBlock(Env, publicKey, () => {}); + } }; diff --git a/lib/http-commands.js b/lib/http-commands.js index cf4cf3ad9..e573d5b83 100644 --- a/lib/http-commands.js +++ b/lib/http-commands.js @@ -62,7 +62,7 @@ var COMMANDS = {}; // and to authenticate new sessions once a TOTP secret has been associated with their account, const NOAUTH = require("./challenge-commands/base.js"); COMMANDS.MFA_CHECK = NOAUTH.MFA_CHECK; -COMMANDS.WRITE_BLOCK = NOAUTH.WRITE_BLOCK; +COMMANDS.WRITE_BLOCK = NOAUTH.WRITE_BLOCK; // Account creation + password change COMMANDS.REMOVE_BLOCK = NOAUTH.REMOVE_BLOCK; const TOTP = require("./challenge-commands/totp.js"); @@ -70,13 +70,14 @@ COMMANDS.TOTP_SETUP = TOTP.TOTP_SETUP; COMMANDS.TOTP_VALIDATE = TOTP.TOTP_VALIDATE; COMMANDS.TOTP_MFA_CHECK = TOTP.TOTP_MFA_CHECK; COMMANDS.TOTP_REVOKE = TOTP.TOTP_REVOKE; -COMMANDS.TOTP_WRITE_BLOCK = TOTP.TOTP_WRITE_BLOCK; +COMMANDS.TOTP_WRITE_BLOCK = TOTP.TOTP_WRITE_BLOCK; // Password change only for now (v5.5.0) COMMANDS.TOTP_REMOVE_BLOCK = TOTP.TOTP_REMOVE_BLOCK; const SSO = require("./challenge-commands/sso.js"); COMMANDS.SSO_AUTH = SSO.SSO_AUTH; COMMANDS.SSO_AUTH_CB = SSO.SSO_AUTH_CB; -COMMANDS.SSO_WRITE_BLOCK = SSO.SSO_WRITE_BLOCK; +COMMANDS.SSO_WRITE_BLOCK = SSO.SSO_WRITE_BLOCK; // Account creation only +COMMANDS.SSO_UPDATE_BLOCK = SSO.SSO_UPDATE_BLOCK; // Password change COMMANDS.SSO_VALIDATE = SSO.SSO_VALIDATE; var randomToken = () => Nacl.util.encodeBase64(Nacl.randomBytes(24)).replace(/\//g, '-'); diff --git a/lib/http-worker.js b/lib/http-worker.js index 90b0babfe..de3b93437 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -204,7 +204,6 @@ const wsProxy = createProxyMiddleware({ app.use('/cryptpad_websocket', wsProxy); app.use('/ssoauth', (req, res, next) => { - console.log(req.body.SAMLResponse); if (req && req.body && req.body.SAMLResponse) { req.method = 'GET'; @@ -407,7 +406,8 @@ app.use('/block/', function (req, res, next) { var no = function () { w.abort(); res.status(401).json({ - method: (mfa_params && mfa_params.method) || (sso_params && 'SSO'), + sso: Boolean(sso_params), + method: mfa_params && mfa_params.method, code: 401 }); }; @@ -427,7 +427,8 @@ app.use('/block/', function (req, res, next) { if (err) { Log.error('SESSION_READ_ERROR', err); return res.status(401).json({ - method: mfa_params.method, + sso: Boolean(sso_params), + method: mfa_params && mfa_params.method, code: 401, }); } @@ -439,7 +440,6 @@ app.use('/block/', function (req, res, next) { if (content.mfa && content.mfa.exp && (+new Date()) > content.mfa.exp) { Log.error("OTP_SESSION_EXPIRED", content.mfa); - // XXX Only delete the mfa part Sessions.delete(Env, name, token, function (err) { if (err) { Log.error('SESSION_DELETE_EXPIRED_ERROR', err); diff --git a/lib/sso-utils.js b/lib/sso-utils.js index b1fa2f8f6..dd9f8136f 100644 --- a/lib/sso-utils.js +++ b/lib/sso-utils.js @@ -4,6 +4,7 @@ const Nacl = require("tweetnacl/nacl-fast"); const JWT = require("jsonwebtoken"); const Util = require("./common-util"); const config = require("./load-config"); +const nThen = require("nthen"); const SSOUtils = module.exports; @@ -17,7 +18,6 @@ SSOUtils.getOptions = () => { }; }; -// XXX const SAML = require('node-saml'); // https://www.npmjs.com/package/node-saml const TYPES = SSOUtils.TYPES = { oidc: require('./plugins/sso/oidc'), saml: require('./plugins/sso/saml') @@ -82,8 +82,11 @@ SSOUtils.readUser = (Env, provider, id, cb) => { cb(void 0, Util.tryParse(user)); }); }; +SSOUtils.deleteUser = (Env, provider, id, cb) => { + SSO.user.archive(Env, provider, id, cb); +}; SSOUtils.updateUser = (Env, provider, id, data, cb) => { - SSO.user.delete(Env, provider, id, () => { + SSO.user.archive(Env, provider, id, () => { SSO.user.write(Env, provider, id, JSON.stringify(data), (err) => { if (err) { return void cb(err); } cb(); @@ -91,9 +94,10 @@ SSOUtils.updateUser = (Env, provider, id, data, cb) => { }); }; -SSOUtils.writeBlock = (Env, id, ssoID, cb) => { +SSOUtils.writeBlock = (Env, id, provider, ssoID, cb) => { SSO.block.write(Env, id, JSON.stringify({ - id: ssoID + id: ssoID, + provider: provider }), (err) => { if (err) { return void cb(err); } cb(); @@ -101,10 +105,58 @@ SSOUtils.writeBlock = (Env, id, ssoID, cb) => { }; SSOUtils.readBlock = (Env, id, cb) => { SSO.block.read(Env, id, (err, blockData) => { - if (err) { return void cb(err); } + if (err && err !== 'ENOENT' && err.code !== 'ENOENT') { + Env.Log.error("SSO_READ_BLOCK", { + error: Util.serializeError(err), + publicKey: id + }); + } + if (err) { return void cb(err.code || err); } cb(void 0, Util.tryParse(blockData)); }); }; +SSOUtils.deleteBlock = (Env, id, cb) => { + SSO.block.archive(Env, id, (err) => { + if (err) { return void cb(err); } + cb(); + }); +}; + +// Archive SSO account data +SSOUtils.deleteAccount = (Env, publicKey, cb) => { + SSOUtils.readBlock(Env, publicKey, (err, data) => { + if (err && err !== 'ENOENT') { return void cb(err); } + if (!data) { return void cb(); } + let provider = data.provider; + let userId = data.id; + nThen((w) => { + SSOUtils.deleteUser(Env, provider, userId, w((err) => { + Env.Log.error("SSO_DELETE_USER", { + error: Util.serializeError(err), + provider: provider, + id: userId + }); + })); + SSOUtils.deleteBlock(Env, publicKey, w()); + }).nThen(() => { + cb(); + }); + }); +}; +SSOUtils.restoreAccount = (Env, publicKey, cb) => { + SSO.block.restore(Env, publicKey, (err) => { + if (err && err.code === 'ENOENT') { return void cb(); } + if (err) { return void cb(err); } + SSOUtils.readBlock(Env, publicKey, (err, data) => { + let provider = data.provider; + let userId = data.id; + SSO.user.restore(Env, provider, userId, (err) => { + cb(err); + }); + }); + }); +}; + // Store the SSO data (tokens, etc.) in a JWT while waiting for the user's CryptPad password SSOUtils.createJWT = (Env, ssoId, provider, data, cb) => { @@ -149,7 +201,6 @@ SSOUtils.checkJWT = (Env, token, cb) => { SSOUtils.makeSession = (Env, publicKey, provider, ssoData, cb) => { const sessionId = Sessions.randomId(); - // XXX If we already have an OTP session, recover it Sessions.write(Env, publicKey, sessionId, JSON.stringify({ sso: { exp: +new Date() + SESSION_EXPIRATIION, @@ -171,3 +222,4 @@ SSOUtils.makeSession = (Env, publicKey, provider, ssoData, cb) => { }); }; + diff --git a/lib/storage/basic.js b/lib/storage/basic.js index c164cceae..298c72865 100644 --- a/lib/storage/basic.js +++ b/lib/storage/basic.js @@ -21,6 +21,7 @@ Feel free to migrate all of these to a relational DB at some point in the future const Basic = module.exports; const Fs = require("node:fs"); +const Fse = require("fs-extra"); const Path = require("node:path"); var pathError = (cb) => { @@ -66,4 +67,17 @@ Basic.deleteDir = function (Env, path, cb) { Fs.rm(path, { recursive: true, force: true }, cb); }; - +Basic.archive = function (Env, path, archivePath, cb) { + Fse.move(path, archivePath, { + overwrite: true, + }, (err) => { + cb(err); + }); +}; +Basic.restore = function (Env, archivePath, path, cb) { + Fse.move(archivePath, path, { + //overwrite: true, + }, (err) => { + cb(err); + }); +}; diff --git a/lib/storage/sessions.js b/lib/storage/sessions.js index b5f494447..907306f05 100644 --- a/lib/storage/sessions.js +++ b/lib/storage/sessions.js @@ -42,6 +42,19 @@ Sessions.delete = function (Env, id, ref, cb) { Basic.delete(Env, path, cb); }; +Sessions.update = function (Env, id, oldId, ref, dataStr, cb) { + var data = Util.tryParse(dataStr); + Sessions.read(Env, oldId, ref, (err, oldData) => { + let content = Util.tryParse(oldData) || {}; + Object.keys(data || {}).forEach((type) => { + content[type] = data[type]; + }); + Sessions.delete(Env, oldId, ref, () => { + Sessions.write(Env, id, ref, JSON.stringify(content), cb); + }); + }); +}; + Sessions.deleteUser = function (Env, id, cb) { if (!id || typeof(id) !== 'string') { return; } id = Util.escapeKeyCharacters(id); diff --git a/lib/storage/sso.js b/lib/storage/sso.js index 3e41bb5d8..e2ee8360f 100644 --- a/lib/storage/sso.js +++ b/lib/storage/sso.js @@ -7,7 +7,7 @@ const SSO = module.exports; A first part (sso-requests) contains temporary files for sso authentication with a remote service A second part (sso-users) is a database of accounts registered via SSO (SSO id ==> block seed) -A third part (sso-blocks) is a databse of blocks that are sso-protected (block id ==> SSO id...) +A third part (sso-blocks) is a database of blocks that are sso-protected (block id ==> SSO id...) The path for requests is based on the "authentication request" token depending on the type of SSO. The path for the user database is based on their persistent identifier (id) from the SSO. @@ -32,6 +32,13 @@ var userPathFromId = function (Env, id, provider) { return Path.join(Env.paths.base, 'sso_user', provider, id.slice(0, 2), `${id}.json`); }; +var blockArchivePath = function (Env, id) { + return Path.join(Env.paths.archive, 'sso_block', id.slice(0, 2), `${id}.json`); +}; +var userArchivePath = function (Env, id, provider) { + return Path.join(Env.paths.archive, 'sso_user', provider, id.slice(0, 2), `${id}.json`); +}; + const Req = SSO.request = {}; Req.read = function (Env, id, cb) { @@ -62,6 +69,16 @@ User.delete = function (Env, provider, id, cb) { var path = userPathFromId(Env, id, provider); Basic.delete(Env, path, cb); }; +User.archive = function (Env, provider, id, cb) { + var path = userPathFromId(Env, id, provider); + var archivePath = userArchivePath(Env, id, provider); + Basic.archive(Env, path, archivePath, cb); +}; +User.restore = function (Env, provider, id, cb) { + var path = userPathFromId(Env, id, provider); + var archivePath = userArchivePath(Env, id, provider); + Basic.restore(Env, archivePath, path, cb); +}; const Block = SSO.block = {}; @@ -77,3 +94,13 @@ Block.delete = function (Env, id, cb) { var path = blockPathFromId(Env, id); Basic.delete(Env, path, cb); }; +Block.archive = function (Env, id, cb) { + var path = blockPathFromId(Env, id); + var archivePath = blockArchivePath(Env, id); + Basic.archive(Env, path, archivePath, cb); +}; +Block.restore = function (Env, id, cb) { + var path = blockPathFromId(Env, id); + var archivePath = blockArchivePath(Env, id); + Basic.restore(Env, archivePath, path, cb); +}; diff --git a/www/common/common-constants.js b/www/common/common-constants.js index 888edeafd..12c4ec818 100644 --- a/www/common/common-constants.js +++ b/www/common/common-constants.js @@ -6,6 +6,7 @@ define(['/customize/application_config.js'], function (AppConfig) { blockHashKey: 'Block_hash', fileHashKey: 'FS_hash', sessionJWT: 'Session_JWT', + ssoSeed: 'SSO_seed', // Store displayNameKey: 'cryptpad.username', diff --git a/www/common/common-login.js b/www/common/common-login.js index d2776dcb7..fede6b609 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -299,7 +299,8 @@ define([ // results... var res = { register: isRegister, - uname: uname + uname: uname, + auth_token: {} }; var RT, blockKeys, blockUrl; @@ -323,11 +324,12 @@ define([ // determine where a block for your set of keys would be stored blockUrl = Block.getBlockUrl(res.opt.blockKeys); - var TOTP_prompt = function (err, cb) { + var TOTP_prompt = function (err, ssoSession, cb) { onOTP(function (code) { ServerCommand(res.opt.blockKeys.sign, { command: 'TOTP_VALIDATE', code: code, + session: ssoSession // TODO optionally allow the user to specify a lifetime for this session? // this will require a little bit of server work // and more UI/UX: @@ -352,11 +354,13 @@ define([ }; var missingAuth; + var missingSSO; nThen(function (w) { Util.getBlock(blockUrl, { // request the block without credentials }, w(function (err, response) { if (err === 401) { + missingSSO = response && response.sso; missingAuth = response && response.method; return void console.log("Block requires 2FA"); } @@ -395,19 +399,24 @@ define([ }); })); }).nThen(function (w) { - if (missingAuth !== 'SSO') { return; } // XXX multiple auth + if (!missingSSO) { return; } + // SSO session should always be applied before the OTP one + // because we can't transform an account into an SSO account later + // so we probably don't need to recover the OTP session here ServerCommand(res.opt.blockKeys.sign, { command: 'SSO_VALIDATE', jwt: ssoAuth.data, }, w(function (err, response) { if (err) { - // XXX - return; + console.error(err); + w.abort(); + waitFor.abort(); + return void cb(err); } res.auth_token = response; })); }).nThen(function (w) { - if (missingAuth !== 'TOTP') { return; } // XXX multiple auth + if (missingAuth !== 'TOTP') { return; } // if you're here then you need to request a JWT var done = w(); var tries = 3; @@ -418,7 +427,9 @@ define([ return void cb('TOTP_ATTEMPTS_EXHAUSTED'); } tries--; - TOTP_prompt(tries !== 2, function (err, response) { + // If we have an SSO account, provide the SSO session to update it with OTP + var ssoSession = (res.auth_token && res.auth_token.bearer) || ''; + TOTP_prompt(tries !== 2, ssoSession, function (err, response) { // ask again until your number of tries are exhausted if (err) { console.error(err); @@ -477,6 +488,7 @@ define([ }).nThen(function (waitFor) { // MODERN REGISTRATION / LOGIN var opt = getProxyOpt(res.blockInfo); + LocalStore.setSessionToken(''); modernLoginRegister(opt, isRegister, waitFor(function (err, data, _RT) { if (err) { waitFor.abort(); @@ -497,11 +509,14 @@ define([ toPublish[Constants.userHashKey] = res.userHash; toPublish.edPublic = RT.proxy.edPublic; + // FIXME We currently can't create an account with OTP by default + // NOTE If we ever want to do that for SSO accounts it will require major changes + // because writeLoginBlock only supports one type of authentication at a time Block.writeLoginBlock({ pw: Boolean(passwd), auth: ssoAuth, blockKeys: blockKeys, - content: toPublish + content: toPublish, }, waitFor(function (e, res) { if (e === 'SSO_NO_SESSION') { return; } // account created, need re-login if (e) { diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 3ab33e5b8..f0a4d3801 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1994,6 +1994,11 @@ define([ console.log("no block found"); return; } + if (err && err === 401) { + // there is a protected block at the next location, abort FIXME check + waitFor.abort(); + return void cb({ error: 'EEXISTS' }); + } response.arrayBuffer().then(waitFor(arraybuffer => { var block = new Uint8Array(arraybuffer); @@ -2042,21 +2047,42 @@ define([ User_hash: newHash, edPublic: edPublic, }; + var sessionToken = LocalStore.getSessionToken() || undefined; Block.writeLoginBlock({ auth: auth, blockKeys: blockKeys, oldBlockKeys: oldBlockKeys, - content: content + content: content, + session: sessionToken // Recover existing SSO session }, waitFor(function (err, data) { if (err) { waitFor.abort(); return void cb({error: err}); } + // Update the session if OTP is enabled + // If OTP is disabled, keep the existing SSO session if (data && data.bearer) { LocalStore.setSessionToken(data.bearer); } })); + }).nThen(function (waitFor) { + var isSSO = Boolean(LocalStore.getSSOSeed()); + if (!isSSO) { return; } + + // Update "sso_block" data for SSO accounts + Block.updateSSOBlock({ + blockKeys: blockKeys, + oldBlockKeys: oldBlockKeys + }, waitFor(function (err) { + if (err) { + // If we can't move the sso_block data, we won't be able to log in later + // so we must abort the password change. + console.error(err); + waitFor.abort(); + return void cb({error: err}); + } + })); }).nThen(function (waitFor) { var blockUrl = Block.getBlockUrl(blockKeys); var sessionToken = LocalStore.getSessionToken() || undefined; diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 954ca4ba7..f2a6ad358 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -881,6 +881,7 @@ define([ })); }).nThen(function (waitFor) { // Delete Drive + store.ownDeletion = true; Store.removeOwnedChannel(clientId, { channel: store.driveChannel, force: true @@ -3055,6 +3056,7 @@ define([ }) .on('error', function (info) { if (info.error && info.error === 'EDELETED') { + if (store.ownDeletion) { return; } broadcast([], "LOGOUT", { reason: info.message }); diff --git a/www/common/outer/local-store.js b/www/common/outer/local-store.js index 845a6393a..d14532d7c 100644 --- a/www/common/outer/local-store.js +++ b/www/common/outer/local-store.js @@ -47,7 +47,7 @@ define([ return hash; }; - var getUserHash = LocalStore.getUserHash = function () { + LocalStore.getUserHash = function () { var hash = localStorage[Constants.userHashKey]; if (['undefined', 'undefined/'].indexOf(hash) !== -1) { @@ -84,6 +84,13 @@ define([ safeSet(Constants.sessionJWT, token); }; + LocalStore.getSSOSeed = function () { + return localStorage[Constants.ssoSeed]; + }; + LocalStore.setSSOSeed = function (seed) { + safeSet(Constants.ssoSeed, seed); + }; + LocalStore.getAccountName = function () { return localStorage[Constants.userNameKey]; }; @@ -130,6 +137,7 @@ define([ Constants.userHashKey, Constants.blockHashKey, Constants.sessionJWT, + Constants.ssoSeed, 'loginToken', 'plan', ].forEach(function (k) { diff --git a/www/common/outer/login-block.js b/www/common/outer/login-block.js index dcabdaaad..7872d9b88 100644 --- a/www/common/outer/login-block.js +++ b/www/common/outer/login-block.js @@ -173,7 +173,7 @@ define([ }, cb); }; Block.writeLoginBlock = function (data, cb) { - const { content, blockKeys, oldBlockKeys, auth, pw } = data; + const { content, blockKeys, oldBlockKeys, auth, pw, session } = data; var command = 'WRITE_BLOCK'; if (auth && auth.type) { command = `${auth.type.toUpperCase()}_` + command; } @@ -185,7 +185,8 @@ define([ ServerCommand(blockKeys.sign, { command: command, - content: block + content: block, + session: session // sso session }, cb); }; Block.removeLoginBlock = function (data, cb) { @@ -201,5 +202,16 @@ define([ }, cb); }; + Block.updateSSOBlock = function (data, cb) { + const { blockKeys, oldBlockKeys } = data; + var oldProof = oldBlockKeys && Block.proveAncestor(oldBlockKeys); + + ServerCommand(blockKeys.sign, { + command: 'SSO_UPDATE_BLOCK', + ancestorProof: oldProof + }, cb); + + }; + return Block; }); diff --git a/www/settings/inner.js b/www/settings/inner.js index 9b304a2dd..7500e3c0a 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -577,10 +577,17 @@ define([ loadingText: Messages.settings_deleteTitle }); setTimeout(function () { - var name = privateData.accountName; var bytes; var auth = {}; + var ssoSeed; nThen(function (w) { + sframeChan.query("Q_SETTINGS_GET_SSO_SEED", { + }, w(function (err, obj) { + if (!obj || !obj.seed) { return; } // Not an sso account? + ssoSeed = obj.seed; + })); + }).nThen(function (w) { + var name = ssoSeed || privateData.accountName; deriveBytes(name, password, w(function (_bytes) { bytes = _bytes; })); @@ -723,8 +730,15 @@ define([ setTimeout(function () { var oldBytes, newBytes; var auth = {}; + var ssoSeed; nThen(function (w) { - var name = privateData.accountName; + sframeChan.query("Q_SETTINGS_GET_SSO_SEED", { + }, w(function (err, obj) { + if (!obj || !obj.seed) { return; } // Not an sso account? + ssoSeed = obj.seed; + })); + }).nThen(function (w) { + var name = ssoSeed || privateData.accountName; deriveBytes(name, oldPassword, w(function (bytes) { oldBytes = bytes; })); @@ -1053,6 +1067,7 @@ define([ var Base32, QRCode, Nacl; var blockKeys; var recoverySecret; + var ssoSeed; nThen(function (waitFor) { require([ '/auth/base32.js', @@ -1063,12 +1078,19 @@ define([ QRCode = window.QRCode; Nacl = window.nacl; })); + }).nThen(function (waitFor) { + sframeChan.query("Q_SETTINGS_GET_SSO_SEED", { + }, waitFor(function (err, obj) { + if (!obj || !obj.seed) { return; } // Not an sso account? + ssoSeed = obj.seed; + })); }).nThen(function (waitFor) { var next = waitFor(); // scrypt locks up the UI before the DOM has a chance // to update (displaying logs, etc.), so do a set timeout setTimeout(function () { - Login.Cred.deriveFromPassphrase(name, password, Login.requiredBytes, function (bytes) { + var salt = ssoSeed || name; + Login.Cred.deriveFromPassphrase(salt, password, Login.requiredBytes, function (bytes) { var result = Login.allocateBytes(bytes); sframeChan.query("Q_SETTINGS_CHECK_PASSWORD", { blockHash: result.blockHash, @@ -1160,7 +1182,6 @@ define([ lock = true; var data = { - command: 'TOTP_SETUP', secret: secret, contact: "secret:" + recoverySecret, // TODO other recovery options code: code, diff --git a/www/settings/main.js b/www/settings/main.js index 371c4f899..26705d5a3 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -81,7 +81,10 @@ define([ require([ '/common/outer/http-command.js', ], function (ServerCommand) { - ServerCommand(obj.key, obj.data, function (err, response) { + var data = obj.data; + data.command = 'TOTP_SETUP'; + data.session = Utils.LocalStore.getSessionToken(); + ServerCommand(obj.key, data, function (err, response) { cb({ success: Boolean(!err && response && response.bearer) }); if (response && response.bearer) { Utils.LocalStore.setSessionToken(response.bearer); @@ -111,11 +114,18 @@ define([ Utils.Util.getBlock(parsed.href, {}, function (err, data) { cb({ mfa: err === 401, + sso: data && data.sso, type: data && data.method }); }); }); }); + sframeChan.on('Q_SETTINGS_GET_SSO_SEED', function (obj, _cb) { + var cb = Utils.Util.mkAsync(_cb); + cb({ + seed: Utils.LocalStore.getSSOSeed() + }); + }); sframeChan.on('Q_SETTINGS_REMOVE_OWNED_PADS', function (data, cb) { Cryptpad.removeOwnedPads(data, cb); }); diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index 758e823ce..db51ee60b 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -58,6 +58,7 @@ define([ $button.prop('disabled', ''); return void UI.warn(msg); } + LocalStore.setSSOSeed(seed.toLowerCase()); window.location.href = '/drive/'; }); }; From 442d7655dc36cbe9fa2000d38f12ed26cce7136a Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Sat, 28 Oct 2023 17:21:48 +0300 Subject: [PATCH 022/283] Fix chat and userlist height problem --- www/pad/app-pad.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/pad/app-pad.less b/www/pad/app-pad.less index 3ecaf13da..b944663d6 100644 --- a/www/pad/app-pad.less +++ b/www/pad/app-pad.less @@ -26,7 +26,8 @@ body.cp-app-pad { @media screen and (max-width: @browser_media-medium-screen){ position: absolute; right: 0; - height: 90%; + bottom: 0; + top: 74px; } } From f3903d3961f8178e6e2ce97d52b2060859580b0d Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 30 Oct 2023 17:13:54 +0100 Subject: [PATCH 023/283] Add keyboard shortcut on SSO login --- www/ssoauth/main.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index db51ee60b..186f41444 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -110,6 +110,19 @@ define([ } $('div.cp-ssoauth-pw').show(); + $pw.focus(); + + $pw.on('keypress', (ev) => { + if (ev.which !== 13) { return; } + if (!$pw2.val() && data.register) { + return void $pw2.focus(); + } + $button.click(); + }); + $pw2.on('keypress', (ev) => { + if (ev.which !== 13) { return; } + $button.click(); + }); $button.click(() => { let pw = $pw.val(); From 77e600ce809fa366dcd5b04db4dcafa3e89a56d4 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 30 Oct 2023 17:14:27 +0100 Subject: [PATCH 024/283] Add signing certificate to SAML auth --- lib/plugins/sso/saml.js | 8 ++++++++ scripts/saml-metadata.js | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 scripts/saml-metadata.js diff --git a/lib/plugins/sso/saml.js b/lib/plugins/sso/saml.js index 7f7d7edfb..1b7333db8 100644 --- a/lib/plugins/sso/saml.js +++ b/lib/plugins/sso/saml.js @@ -28,11 +28,19 @@ const getClient = (cfg, cb) => { entryPoint: cfg.url, issuer: cfg.issuer, cert: cfg.cert, + privateKey: cfg.privateKey }); cb(void 0, saml); }; +const getMetadata = (cfg, cb) => { + getClient(cfg, (err, client) => { + if (err) { return void cb(err); } + cb(null, client.generateServiceProviderMetadata(null, cfg.signingCert)); + }); +}; module.exports = { type: TYPE, + getMetadata: getMetadata, checkConfig: (cfg) => { return cfg.url && cfg.issuer && cfg.cert; }, diff --git a/scripts/saml-metadata.js b/scripts/saml-metadata.js new file mode 100644 index 000000000..eec57ebef --- /dev/null +++ b/scripts/saml-metadata.js @@ -0,0 +1,16 @@ +const config = require("../lib/load-config"); +const SSOUtils = require('../lib/sso-utils'); + +const sso = config.sso; +sso.list.filter((el) => { + return el.type === 'saml'; +}).forEach((cfg) => { + SSOUtils.TYPES.saml.getMetadata(cfg, (err, md) => { + console.log(`Name: ${cfg.name}`); + console.log('Metadata:'); + console.log(); + console.log(md); + console.log(); + console.log('===================================='); + }); +}); From 5c32f2e39d0f1640d55c77f8ab92901565471e09 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Tue, 31 Oct 2023 17:21:26 +0100 Subject: [PATCH 025/283] further fixes to poll option types --- www/form/app-form.less | 3 +++ www/form/inner.js | 33 +++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 7783aba12..69ebefa87 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -642,6 +642,9 @@ display: flex; justify-content: space-between; } + .cp-empty-poll-edit-buttons { + padding-top: 40px + } input:invalid { border: 2px solid @cryptpad_color_red; color: @cp_form-invalid; diff --git a/www/form/inner.js b/www/form/inner.js index 42f103bdf..91d1c8c34 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -431,11 +431,7 @@ define([ // Calendar inline for "day" type var calendarInput = h('input'); calendarView = h('div', calendarInput); - var calendarDefault = v.type === "day" ? extractValues(v.values).map(function (time) { - if (!time) { return; } - var d = new Date(time); - if (!isNaN(d)) { return d; } - }).filter(Boolean) : undefined; + var calendarDefault = new Date() Flatpickr(calendarInput, { mode: 'multiple', inline: true, @@ -506,6 +502,7 @@ define([ refreshView(); // Doodle type change: empty current values and change input types? + if (typeSelect) { typeSelect.onChange.reg(function (prettyVal, val) { v.type = val; @@ -524,12 +521,22 @@ define([ $add.before(el); $(el).find('input').focus(); return; + } else if (val === "day") { + var time = new Date(); + var el = getOption(+time, false, false, Util.uid()); + $add.before(el); + $(el).find('input').focus(); + return; } $(add).click(); return; } + + if (parseInt($container.find('input')[0].value) !== NaN && parseInt($container.find('input')[0].value).toString().length > 4) { + var dateInput = new Date(parseInt($container.find('input')[0].value)) + $container.find('input')[0].value = dateInput.toDateString() + } $container.find('input').each(function (i, input) { - $container.find('input')[0].value = '' if (input._flatpickr) { input._flatpickr.destroy(); delete input._flatpickr; @@ -4054,23 +4061,25 @@ define([ framework.localChange(); updateAddInline(); }); - editButtons = h('div.cp-form-edit-buttons-container', [ fakeEdit, del ]); - changeType = h('div.cp-form-block-type', [ - model.icon.cloneNode(), - h('span', Messages['form_type_'+type]) - ]); - + changeType = h('div.cp-form-block-type', [ + model.icon.cloneNode(), + h('span', Messages['form_type_'+type]) + ]); // Values if (data.edit) { + var edit = h('button.btn.btn-default.cp-form-edit-button', [ h('i.fa.fa-pencil'), h('span', Messages.form_editBlock) ]); editButtons = h('div.cp-form-edit-buttons-container', [ edit, del ]); editContainer = h('div'); + if (type === 'poll' && block.opts.values.length === 0) { + $(editButtons).addClass('cp-empty-poll-edit-buttons') + } var onSave = function (newOpts, close) { if (close) { // Cancel edit data.editing = false; From 4aa33be5745619768a94e5926fc9da7724be7633 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Tue, 31 Oct 2023 17:29:35 +0100 Subject: [PATCH 026/283] adjusted poll option input width on mobile --- www/form/app-form.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 69ebefa87..4738eb934 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -778,7 +778,7 @@ display: flex; width: 400px; @media (max-width:460px) { - width: 300px + width: 100% } input { flex: 1; From 304fc6e970597417d72249c65b06ab3e656dc028 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 14 Sep 2023 15:17:32 +0200 Subject: [PATCH 027/283] Upgrade draw.io to 21.7.5 --- docs/example-advanced.nginx.conf | 2 +- lib/http-worker.js | 2 +- package-lock.json | 2 +- package.json | 2 +- scripts/copy-components.js | 2 +- www/diagram/inner.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/example-advanced.nginx.conf b/docs/example-advanced.nginx.conf index 5a0accab1..b3b8d36f1 100644 --- a/docs/example-advanced.nginx.conf +++ b/docs/example-advanced.nginx.conf @@ -163,7 +163,7 @@ server { if ($uri ~ ^\/unsafeiframe\/inner\.html.*$) { set $unsafe 1; } # draw.io uses inline script tags in it's index.html. The hashes are added here. - if ($uri ~ ^\/components\/drawio\/src\/main\/webapp\/index.html.*$) { + if ($uri ~ ^\/components\/drawio-cp\/src\/main\/webapp\/index.html.*$) { set $scriptSrc "'self' 'sha256-dLMFD7ijAw6AVaqecS7kbPcFFzkxQ+yeZSsKpOdLxps=' 'sha256-6g514VrT/cZFZltSaKxIVNFF46+MFaTSDTPB8WfYK+c=' resource: https://${main_domain}"; } diff --git a/lib/http-worker.js b/lib/http-worker.js index 3ade5af71..a88d3d713 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -147,7 +147,7 @@ var setHeaders = function (req, res) { type = 'office'; } else if (/^\/api\/(broadcast|config)/.test(req.url)) { type = 'api'; - } else if (/^\/components\/drawio\/src\/main\/webapp\/index.html.*$/.test(req.url)) { + } else if (/^\/components\/drawio-cp\/src\/main\/webapp\/index.html.*$/.test(req.url)) { type = 'diagram'; } else { type = 'standard'; diff --git a/package-lock.json b/package-lock.json index 189259d0b..c7cb9ea59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "cryptpad/drawio-npm#npm", + "drawio-cp": "github:cryptpad/drawio-npm#npm-21.7.5", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", diff --git a/package.json b/package.json index 5554f4da5..6cfb724db 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "cryptpad/drawio-npm#npm", + "drawio-cp": "github:cryptpad/drawio-npm#npm-21.7.5", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/scripts/copy-components.js b/scripts/copy-components.js index 2aa66ada8..c1f946501 100644 --- a/scripts/copy-components.js +++ b/scripts/copy-components.js @@ -40,7 +40,7 @@ Fse.rmSync(oldComponentsPath, { recursive: true, force: true }); "saferphore", "nthen", "netflux-websocket", - "drawio", + "drawio-cp", "pako", "x2js" ].forEach(l => { diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 3b05c261e..bf2b917aa 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -168,7 +168,7 @@ define([ // starting the CryptPad framework framework.start(); - drawioFrame.src = '/components/drawio/src/main/webapp/index.html?' + drawioFrame.src = '/components/drawio-cp/src/main/webapp/index.html?' + new URLSearchParams({ // pages: 0, // dev: 1, From 8d6942ba610507c5b7ab375aeaf8d7fd1a64f319 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Fri, 22 Sep 2023 09:56:35 +0200 Subject: [PATCH 028/283] WIP play with open dialog --- package-lock.json | 11 +++++++---- package.json | 2 +- scripts/copy-components.js | 1 + www/diagram/inner.js | 6 +++--- www/diagram/open.html | 11 +++++++++++ www/diagram/open.js | 8 ++++++++ 6 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 www/diagram/open.html create mode 100644 www/diagram/open.js diff --git a/package-lock.json b/package-lock.json index c7cb9ea59..cd746d06e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio-cp": "github:cryptpad/drawio-npm#npm-21.7.5", + "drawio-cp": "../drawio-npm", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -68,6 +68,9 @@ "url": "https://opencollective.com/cryptpad" } }, + "../drawio-npm": { + "version": "21.7.5" + }, "node_modules/@mcrowe/minibloom": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mcrowe/minibloom/-/minibloom-0.2.0.tgz", @@ -914,9 +917,9 @@ }, "node_modules/ckeditor": { "name": "ckeditor4", - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.22.1.tgz", - "integrity": "sha512-Yj4vTHX5YxHwc48gNqUqTm+KLkRr9tuyb4O2VIABu4oKHWRNVIdLdy6vUNe/XNx+RiTavMejfA1MVOU/MxLjqQ==" + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.23.0.tgz", + "integrity": "sha512-K9DUzTa7roj8JffKLm6nOxDF02aPURDK8m7oFibvvkyAaomj24qOgpVdt7yvszmIubeJLbAB6q4k7Euk8jzD1A==" }, "node_modules/class-utils": { "version": "0.3.6", diff --git a/package.json b/package.json index 6cfb724db..a9b646d76 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio-cp": "github:cryptpad/drawio-npm#npm-21.7.5", + "drawio-cp": "../drawio-npm", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/scripts/copy-components.js b/scripts/copy-components.js index c1f946501..577100c81 100644 --- a/scripts/copy-components.js +++ b/scripts/copy-components.js @@ -46,5 +46,6 @@ Fse.rmSync(oldComponentsPath, { recursive: true, force: true }); ].forEach(l => { const source = Path.join("node_modules", l); const destination = Path.join(componentsPath, l); + Fs.rmSync(destination, { recursive: true }); Fs.cpSync(source, destination, { recursive: true }); }); diff --git a/www/diagram/inner.js b/www/diagram/inner.js index bf2b917aa..f3388492a 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -170,13 +170,12 @@ define([ drawioFrame.src = '/components/drawio-cp/src/main/webapp/index.html?' + new URLSearchParams({ - // pages: 0, - // dev: 1, test: 1, stealth: 1, embed: 1, drafts: 0, - plugins: 0, + // plugins: 0, + p: '/cryptpad.js', chrome: framework.isReadOnly() ? 0 : 1, dark: window.CryptPad_theme === "dark" ? 1 : 0, @@ -185,6 +184,7 @@ define([ noSaveBtn: 1, saveAndExit: 0, noExitBtn: 1, + browser: 0, modified: 'unsavedChanges', proto: 'json', diff --git a/www/diagram/open.html b/www/diagram/open.html new file mode 100644 index 000000000..48fbc66bf --- /dev/null +++ b/www/diagram/open.html @@ -0,0 +1,11 @@ + + + + + + + + Hello World! + + + diff --git a/www/diagram/open.js b/www/diagram/open.js new file mode 100644 index 000000000..3ff6dcb84 --- /dev/null +++ b/www/diagram/open.js @@ -0,0 +1,8 @@ +window.addEventListener('load', () => { + const img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kTtIw1AUhv+mSlUqDnYQcQhSnSyIijhqFYpQIdQKrTqY3PQFTRqSFBdHwbXg4GOx6uDirKuDqyAIPkBcXZwUXaTEc5NCixgPHO7Hf89/OPdcQKiXmWZ1jAOabpupRFzMZFfF0Cu6EaEMYFhmljEnSUn4xtc91VHcxXgv/7o/o1fNWQwIiMSzzDBt4g3i6U3b4LxPHGFFWSU+Jx4zaUDiR64rHr9xLrgs8J4RM52aJ44Qi4U2VtqYFU2NeIo4qmo69RcyHquctzhr5SprzslfGM7pK8tcpxxCAotYggQRCqoooQwbMTp1Uiyk6D7u4x90/RK5FHKVwMixgAo0yK4f/A9+79bKT054ncJxoPPFcT5GgNAu0Kg5zvex4zROgOAzcKW3/JU6MPNJeq2lRY+Avm3g4rqlKXvA5Q4w8GTIpuxKQUohnwfez+ibskD/LdCz5u2teY/TByBNu0reAAeHwGiBeq/7vLurfW//1jT39wMoP3KJ0fwekQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+cJFAkDEsK7OicAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAJElEQVQI12P8//8/AzbAxIADQCUYGRnRGQSMwqcDIoTgkuwqAOKDDw0zjEG/AAAAAElFTkSuQmCC'; + const btn = document.querySelector('button'); + btn.addEventListener('click', () => { + debugger; + window.parent.openFile.setData(img, 'test.png'); + }); +}); From 2dbd2b6ce7c9fa919c724b638c440e7e43ac6c3b Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Wed, 27 Sep 2023 14:38:37 +0200 Subject: [PATCH 029/283] openFilePicker now also returns fileType --- www/secureiframe/inner.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/secureiframe/inner.js b/www/secureiframe/inner.js index a93fc5e26..2aea4c1ee 100644 --- a/www/secureiframe/inner.js +++ b/www/secureiframe/inner.js @@ -117,6 +117,7 @@ define([ var key = Hash.encodeBase64(secret.keys.cryptKey); sframeChan.event("EV_SECURE_ACTION", { type: parsed.type, + fileType: data.fileType, href: data.url, src: src, name: data.name, @@ -230,7 +231,7 @@ define([ if (data.static) { $span.attr('title', Util.fixHTML(data.href)); } $span.click(function () { if (typeof onFilePicked === "function") { - onFilePicked({url: data.href, name: name, static: data.static, password: data.password}); + onFilePicked({url: data.href, name: name, static: data.static, password: data.password, fileType: data.fileType}); } }); From d1b2da8cce410e20b1afbade7896e9b5fc00dafa Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Wed, 27 Sep 2023 14:45:16 +0200 Subject: [PATCH 030/283] Can add image from CryptPad. Size is missing. --- scripts/copy-components.js | 2 +- www/diagram/inner.js | 75 +++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/scripts/copy-components.js b/scripts/copy-components.js index 577100c81..24831aca7 100644 --- a/scripts/copy-components.js +++ b/scripts/copy-components.js @@ -46,6 +46,6 @@ Fse.rmSync(oldComponentsPath, { recursive: true, force: true }); ].forEach(l => { const source = Path.join("node_modules", l); const destination = Path.join(componentsPath, l); - Fs.rmSync(destination, { recursive: true }); + Fs.rmSync(destination, { recursive: true, force: true }); Fs.cpSync(source, destination, { recursive: true }); }); diff --git a/www/diagram/inner.js b/www/diagram/inner.js index f3388492a..8d92bd55e 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -4,6 +4,8 @@ define([ '/customize/messages.js', // translation keys '/components/pako/dist/pako.min.js', '/components/x2js/x2js.js', + '/common/common-util.js', + '/file/file-crypto.js', '/components/tweetnacl/nacl-fast.min.js', 'less!/diagram/app-diagram.less', 'css!/diagram/drawio.css', @@ -11,8 +13,11 @@ define([ Framework, Messages, pako, - X2JS) { + X2JS, + Util, + FileCrypto) { const Nacl = window.nacl; + const APP = window.APP = {}; // As described here: https://drawio-app.com/extracting-the-xml-from-mxfiles/ const decompressDrawioXml = function(xmlDocStr) { @@ -55,6 +60,8 @@ define([ // This is the main initialization loop var onFrameworkReady = function (framework) { + console.log('XXX framework', framework); + const common = framework._.sfCommon; // TODO do not access internals var EMPTY_DRAWIO = ""; var drawioFrame = document.querySelector('#cp-app-diagram-content'); var x2js = new X2JS(); @@ -121,6 +128,70 @@ define([ autosave: onDrawioAutosave, }; + const createDataUrl = (mimeType, blob) => { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.addEventListener( + "load", + () => { + resolve(reader.result); + }, + false + ); + + const fixedBlob = new Blob([blob], {type: mimeType}); + reader.readAsDataURL(fixedBlob); + }); + }; + + APP.getImageURL = function(data, callback) { + Util.fetch(data.src, function (err, u8) { + if (err) { + console.error(err); + return void callback(""); + } + try { + FileCrypto.decrypt(u8, Nacl.util.decodeBase64(data.key), async (err, res) => { + if (err || !res.content) { + console.error("Decrypting failed"); + return void callback(""); + } + console.log('XXX res', res); + + try { + const dataUrl = await createDataUrl(data.fileType, res.content); + callback(dataUrl); + } catch (e) {} + }); + } catch (e) { + console.error(e); + callback(""); + } + }, void 0, common.getCache()); + }; + + APP.addImage = function() { + return new Promise((resolve) => { + common.openFilePicker({ + types: ['file'], + where: ['root'], + filter: { + fileType: ['image/'] + } + }, (data) => { + console.log('XXX data', data); + // TODO wait for realtime.onSettle + APP.getImageURL(data, function(url) { + common.setPadAttribute('atime', +new Date(), null, data.href); + resolve({ + name: data.name, + url: url + }); + }); + }); + }); + }; + // This is the function from which you will receive updates from CryptPad framework.onContentUpdate(function (newContent) { lastContent = newContent; @@ -175,7 +246,7 @@ define([ embed: 1, drafts: 0, // plugins: 0, - p: '/cryptpad.js', + p: 'cryptpad', chrome: framework.isReadOnly() ? 0 : 1, dark: window.CryptPad_theme === "dark" ? 1 : 0, From 62770db3d09a8d7a77c90c9b354992c224165569 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Wed, 27 Sep 2023 15:38:47 +0200 Subject: [PATCH 031/283] Clean up code --- www/diagram/inner.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 8d92bd55e..79ccf0a06 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -60,8 +60,7 @@ define([ // This is the main initialization loop var onFrameworkReady = function (framework) { - console.log('XXX framework', framework); - const common = framework._.sfCommon; // TODO do not access internals + const common = framework._.sfCommon; var EMPTY_DRAWIO = ""; var drawioFrame = document.querySelector('#cp-app-diagram-content'); var x2js = new X2JS(); @@ -156,7 +155,6 @@ define([ console.error("Decrypting failed"); return void callback(""); } - console.log('XXX res', res); try { const dataUrl = await createDataUrl(data.fileType, res.content); @@ -179,12 +177,11 @@ define([ fileType: ['image/'] } }, (data) => { - console.log('XXX data', data); - // TODO wait for realtime.onSettle APP.getImageURL(data, function(url) { common.setPadAttribute('atime', +new Date(), null, data.href); resolve({ name: data.name, + fileType: data.fileType, url: url }); }); From f4aa3731eb878d0fcd7afd6211169d43245221fe Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Fri, 29 Sep 2023 09:12:17 +0200 Subject: [PATCH 032/283] Fix npm lint --- www/diagram/inner.js | 7 ++----- www/diagram/open.html | 11 ----------- www/diagram/open.js | 8 -------- 3 files changed, 2 insertions(+), 24 deletions(-) delete mode 100644 www/diagram/open.html delete mode 100644 www/diagram/open.js diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 79ccf0a06..829e681cf 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -150,16 +150,13 @@ define([ return void callback(""); } try { - FileCrypto.decrypt(u8, Nacl.util.decodeBase64(data.key), async (err, res) => { + FileCrypto.decrypt(u8, Nacl.util.decodeBase64(data.key), (err, res) => { if (err || !res.content) { console.error("Decrypting failed"); return void callback(""); } - try { - const dataUrl = await createDataUrl(data.fileType, res.content); - callback(dataUrl); - } catch (e) {} + createDataUrl(data.fileType, res.content).then(callback); }); } catch (e) { console.error(e); diff --git a/www/diagram/open.html b/www/diagram/open.html deleted file mode 100644 index 48fbc66bf..000000000 --- a/www/diagram/open.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - Hello World! - - - diff --git a/www/diagram/open.js b/www/diagram/open.js deleted file mode 100644 index 3ff6dcb84..000000000 --- a/www/diagram/open.js +++ /dev/null @@ -1,8 +0,0 @@ -window.addEventListener('load', () => { - const img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAABhGlDQ1BJQ0MgcHJvZmlsZQAAKJF9kTtIw1AUhv+mSlUqDnYQcQhSnSyIijhqFYpQIdQKrTqY3PQFTRqSFBdHwbXg4GOx6uDirKuDqyAIPkBcXZwUXaTEc5NCixgPHO7Hf89/OPdcQKiXmWZ1jAOabpupRFzMZFfF0Cu6EaEMYFhmljEnSUn4xtc91VHcxXgv/7o/o1fNWQwIiMSzzDBt4g3i6U3b4LxPHGFFWSU+Jx4zaUDiR64rHr9xLrgs8J4RM52aJ44Qi4U2VtqYFU2NeIo4qmo69RcyHquctzhr5SprzslfGM7pK8tcpxxCAotYggQRCqoooQwbMTp1Uiyk6D7u4x90/RK5FHKVwMixgAo0yK4f/A9+79bKT054ncJxoPPFcT5GgNAu0Kg5zvex4zROgOAzcKW3/JU6MPNJeq2lRY+Avm3g4rqlKXvA5Q4w8GTIpuxKQUohnwfez+ibskD/LdCz5u2teY/TByBNu0reAAeHwGiBeq/7vLurfW//1jT39wMoP3KJ0fwekQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+cJFAkDEsK7OicAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAJElEQVQI12P8//8/AzbAxIADQCUYGRnRGQSMwqcDIoTgkuwqAOKDDw0zjEG/AAAAAElFTkSuQmCC'; - const btn = document.querySelector('button'); - btn.addEventListener('click', () => { - debugger; - window.parent.openFile.setData(img, 'test.png'); - }); -}); From 2945e6fce9b9d78924ecbc5614d34a2a26268131 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 10 Oct 2023 11:33:43 +0200 Subject: [PATCH 033/283] Pass blobs to draw.io --- www/common/sframe-common-file.js | 1 + www/diagram/inner.js | 25 +++++++------------------ 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/www/common/sframe-common-file.js b/www/common/sframe-common-file.js index 813678c0e..87236f277 100644 --- a/www/common/sframe-common-file.js +++ b/www/common/sframe-common-file.js @@ -92,6 +92,7 @@ define([ var data = {}; data.name = file.metadata.name; + data.fileType = file.metadata.type; data.url = href; data.password = file.password; if (file.metadata.type.slice(0,6) === 'image/') { diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 829e681cf..89cab27dd 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -127,23 +127,12 @@ define([ autosave: onDrawioAutosave, }; - const createDataUrl = (mimeType, blob) => { - return new Promise((resolve) => { - const reader = new FileReader(); - reader.addEventListener( - "load", - () => { - resolve(reader.result); - }, - false - ); - - const fixedBlob = new Blob([blob], {type: mimeType}); - reader.readAsDataURL(fixedBlob); - }); + const setBlobType = (blob, mimeType) => { + const fixedBlob = new Blob([blob], {type: mimeType}); + return fixedBlob; }; - APP.getImageURL = function(data, callback) { + APP.getImage = function(data, callback) { Util.fetch(data.src, function (err, u8) { if (err) { console.error(err); @@ -156,7 +145,7 @@ define([ return void callback(""); } - createDataUrl(data.fileType, res.content).then(callback); + callback(setBlobType(res.content, data.fileType)); }); } catch (e) { console.error(e); @@ -174,12 +163,12 @@ define([ fileType: ['image/'] } }, (data) => { - APP.getImageURL(data, function(url) { + APP.getImage(data, function(blob) { common.setPadAttribute('atime', +new Date(), null, data.href); resolve({ name: data.name, fileType: data.fileType, - url: url + blob: blob }); }); }); From bd0ace126183ef095a4387822b508f974c839922 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 12 Oct 2023 16:18:10 +0200 Subject: [PATCH 034/283] Adding an image from Nextcloud works --- www/common/sframe-app-framework.js | 61 +++++++++++++++++++++++++++++- www/common/sframe-common-outer.js | 5 +++ www/cryptpad-api.js | 6 ++- www/diagram/inner.js | 51 ++----------------------- www/integration/main.js | 8 +++- 5 files changed, 80 insertions(+), 51 deletions(-) diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index c0c4e9106..9ae44dc27 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -16,6 +16,7 @@ define([ '/common/inner/snapshots.js', '/customize/application_config.js', '/components/chainpad/chainpad.dist.js', + '/file/file-crypto.js', '/common/test.js', '/components/file-saver/FileSaver.min.js', @@ -38,7 +39,8 @@ define([ Feedback, Snapshots, AppConfig, - ChainPad /*, + ChainPad, + FileCrypto /*, /* Test */) { var SaveAs = window.saveAs; @@ -64,6 +66,7 @@ define([ var create = function (options, cb) { var evContentUpdate = Util.mkEvent(); var evIntegrationSave = Util.mkEvent(); + var evIntegrationInsertImage = Util.mkEvent(); var evCursorUpdate = Util.mkEvent(); var evEditableStateChange = Util.mkEvent(); var evOnReady = Util.mkEvent(true); @@ -643,6 +646,9 @@ define([ const integrationHasUnsavedChanges = function(unsavedChanges, cb) { sframeChan.query('Q_INTEGRATION_HAS_UNSAVED_CHANGES', unsavedChanges, cb); }; + const integrationOnInsertImage = function(data, cb) { + sframeChan.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, cb, {raw: true}); + }; var inte = common.createIntegration(onLocal, cpNfInner.chainpad, integrationSave, integrationHasUnsavedChanges); if (inte) { @@ -650,6 +656,7 @@ define([ evIntegrationSave.reg(function () { inte.changed(); }); + evIntegrationInsertImage.reg(integrationOnInsertImage); } if (firstConnection) { sframeChan.on('Q_INTEGRATION_NEEDSAVE', function (data, cb) { @@ -1119,6 +1126,58 @@ define([ // Call this after all of the handlers are setup. start: evStart.fire, + // Call this, when the user wants to add an image from drive. + insertImage: function(data, cb) { // TODO Move function somwhere else + if (integration) { + evIntegrationInsertImage.fire(data, cb); + return; + } + + const setBlobType = (blob, mimeType) => { + const fixedBlob = new Blob([blob], {type: mimeType}); + return fixedBlob; + }; + + const getImage = function(data, callback) { + Util.fetch(data.src, function (err, u8) { + if (err) { + console.error(err); + return void callback(""); + } + try { + FileCrypto.decrypt(u8, nacl.util.decodeBase64(data.key), (err, res) => { + if (err || !res.content) { + console.error("Decrypting failed"); + return void callback(""); + } + + callback(setBlobType(res.content, data.fileType)); + }); + } catch (e) { + console.error(e); + callback(""); + } + }, void 0, common.getCache()); + }; + + common.openFilePicker({ + types: ['file'], + where: ['root'], + filter: { + fileType: ['image/', 'application/x-drawio'] + } + }, (data) => { + getImage(data, function(blob) { + common.setPadAttribute('atime', +new Date(), null, data.href); + cb({ + name: data.name, + fileType: data.fileType, + blob: blob + }); + }); + }); + }, + // Determine the internal state of the framework. getState: function () { return state; }, diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 4ccda4b68..61b93f135 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -2009,6 +2009,11 @@ define([ cfg.integrationUtils.onHasUnsavedChanges(obj, cb); } }); + sframeChan.on('Q_INTEGRATION_ON_INSERT_IMAGE', function (data, cb) { + if (cfg.integrationUtils && cfg.integrationUtils.onInsertImage) { + cfg.integrationUtils.onInsertImage(data, cb); + } + }); integrationSave = function (cb) { sframeChan.query('Q_INTEGRATION_NEEDSAVE', null, cb); }; diff --git a/www/cryptpad-api.js b/www/cryptpad-api.js index 556bd5fd6..d66f2c6bb 100644 --- a/www/cryptpad-api.js +++ b/www/cryptpad-api.js @@ -162,6 +162,9 @@ config.events.onHasUnsavedChanges(unsavedChanges); cb(); }); + chan.on('ON_INSERT_IMAGE', function(data, cb) { + config.events.onInsertImage(data, cb); + }); }); }); @@ -180,6 +183,7 @@ * @param {object} config.events Event handlers. * @param {function} events.onSave (blob, callback) The save function to store the document when edited. * @param {function} events.onNewKey (data, callback) The function called when a new key is used. + * @param {function} events.onInsertImage (data, callback) The function called the user wants to add an image. * @param {string} config.documentType The editor to load in CryptPad. * @return {promise} */ @@ -202,7 +206,7 @@ if (!config) { return reject('Missing args: no data provided'); } if(['document.url', 'document.fileType', 'documentType', 'events.onSave', 'events.onHasUnsavedChanges', - 'events.onNewKey'].some(function (k) { + 'events.onNewKey', 'events.onInsertImage'].some(function (k) { var s = k.split('.'); var c = config; return s.some(function (key) { diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 89cab27dd..25b475cee 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -4,8 +4,6 @@ define([ '/customize/messages.js', // translation keys '/components/pako/dist/pako.min.js', '/components/x2js/x2js.js', - '/common/common-util.js', - '/file/file-crypto.js', '/components/tweetnacl/nacl-fast.min.js', 'less!/diagram/app-diagram.less', 'css!/diagram/drawio.css', @@ -13,9 +11,7 @@ define([ Framework, Messages, pako, - X2JS, - Util, - FileCrypto) { + X2JS) { const Nacl = window.nacl; const APP = window.APP = {}; @@ -127,50 +123,11 @@ define([ autosave: onDrawioAutosave, }; - const setBlobType = (blob, mimeType) => { - const fixedBlob = new Blob([blob], {type: mimeType}); - return fixedBlob; - }; - - APP.getImage = function(data, callback) { - Util.fetch(data.src, function (err, u8) { - if (err) { - console.error(err); - return void callback(""); - } - try { - FileCrypto.decrypt(u8, Nacl.util.decodeBase64(data.key), (err, res) => { - if (err || !res.content) { - console.error("Decrypting failed"); - return void callback(""); - } - - callback(setBlobType(res.content, data.fileType)); - }); - } catch (e) { - console.error(e); - callback(""); - } - }, void 0, common.getCache()); - }; - APP.addImage = function() { return new Promise((resolve) => { - common.openFilePicker({ - types: ['file'], - where: ['root'], - filter: { - fileType: ['image/'] - } - }, (data) => { - APP.getImage(data, function(blob) { - common.setPadAttribute('atime', +new Date(), null, data.href); - resolve({ - name: data.name, - fileType: data.fileType, - blob: blob - }); - }); + framework.insertImage({}, (_, image) => { + console.log('XXX image', image); + resolve(image); }); }); }; diff --git a/www/integration/main.js b/www/integration/main.js index c36c6869f..c4795bef1 100644 --- a/www/integration/main.js +++ b/www/integration/main.js @@ -10,7 +10,7 @@ define([ console.warn('INIT'); var p = window.parent; var txid = getTxid(); - p.postMessage(JSON.stringify({ q: 'INTEGRATION_READY', txid: txid }), '*'); + p.postMessage({ q: 'INTEGRATION_READY', txid: txid }, '*'); var makeChan = function () { var handlers = {}; @@ -118,6 +118,9 @@ define([ var onHasUnsavedChanges = function (unsavedChanges, cb) { chan.send('HAS_UNSAVED_CHANGES', unsavedChanges, cb); }; + var onInsertImage = function (data, cb) { + chan.send('ON_INSERT_IMAGE', data, cb); + }; chan.on('START', function (data) { console.warn('INNER START', data); @@ -135,7 +138,8 @@ define([ utils: { save: save, reload: reload, - onHasUnsavedChanges: onHasUnsavedChanges + onHasUnsavedChanges: onHasUnsavedChanges, + onInsertImage: onInsertImage } }; require(['/common/sframe-app-outer.js'], function () { From b1e8122ee4997e2196620b42df9a1714ff31c7e5 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Mon, 16 Oct 2023 12:47:47 +0200 Subject: [PATCH 035/283] Move image dialog to its own module --- www/common/image-dialog.js | 60 ++++++++++++++++++++++++++ www/common/sframe-app-framework.js | 67 ++++-------------------------- www/diagram/inner.js | 1 - 3 files changed, 68 insertions(+), 60 deletions(-) create mode 100644 www/common/image-dialog.js diff --git a/www/common/image-dialog.js b/www/common/image-dialog.js new file mode 100644 index 000000000..998e2057f --- /dev/null +++ b/www/common/image-dialog.js @@ -0,0 +1,60 @@ +define([ + '/common/common-util.js', + '/file/file-crypto.js', +], function( + Util, + FileCrypto, +) { + + const setBlobType = (blob, mimeType) => { + const fixedBlob = new Blob([blob], {type: mimeType}); + return fixedBlob; + }; + + const getImage = function(common, data, callback) { + Util.fetch(data.src, function (err, u8) { + if (err) { + console.error(err); + return void callback(""); + } + try { + FileCrypto.decrypt(u8, nacl.util.decodeBase64(data.key), (err, res) => { + if (err || !res.content) { + console.error("Decrypting failed"); + return void callback(""); + } + + callback(setBlobType(res.content, data.fileType)); + }); + } catch (e) { + console.error(e); + callback(""); + } + }, void 0, common.getCache()); + }; + + return { + openImageDialog: function(common, integrationChannel, data, cb) { + if (integrationChannel) { + integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, cb, {raw: true}); + return; + } + common.openFilePicker({ + types: ['file'], + where: ['root'], + filter: { + fileType: ['image/', 'application/x-drawio'] + } + }, (data) => { + getImage(data, function(blob) { + common.setPadAttribute('atime', +new Date(), null, data.href); + cb({ + name: data.name, + fileType: data.fileType, + blob: blob + }); + }); + }); + } + }; +}); diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 9ae44dc27..78d9bbb2f 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -16,7 +16,6 @@ define([ '/common/inner/snapshots.js', '/customize/application_config.js', '/components/chainpad/chainpad.dist.js', - '/file/file-crypto.js', '/common/test.js', '/components/file-saver/FileSaver.min.js', @@ -39,8 +38,7 @@ define([ Feedback, Snapshots, AppConfig, - ChainPad, - FileCrypto /*, + ChainPad /*, /* Test */) { var SaveAs = window.saveAs; @@ -66,7 +64,6 @@ define([ var create = function (options, cb) { var evContentUpdate = Util.mkEvent(); var evIntegrationSave = Util.mkEvent(); - var evIntegrationInsertImage = Util.mkEvent(); var evCursorUpdate = Util.mkEvent(); var evEditableStateChange = Util.mkEvent(); var evOnReady = Util.mkEvent(true); @@ -87,6 +84,7 @@ define([ var state = STATE.DISCONNECTED; var firstConnection = true; var integration; + let integrationChannel; var toolbarContainer = options.toolbarContainer || (function () { throw new Error("toolbarContainer must be specified"); }()); @@ -622,12 +620,12 @@ define([ if (privateDat.integration) { common.openIntegrationChannel(onLocal); - var sframeChan = common.getSframeChannel(); + integrationChannel = common.getSframeChannel(); var integrationSave = function (cb) { var ext = privateDat.integrationConfig.fileType; var upload = Util.once(function (_blob) { - sframeChan.query('Q_INTEGRATION_SAVE', { + integrationChannel.query('Q_INTEGRATION_SAVE', { blob: _blob }, cb, { raw: true @@ -644,10 +642,7 @@ define([ } }; const integrationHasUnsavedChanges = function(unsavedChanges, cb) { - sframeChan.query('Q_INTEGRATION_HAS_UNSAVED_CHANGES', unsavedChanges, cb); - }; - const integrationOnInsertImage = function(data, cb) { - sframeChan.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, cb, {raw: true}); + integrationChannel.query('Q_INTEGRATION_HAS_UNSAVED_CHANGES', unsavedChanges, cb); }; var inte = common.createIntegration(onLocal, cpNfInner.chainpad, integrationSave, integrationHasUnsavedChanges); @@ -656,10 +651,9 @@ define([ evIntegrationSave.reg(function () { inte.changed(); }); - evIntegrationInsertImage.reg(integrationOnInsertImage); } if (firstConnection) { - sframeChan.on('Q_INTEGRATION_NEEDSAVE', function (data, cb) { + integrationChannel.on('Q_INTEGRATION_NEEDSAVE', function (data, cb) { integrationSave(function (obj) { if (obj && obj.error) { console.error(obj.error); } cb(); @@ -1128,53 +1122,8 @@ define([ // Call this, when the user wants to add an image from drive. insertImage: function(data, cb) { // TODO Move function somwhere else - if (integration) { - evIntegrationInsertImage.fire(data, cb); - return; - } - - const setBlobType = (blob, mimeType) => { - const fixedBlob = new Blob([blob], {type: mimeType}); - return fixedBlob; - }; - - const getImage = function(data, callback) { - Util.fetch(data.src, function (err, u8) { - if (err) { - console.error(err); - return void callback(""); - } - try { - FileCrypto.decrypt(u8, nacl.util.decodeBase64(data.key), (err, res) => { - if (err || !res.content) { - console.error("Decrypting failed"); - return void callback(""); - } - - callback(setBlobType(res.content, data.fileType)); - }); - } catch (e) { - console.error(e); - callback(""); - } - }, void 0, common.getCache()); - }; - - common.openFilePicker({ - types: ['file'], - where: ['root'], - filter: { - fileType: ['image/', 'application/x-drawio'] - } - }, (data) => { - getImage(data, function(blob) { - common.setPadAttribute('atime', +new Date(), null, data.href); - cb({ - name: data.name, - fileType: data.fileType, - blob: blob - }); - }); + require(['/common/image-dialog.js'], function(imageDialog) { + imageDialog.openImageDialog(common, integrationChannel, data, cb); }); }, diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 25b475cee..112ebd11d 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -126,7 +126,6 @@ define([ APP.addImage = function() { return new Promise((resolve) => { framework.insertImage({}, (_, image) => { - console.log('XXX image', image); resolve(image); }); }); From 2d63fec04009d4e7c78b6d0eb82d709f70829b25 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 17 Oct 2023 10:19:26 +0200 Subject: [PATCH 036/283] Fix image import from cryptpad --- www/common/image-dialog.js | 5 +++-- www/diagram/inner.js | 2 +- www/integration/main.js | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/www/common/image-dialog.js b/www/common/image-dialog.js index 998e2057f..246f7f387 100644 --- a/www/common/image-dialog.js +++ b/www/common/image-dialog.js @@ -36,7 +36,8 @@ define([ return { openImageDialog: function(common, integrationChannel, data, cb) { if (integrationChannel) { - integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, cb, {raw: true}); + const ignoreFirstParam = (_, image) => cb(image); + integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, ignoreFirstParam, {raw: true}); return; } common.openFilePicker({ @@ -46,7 +47,7 @@ define([ fileType: ['image/', 'application/x-drawio'] } }, (data) => { - getImage(data, function(blob) { + getImage(common, data, function(blob) { common.setPadAttribute('atime', +new Date(), null, data.href); cb({ name: data.name, diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 112ebd11d..4359f45d3 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -125,7 +125,7 @@ define([ APP.addImage = function() { return new Promise((resolve) => { - framework.insertImage({}, (_, image) => { + framework.insertImage({}, (image) => { resolve(image); }); }); diff --git a/www/integration/main.js b/www/integration/main.js index c4795bef1..fb3cfadce 100644 --- a/www/integration/main.js +++ b/www/integration/main.js @@ -34,6 +34,7 @@ define([ // On new command var msg = data.msg; + if (!msg) { return; } var txid = data.txid; if (commands[msg.q]) { commands[msg.q](msg.data, function (args) { From 2611785a500c33630be2aaedc6f9b539428e2449 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 17 Oct 2023 13:48:53 +0200 Subject: [PATCH 037/283] Fix draw.io dependency --- package-lock.json | 34 ++++++++++++++++++---------------- package.json | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index cd746d06e..2b6f0c305 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio-cp": "../drawio-npm", + "drawio-cp": "github:cryptpad/drawio-npm#npm-21.8.2", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -68,9 +68,6 @@ "url": "https://opencollective.com/cryptpad" } }, - "../drawio-npm": { - "version": "21.7.5" - }, "node_modules/@mcrowe/minibloom": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mcrowe/minibloom/-/minibloom-0.2.0.tgz", @@ -1889,9 +1886,12 @@ "dev": true }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gar": { "version": "1.0.4", @@ -2023,12 +2023,9 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "engines": { "node": ">= 0.4.0" } @@ -3186,9 +3183,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.0.tgz", + "integrity": "sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4592,6 +4589,11 @@ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", diff --git a/package.json b/package.json index a9b646d76..8ced5f4a5 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio-cp": "../drawio-npm", + "drawio-cp": "github:cryptpad/drawio-npm#npm-21.8.2", "pako": "^2.1.0", "x2js": "^3.4.4" }, From 7f55498bcc5c47e9f8e70a7fce44e5c623165641 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 17 Oct 2023 14:09:07 +0200 Subject: [PATCH 038/283] Update draw.io dependency and remove unneeded CSP headers --- docs/example-advanced.nginx.conf | 4 ++-- lib/defaults.js | 4 ---- lib/http-worker.js | 4 ---- package-lock.json | 2 +- package.json | 2 +- scripts/copy-components.js | 2 +- www/diagram/inner.js | 2 +- 7 files changed, 6 insertions(+), 14 deletions(-) diff --git a/docs/example-advanced.nginx.conf b/docs/example-advanced.nginx.conf index b3b8d36f1..16d45087a 100644 --- a/docs/example-advanced.nginx.conf +++ b/docs/example-advanced.nginx.conf @@ -163,8 +163,8 @@ server { if ($uri ~ ^\/unsafeiframe\/inner\.html.*$) { set $unsafe 1; } # draw.io uses inline script tags in it's index.html. The hashes are added here. - if ($uri ~ ^\/components\/drawio-cp\/src\/main\/webapp\/index.html.*$) { - set $scriptSrc "'self' 'sha256-dLMFD7ijAw6AVaqecS7kbPcFFzkxQ+yeZSsKpOdLxps=' 'sha256-6g514VrT/cZFZltSaKxIVNFF46+MFaTSDTPB8WfYK+c=' resource: https://${main_domain}"; + if ($uri ~ ^\/components\/drawio\/src\/main\/webapp\/index.html.*$) { + set $scriptSrc "'self' resource: https://${main_domain}"; } # privileged contexts allow a few more rights than unprivileged contexts, though limits are still applied diff --git a/lib/defaults.js b/lib/defaults.js index 969842189..ef85e9470 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -48,10 +48,6 @@ Default.padContentSecurity = function (Env) { return (Default.commonCSP(Env).join('; ') + "script-src 'self' 'unsafe-eval' 'unsafe-inline' resource: " + Env.httpUnsafeOrigin).replace(/\s+/g, ' '); }; -Default.diagramContentSecurity = function (Env) { - return (Default.commonCSP(Env).join('; ') + "script-src 'self' 'sha256-dLMFD7ijAw6AVaqecS7kbPcFFzkxQ+yeZSsKpOdLxps=' 'sha256-6g514VrT/cZFZltSaKxIVNFF46+MFaTSDTPB8WfYK+c=' resource: " + Env.httpUnsafeOrigin).replace(/\s+/g, ' '); -}; - Default.httpHeaders = function (Env) { return { "X-XSS-Protection": "1; mode=block", diff --git a/lib/http-worker.js b/lib/http-worker.js index a88d3d713..8bc11800c 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -123,8 +123,6 @@ var getHeaders = function (Env, type) { var csp; if (type === 'office') { csp = Default.padContentSecurity(Env); - } else if (type === 'diagram') { - csp = Default.diagramContentSecurity(Env); } else { csp = Default.contentSecurity(Env); } @@ -147,8 +145,6 @@ var setHeaders = function (req, res) { type = 'office'; } else if (/^\/api\/(broadcast|config)/.test(req.url)) { type = 'api'; - } else if (/^\/components\/drawio-cp\/src\/main\/webapp\/index.html.*$/.test(req.url)) { - type = 'diagram'; } else { type = 'standard'; } diff --git a/package-lock.json b/package-lock.json index 2b6f0c305..46e21f23e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio-cp": "github:cryptpad/drawio-npm#npm-21.8.2", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", diff --git a/package.json b/package.json index 8ced5f4a5..f1f36b015 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio-cp": "github:cryptpad/drawio-npm#npm-21.8.2", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/scripts/copy-components.js b/scripts/copy-components.js index 24831aca7..cd0903373 100644 --- a/scripts/copy-components.js +++ b/scripts/copy-components.js @@ -40,7 +40,7 @@ Fse.rmSync(oldComponentsPath, { recursive: true, force: true }); "saferphore", "nthen", "netflux-websocket", - "drawio-cp", + "drawio", "pako", "x2js" ].forEach(l => { diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 4359f45d3..411ad21b6 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -178,7 +178,7 @@ define([ // starting the CryptPad framework framework.start(); - drawioFrame.src = '/components/drawio-cp/src/main/webapp/index.html?' + drawioFrame.src = '/components/drawio/src/main/webapp/index.html?' + new URLSearchParams({ test: 1, stealth: 1, From e7142962a6d43574a8d86332565b6338c0b14014 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 17 Oct 2023 16:47:23 +0200 Subject: [PATCH 039/283] Fix package-lock after rebase --- package-lock.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46e21f23e..cb1761aaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -914,9 +914,9 @@ }, "node_modules/ckeditor": { "name": "ckeditor4", - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.23.0.tgz", - "integrity": "sha512-K9DUzTa7roj8JffKLm6nOxDF02aPURDK8m7oFibvvkyAaomj24qOgpVdt7yvszmIubeJLbAB6q4k7Euk8jzD1A==" + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/ckeditor4/-/ckeditor4-4.22.1.tgz", + "integrity": "sha512-Yj4vTHX5YxHwc48gNqUqTm+KLkRr9tuyb4O2VIABu4oKHWRNVIdLdy6vUNe/XNx+RiTavMejfA1MVOU/MxLjqQ==" }, "node_modules/class-utils": { "version": "0.3.6", @@ -4589,11 +4589,6 @@ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, - "node_modules/undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" - }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", From dc0bf5533d3cf6793748035c150022c268525e35 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Wed, 18 Oct 2023 15:35:05 +0200 Subject: [PATCH 040/283] Correct wording for integrated diagram --- package-lock.json | 27 +++++++++++++++++---------- package.json | 2 +- www/common/sframe-app-framework.js | 4 +++- www/diagram/inner.js | 2 +- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb1761aaa..d7547442c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+1", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -106,9 +106,9 @@ } }, "node_modules/@types/http-proxy": { - "version": "1.17.12", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.12.tgz", - "integrity": "sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw==", + "version": "1.17.13", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.13.tgz", + "integrity": "sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw==", "dependencies": { "@types/node": "*" } @@ -120,9 +120,12 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.3.tgz", - "integrity": "sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==" + "version": "20.8.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", + "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "dependencies": { + "undici-types": "~5.25.1" + } }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", @@ -1344,9 +1347,8 @@ } }, "node_modules/drawio": { - "name": "drawio-cp", - "version": "21.7.5", - "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#b430ab78be9944f19721c3489c9ce95bc1abe2ca" + "version": "21.8.2+1", + "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#c1708e16bb816dd3bc9b95bd8f3ecf33216d8597" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", @@ -4589,6 +4591,11 @@ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", diff --git a/package.json b/package.json index f1f36b015..cecc49fd1 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+1", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 78d9bbb2f..27147ce51 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -1121,7 +1121,7 @@ define([ start: evStart.fire, // Call this, when the user wants to add an image from drive. - insertImage: function(data, cb) { // TODO Move function somwhere else + insertImage: function(data, cb) { require(['/common/image-dialog.js'], function(imageDialog) { imageDialog.openImageDialog(common, integrationChannel, data, cb); }); @@ -1130,6 +1130,8 @@ define([ // Determine the internal state of the framework. getState: function () { return state; }, + isIntegrated: function() { return cpNfInner.metadataMgr.getPrivateData().integration; }, + // Internals _: { sfCommon: common, diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 411ad21b6..f7b2c83ac 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -184,8 +184,8 @@ define([ stealth: 1, embed: 1, drafts: 0, - // plugins: 0, p: 'cryptpad', + integrated: framework.isIntegrated() ? 'true' : 'false', chrome: framework.isReadOnly() ? 0 : 1, dark: window.CryptPad_theme === "dark" ? 1 : 0, From 98735a2f6ca1b610324353d71e53a1d64d92aad3 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 19 Oct 2023 08:52:30 +0200 Subject: [PATCH 041/283] Fix lint warnings --- www/common/image-dialog.js | 4 +++- www/common/onlyoffice/inner.js | 1 - www/diagram/inner.js | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/www/common/image-dialog.js b/www/common/image-dialog.js index 246f7f387..df7d13aea 100644 --- a/www/common/image-dialog.js +++ b/www/common/image-dialog.js @@ -1,9 +1,11 @@ +/* globals nacl */ + define([ '/common/common-util.js', '/file/file-crypto.js', ], function( Util, - FileCrypto, + FileCrypto ) { const setBlobType = (blob, mimeType) => { diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 6de5d2e68..874f30938 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -1365,7 +1365,6 @@ define([ endSaveChanges: true, isExcel: true, deleteIndex: null, - excelAdditionalInfo: null, unlock: false, releaseLocks: true, reSave: true, diff --git a/www/diagram/inner.js b/www/diagram/inner.js index f7b2c83ac..1ac1a5bed 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -56,7 +56,6 @@ define([ // This is the main initialization loop var onFrameworkReady = function (framework) { - const common = framework._.sfCommon; var EMPTY_DRAWIO = ""; var drawioFrame = document.querySelector('#cp-app-diagram-content'); var x2js = new X2JS(); From 210606758b1e832dc33c5e3208c74de8c229f5fe Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 6 Nov 2023 13:28:28 +0100 Subject: [PATCH 042/283] Detect and compute timezone errors due to Daylight Saving Time --- www/calendar/recurrence.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/www/calendar/recurrence.js b/www/calendar/recurrence.js index bd3fa0519..6a0cdff01 100644 --- a/www/calendar/recurrence.js +++ b/www/calendar/recurrence.js @@ -578,6 +578,38 @@ define([ return r; }).filter(Boolean); }; + + var fixTimeZone = function (evTimeZone, origin, target) { + var getOffset = function (date, tz) { + // Get an ISO string using Canadian local format + let iso = date.toLocaleString('en-CA', { timeZone:tz, hour12: false }).replace(', ', 'T'); + iso += '.' + date.getMilliseconds().toString().padStart(3, '0'); + + // Get a UTC version of this time + let utcDate = new Date(iso + 'Z'); + + // Return the difference in timestamps, as minutes (60*1000) + return -(utcDate - date); + } + + var myTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; + var offset = getOffset(origin, evTimeZone) - getOffset(target, evTimeZone); + var myOffset = getOffset(origin, myTimeZone) - getOffset(target, myTimeZone); + + return offset - myOffset; + }; +/* +XXX to test + var first = new Date(2023, 09, 10, 15) + var second = new Date(2023, 09, 30, 15) + fixTimeZone('America/New_York', first, second) ==> should return +1h + +*/ + + + + + Rec.getRecurring = function (months, events) { if (window.CP_DEV_MODE) { debug = console.warn; } From ed97d28528cc905544a257ef99ffbb1d82700d47 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 6 Nov 2023 16:27:52 +0100 Subject: [PATCH 043/283] Make SSO plugin optional --- lib/archive-account.js | 5 +- lib/challenge-commands/sso.js | 303 --------------------------------- lib/challenge-commands/totp.js | 5 +- lib/commands/admin-rpc.js | 7 +- lib/commands/block.js | 4 +- lib/http-commands.js | 15 +- lib/http-worker.js | 6 +- lib/plugins/sso/oidc.js | 85 --------- lib/plugins/sso/saml.js | 80 --------- lib/sso-utils.js | 225 ------------------------ scripts/saml-metadata.js | 16 -- 11 files changed, 27 insertions(+), 724 deletions(-) delete mode 100644 lib/challenge-commands/sso.js delete mode 100644 lib/plugins/sso/oidc.js delete mode 100644 lib/plugins/sso/saml.js delete mode 100644 lib/sso-utils.js delete mode 100644 scripts/saml-metadata.js diff --git a/lib/archive-account.js b/lib/archive-account.js index 56d90ba7f..31256336b 100644 --- a/lib/archive-account.js +++ b/lib/archive-account.js @@ -9,7 +9,8 @@ const Core = require("./commands/core"); const Metadata = require("./commands/metadata"); const Meta = require("./metadata"); const Logger = require("./log"); -const SSOUtils = require('./sso-utils'); + +let SSOUtils; try { SSOUtils = require("./plugins/sso/sso-utils"); } catch (e) {} const Path = require("path"); const Fse = require("fs-extra"); @@ -197,6 +198,7 @@ COMMANDS.start = (edPublic, blockId, reason) => { } Log.info('MODERATION_ACCOUNT_BLOCK', safeKey, waitFor()); })); + if (!SSOUtils) { return; } SSOUtils.deleteAccount(Env, blockId, waitFor((err) => { if (err) { return Log.error('MODERATION_ACCOUNT_BLOCK_SSO', err, waitFor()); @@ -291,6 +293,7 @@ COMMANDS.restore = (edPublic) => { } Log.info('MODERATION_ACCOUNT_BLOCK_RESTORE', safeKey, waitFor()); })); + if (!SSOUtils) { return; } SSOUtils.restoreAccount(Env, blockId, waitFor(function (err) { if (err) { return Log.error('MODERATION_ACCOUNT_BLOCK_RESTORE_SSO', err, waitFor()); diff --git a/lib/challenge-commands/sso.js b/lib/challenge-commands/sso.js deleted file mode 100644 index fe1dcf266..000000000 --- a/lib/challenge-commands/sso.js +++ /dev/null @@ -1,303 +0,0 @@ -const Util = require("../common-util"); -const Commands = module.exports; -const SSOUtils = require('../sso-utils'); -const nThen = require("nthen"); -const BlockStore = require("../storage/block"); -const Block = require("../commands/block"); - -const TYPES = SSOUtils.TYPES; -const checkConfig = SSOUtils.checkConfig; -const getProviderConfig = SSOUtils.getProviderConfig; -const isValidConfig = SSOUtils.isValidConfig; - - -// Create an SSO authentication request -const auth = Commands.SSO_AUTH = function (Env, body, cb) { - if (!checkConfig(Env)) { return void cb('INVALID_SERVER_CONFIG'); } - const { provider } = body; - const cfg = getProviderConfig(Env, provider); - if (!cfg) { return void cb('UNRECOGNIZED_IDP'); } - if (!isValidConfig(cfg)) { return void cb('INVALID_IDP_CONFIG'); } - - cb(); -}; -auth.complete = function (Env, body, cb, req, res) { - // If we're here it means a valid provider was given. We can start the authentication process - const { provider, register, publicKey } = body; - const cfg = getProviderConfig(Env, provider); - const idp = TYPES[cfg.type.toLowerCase()]; - idp.auth(Env, cfg, (err, obj) => { - if (err) { return void cb(err); } // TODO log - - let { url, token } = obj; - - if (!token) { token = Util.uid() + Util.uid(); } - - SSOUtils.writeRequest(Env, { - id: token, - type: idp.type, - provider: provider, - publicKey: publicKey, - register: Boolean(register) - }, (err) => { - if (err) { return void cb("E_REQ_WRITE"); } - - let value = `ssotoken="${token}"; SameSite=Strict; HttpOnly`; - res.setHeader('Set-Cookie', value); - cb(void 0, {url: url}); - }); - }); -}; - -// Receive authentication data from the IdP. -// Read the auth request, create a JWT and get a block seed for this SSO user. -const authCb = Commands.SSO_AUTH_CB = function (Env, body, cb, req) { - if (!checkConfig(Env)) { return void cb('INVALID_SERVER_CONFIG'); } - const { publicKey } = body; - const cookies = req.cookies; - const ssotoken = cookies.ssotoken; - if (!ssotoken) { return void cb('NO_COOKIE'); } - SSOUtils.readRequest(Env, ssotoken, (err, value) => { - if (err) { return void cb('ENOENT'); } - const data = Util.tryParse(value); - if (!data || !data.type || !TYPES[data.type]) { return void cb('INVALID_REQUEST_DATA'); } - if (data.type !== 'saml' && publicKey !== data.publicKey) { return void cb('WRONG_SIGNATURE_KEYS'); } - cb(); - }); -}; -authCb.complete = function (Env, body, cb, req) { - // If we're here it means a valid cookie was given. We can continue the authentication - const { url } = body; - const cookies = req.cookies; - const ssotoken = cookies.ssotoken; - if (!ssotoken) { return void cb('NO_COOKIE'); } - SSOUtils.readRequest(Env, ssotoken, (err, value) => { - SSOUtils.deleteRequest(Env, ssotoken); - if (err) { return void cb('ENOENT'); } - const data = Util.tryParse(value); - const cfg = getProviderConfig(Env, data.provider); - const idp = TYPES[data.type]; - const register = data.register; - const provider = data.provider; - idp.authCb(Env, cfg, ssotoken, url, cookies, (err, obj) => { - if (err) { return void cb(err); } - const {id, idpData, name} = obj; - - let next = (user, isRegister) => { - SSOUtils.createJWT(Env, id, provider, idpData, (err, jwt) => { - if (err) { return void cb(err); } - cb(void 0, { - jwt: jwt, - name: name, - seed: user.seed, - password: Boolean(user.password), - register: isRegister - }); - }); - }; - - if (register) { - SSOUtils.writeUser(Env, provider, id, (err, userData) => { - if (err && err.code === 'EEXIST') { - return void SSOUtils.readUser(Env, provider, id, (err, userData) => { - if (err) { return void cb(err); } - next(userData, !userData.complete); - }); - } - if (err) { return void cb(err); } - next(userData, true); - }); - } else { - SSOUtils.readUser(Env, provider, id, (err, userData) => { - if (err) { return void cb(err); } - if (!userData || !userData.complete) { - return void cb('NO_USER'); - } - next(userData, false); - }); - } - }); - }); -}; - -// XXX write block change-password? should be the same as otp but without otp code -const register = Commands.SSO_WRITE_BLOCK = function (Env, body, cb) { - const { publicKey, content } = body; - - // they must provide a valid block public key - if (!Block.isValidBlockId(publicKey)) { return void cb("INVALID_KEY"); } - if (publicKey !== content.publicKey) { return void cb("INVALID_KEY"); } - const jwt = content.auth; - if (!jwt) { return void cb('NO_JWT'); } - - BlockStore.isAvailable(Env, publicKey, (err, result) => { - if (err || result) { - return void cb(err || 'EEXISTS'); - } - // No block at this location: continue - cb(); - }); -}; -register.complete = function (Env, body, cb) { - const { publicKey, content } = body; - const jwt = content.auth; - const pw = content.hasPassword; - let payload; - let ssoUser; - // XXX UPDATE sso_user add password boolean - nThen((w) => { - SSOUtils.checkJWT(Env, jwt, w((err, _payload) => { - if (err) { - w.abort(); - return void cb('INVALID_JWT_SIGNATURE'); - } - payload = _payload; - })); - }).nThen((w) => { - const { sub, provider } = payload; - SSOUtils.readUser(Env, provider, sub, w((err, user) => { - if (err) { - w.abort(); - console.log(err, sub); - return void cb('SSO_NO_USER'); - } - ssoUser = user; - })); - }).nThen((w) => { - const { sub, provider } = payload; - SSOUtils.writeBlock(Env, publicKey, provider, sub, w((err) => { - if (err) { - w.abort(); - return void cb('SSO_BLOCK_WRITE'); - } - })); - }).nThen((w) => { - Block.writeLoginBlock(Env, content, w((err) => { - if (err) { w.abort(); } - })); - }).nThen((w) => { - const { sub, provider } = payload; - ssoUser.password = Boolean(pw); - ssoUser.complete = true; - SSOUtils.updateUser(Env, provider, sub, ssoUser, w()); - }).nThen(() => { - const { data, sub, provider } = payload; - let session = Util.clone(data); - session.id = sub; - SSOUtils.makeSession(Env, publicKey, provider, session, cb); - }); -}; - -const login = Commands.SSO_VALIDATE = function (Env, body, cb) { - const { publicKey, jwt } = body; - - // they must provide a valid block public key - if (!Block.isValidBlockId(publicKey)) { return void cb("INVALID_KEY"); } - if (!jwt) { return void cb('NO_JWT'); } - - BlockStore.isAvailable(Env, publicKey, (err, result) => { - if (err && !result) { return void cb(err); } - // Block found - cb(); - }); -}; -login.complete = function (Env, body, cb) { - const { publicKey, jwt } = body; - - let payload; - nThen((w) => { - SSOUtils.checkJWT(Env, jwt, w((err, _payload) => { - if (err) { - w.abort(); - return void cb('INVALID_JWT_SIGNATURE'); - } - payload = _payload; - })); - }).nThen((w) => { - const { sub, provider } = payload; - SSOUtils.readUser(Env, provider, sub, w((err) => { - if (err) { - w.abort(); - console.log(err, sub); - return void cb('SSO_NO_USER'); - } - })); - }).nThen((w) => { - SSOUtils.readBlock(Env, publicKey, w((err) => { - if (err) { - w.abort(); - return void cb('SSO_BLOCK_WRITE'); - } - })); - }).nThen(() => { - const { data, sub, provider } = payload; - let session = Util.clone(data); - session.id = sub; - SSOUtils.makeSession(Env, publicKey, provider, session, cb); - }); -}; - -const update = Commands.SSO_UPDATE_BLOCK = function (Env, body, cb) { - const { publicKey, ancestorProof } = body; - - // they must provide a valid block public key - if (!Block.isValidBlockId(publicKey)) { return void cb("INVALID_KEY"); } - - let oldKey; - nThen((w) => { - BlockStore.isAvailable(Env, publicKey, w((err, result) => { - if (err && !result) { - w.abort(); - return void cb(err); - } - // Block found: next - })); - }).nThen((w) => { - Block.validateAncestorProof(Env, ancestorProof, w((err, provenKey) => { - if (err) { - w.abort(); - return void cb(err); - } - // Ancestor found and proven - oldKey = provenKey; - })); - }).nThen(() => { - SSOUtils.readBlock(Env, oldKey, (err) => { - if (err) { - return void cb('INVALID_OLD_BLOCK'); - } - cb(); - }); - }); -}; -update.complete = function (Env, body, cb) { - const { publicKey, ancestorProof } = body; - - // We've already proven that the "proof" is valid so we can extract its key - const proof = Util.tryParse(ancestorProof); - const oldKey = proof && proof[0]; - - let oldBlock; - nThen((w) => { - SSOUtils.readBlock(Env, oldKey, w((err, data) => { - if (err || !data) { - w.abort(); - return void cb('INVALID_OLD_BLOCK'); - } - if (!data.id) { - w.abort(); - return void cb('INVALID_SSO_BLOCK_CONTENT'); - } - oldBlock = data; - })); - }).nThen((w) => { - SSOUtils.writeBlock(Env, publicKey, oldBlock.provider, oldBlock.id, w((err) => { - if (err) { - w.abort(); - return void cb('SSO_UPDATE_BLOCK_WRITE'); - } - })); - }).nThen(() => { - cb(); - }); -}; diff --git a/lib/challenge-commands/totp.js b/lib/challenge-commands/totp.js index b0761ca44..61fd2f7af 100644 --- a/lib/challenge-commands/totp.js +++ b/lib/challenge-commands/totp.js @@ -8,7 +8,8 @@ const MFA = require("../storage/mfa"); const Sessions = require("../storage/sessions"); const BlockStore = require("../storage/block"); const Block = require("../commands/block"); -const SSOUtils = require("../sso-utils"); + +let SSOUtils; try { SSOUtils = require("../plugins/sso/sso-utils"); } catch (e) {} const Commands = module.exports; @@ -72,7 +73,7 @@ const makeSession = (Env, publicKey, oldKey, ssoSession, cb) => { let isUpdate = false; nThen(function (w) { - if (!ssoSession) { return; } + if (!ssoSession || !SSOUtils) { return; } // If we have an session token, confirm this is an sso account SSOUtils.readBlock(Env, oldKey, w((err) => { if (err === 'ENOENT') { return; } // No sso block, no need to update the session diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 4e9ed319e..55f5b7a9d 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -11,11 +11,12 @@ const Channel = require("./channel"); const BlockStore = require("../storage/block"); const MFA = require("../storage/mfa"); const ArchiveAccount = require('../archive-account'); -const SSOUtils = require("../sso-utils"); /* jshint ignore:start */ 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; @@ -723,7 +724,7 @@ var archiveBlock = function (Env, Server, cb, data) { }); cb(err); }); - SSOUtils.deleteAccount(Env, key, () => {}); + if (SSOUtils) { SSOUtils.deleteAccount(Env, key, () => {}); } }; var restoreArchivedBlock = function (Env, Server, cb, data) { @@ -740,7 +741,7 @@ var restoreArchivedBlock = function (Env, Server, cb, data) { }); // Also restore SSO data - SSOUtils.restoreAccount(Env, key, () => {}); + if (SSOUtils) { SSOUtils.restoreAccount(Env, key, () => {}); } cb(err); }); diff --git a/lib/commands/block.js b/lib/commands/block.js index 2fffb998a..18e1d21a6 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -5,7 +5,8 @@ const Nacl = require("tweetnacl/nacl-fast"); const nThen = require("nthen"); const Util = require("../common-util"); const BlockStore = require("../storage/block"); -const SSOUtils = require("../sso-utils"); + +let SSOUtils; try { SSOUtils = require("../plugins/sso/sso-utils"); } catch (e) {} var isString = s => typeof(s) === 'string'; Block.isValidBlockId = id => { @@ -190,6 +191,7 @@ Block.removeLoginBlock = function (Env, publicKey, reason, _cb) { // is already deleted anyway. // If this is NOT a password change, also delete sso user. + if (!SSOUtils) { return; } if (reason !== 'PASSWORD_CHANGE') { SSOUtils.deleteAccount(Env, publicKey, () => {}); } else { diff --git a/lib/http-commands.js b/lib/http-commands.js index e573d5b83..dcac23421 100644 --- a/lib/http-commands.js +++ b/lib/http-commands.js @@ -73,12 +73,15 @@ COMMANDS.TOTP_REVOKE = TOTP.TOTP_REVOKE; COMMANDS.TOTP_WRITE_BLOCK = TOTP.TOTP_WRITE_BLOCK; // Password change only for now (v5.5.0) COMMANDS.TOTP_REMOVE_BLOCK = TOTP.TOTP_REMOVE_BLOCK; -const SSO = require("./challenge-commands/sso.js"); -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 -COMMANDS.SSO_UPDATE_BLOCK = SSO.SSO_UPDATE_BLOCK; // Password change -COMMANDS.SSO_VALIDATE = SSO.SSO_VALIDATE; +try { + // SSO plugin may not be installed + const SSO = require("./plugins/sso/challenge.js"); + 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 + COMMANDS.SSO_UPDATE_BLOCK = SSO.SSO_UPDATE_BLOCK; // Password change + COMMANDS.SSO_VALIDATE = SSO.SSO_VALIDATE; +} catch (e) {} var randomToken = () => Nacl.util.encodeBase64(Nacl.randomBytes(24)).replace(/\//g, '-'); diff --git a/lib/http-worker.js b/lib/http-worker.js index de3b93437..2c375774a 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -8,7 +8,6 @@ const Util = require("./common-util"); const Logger = require("./log"); const AuthCommands = require("./http-commands"); const MFA = require("./storage/mfa"); -const SSOUtils = require("./sso-utils"); const Sessions = require("./storage/sessions"); const cookieParser = require("cookie-parser"); const bodyParser = require('body-parser'); @@ -18,6 +17,8 @@ const BlockStore = require("./storage/block"); const DEFAULT_QUERY_TIMEOUT = 5000; const PID = process.pid; +let SSOUtils; try { SSOUtils = require("./plugins/sso/sso-utils"); } catch (e) {} + var Env = JSON.parse(process.env.Env); const response = Util.response(function (errLabel, info) { if (!Env.Log) { return; } @@ -204,7 +205,7 @@ const wsProxy = createProxyMiddleware({ app.use('/cryptpad_websocket', wsProxy); app.use('/ssoauth', (req, res, next) => { - if (req && req.body && req.body.SAMLResponse) { + if (SSOUtils && req && req.body && req.body.SAMLResponse) { req.method = 'GET'; let token = Util.uid(); @@ -373,6 +374,7 @@ app.use('/block/', function (req, res, next) { })); // Same for SSO settings + if (!SSOUtils) { return; } SSOUtils.readBlock(Env, name, w(function (err, content) { if (err && err.code === 'ENOENT') { return; diff --git a/lib/plugins/sso/oidc.js b/lib/plugins/sso/oidc.js deleted file mode 100644 index 5fc8bc052..000000000 --- a/lib/plugins/sso/oidc.js +++ /dev/null @@ -1,85 +0,0 @@ -const OID = require('openid-client'); -const SSOUtils = require('../../sso-utils'); - -const TYPE = 'oidc'; - -const opts = SSOUtils.getOptions(); -const getClient = (cfg, cb) => { - OID.Issuer.discover(cfg.url).then((issuer) => { // XXX Only once for all users? - let alg = cfg.jwt_alg || 'PS256'; - if (Array.isArray(issuer.id_token_signing_alg_values_supported) && - !issuer.id_token_signing_alg_values_supported.includes(alg)) { - alg = issuer.id_token_signing_alg_values_supported[0] || 'RS256'; - } - const client = new issuer.Client({ - client_id: cfg.client_id, - client_secret: cfg.client_secret, - redirect_uris: [opts.callbackURL], - response_types: ['code'], - id_token_signed_response_alg: alg - }); - cb(void 0, client); - }, (err) => { - cb(err); - }); -}; -module.exports = { - type: TYPE, - checkConfig: (cfg) => { - return cfg.url && cfg.client_id && cfg.client_secret; - }, - auth: (Env, cfg, cb) => { - getClient(cfg, (err, client) => { - if (err) { return void cb ('E_OIDC_CONNECT'); } - - const generators = OID.generators; - const code_verifier = generators.codeVerifier(); - const code_challenge = generators.codeChallenge(code_verifier); - const url = client.authorizationUrl({ - scope: 'openid email profile', - resource: opts.callbackURL, - access_type: 'offline', - code_challenge, - code_challenge_method: 'S256', - }); - - cb(void 0, { url: url, token: code_verifier }); - }); - }, - authCb: (Env, cfg, token, url, cookies, cb) => { - getClient(cfg, (err, client) => { - if (err) { return void cb ('E_OIDC_CONNECT'); } - - const params = client.callbackParams(url); - delete params.state; - client.callback('http://localhost:3000/ssoauth', params, { code_verifier: token }) - .then((tokenSet) => { - let j = tokenSet; - let c = tokenSet.claims(); - let name = c.name; - const end = () => { - cb(void 0, { - id: c.sub, - name: name, - idpData: { - expires_at: j.expires_at, - access_token: j.access_token, - refresh_token: j.refresh_token, - //id_token: j.id_token // XXX no need to store id_token? - } - }); - }; - if (name) { return void end(); } - let t = client.userinfo(j.access_token).then((data) => { - name = data.name; - end(); - console.log(t); - }, (err) => { - console.error(err); - name = 'Unknown'; // XXX - end(); - }); - }); - }); - }, -}; diff --git a/lib/plugins/sso/saml.js b/lib/plugins/sso/saml.js deleted file mode 100644 index 1b7333db8..000000000 --- a/lib/plugins/sso/saml.js +++ /dev/null @@ -1,80 +0,0 @@ -const { SAML } = require('@node-saml/node-saml'); -const SSOUtils = require('../../sso-utils'); -const Util = require("../../common-util"); - -const TYPE = 'saml'; - -/* -// XXX XXX XXX SAML TEST - -* get metadata with "saml.generateServiceProviderMetadata()" -* test site: https://samltest.id/upload.php - * upload metadata there -* redirected to cryptpad with a POST to /ssoauth handled in http-worker.js - - - - - -*/ - -const nameRef = 'urn:oid:2.16.840.1.113730.3.1.241'; - - -const opts = SSOUtils.getOptions(); -const getClient = (cfg, cb) => { - const saml = new SAML({ - callbackUrl: opts.callbackURL, - entryPoint: cfg.url, - issuer: cfg.issuer, - cert: cfg.cert, - privateKey: cfg.privateKey - }); - cb(void 0, saml); -}; -const getMetadata = (cfg, cb) => { - getClient(cfg, (err, client) => { - if (err) { return void cb(err); } - cb(null, client.generateServiceProviderMetadata(null, cfg.signingCert)); - }); -}; -module.exports = { - type: TYPE, - getMetadata: getMetadata, - checkConfig: (cfg) => { - return cfg.url && cfg.issuer && cfg.cert; - }, - auth: (Env, cfg, cb) => { - getClient(cfg, (err, client) => { - if (err) { return void cb ('E_OIDC_CONNECT'); } - client.getAuthorizeUrlAsync().then((url) => { - cb(void 0, { url: url }); - }); - }); - }, - authCb: (Env, cfg, token, url, cookies, cb) => { - const samltoken = cookies.samltoken; - if (!samltoken) { return void cb('NO_COOKIE'); } - SSOUtils.readRequest(Env, samltoken, (err, value) => { - SSOUtils.deleteRequest(Env, samltoken); - if (err || !value) { return void cb('EINVAL'); } - const data = Util.tryParse(value); - - getClient(cfg, (err, client) => { - if (err) { return void cb ('E_OIDC_CONNECT'); } - client.validatePostResponseAsync({ - SAMLResponse: data.content - }).then((data) => { - if (!data || data.loggedOut || !data.profile || !data.profile.nameID) { - return void cb('EINVAL'); - } - cb(void 0, { - id: data.profile.nameID, - name: data.profile[nameRef] || data.profile.nameID, - idpData: {} - }); - }); - }); - }); - }, -}; diff --git a/lib/sso-utils.js b/lib/sso-utils.js deleted file mode 100644 index dd9f8136f..000000000 --- a/lib/sso-utils.js +++ /dev/null @@ -1,225 +0,0 @@ -const SSO = require("./storage/sso"); -const Sessions = require("./storage/sessions"); -const Nacl = require("tweetnacl/nacl-fast"); -const JWT = require("jsonwebtoken"); -const Util = require("./common-util"); -const config = require("./load-config"); -const nThen = require("nthen"); - -const SSOUtils = module.exports; - -const SESSION_EXPIRATIION = 12 * 3600 * 1000; // XXX Hours? Days? Weeks? Configurable? - - - -SSOUtils.getOptions = () => { - return { - callbackURL: config.httpUnsafeOrigin + '/ssoauth' - }; -}; - -const TYPES = SSOUtils.TYPES = { - oidc: require('./plugins/sso/oidc'), - saml: require('./plugins/sso/saml') -}; - -const checkConfig = SSOUtils.checkConfig = (Env) => { - return Env && Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && Env.sso.list.length; -}; -SSOUtils.getProviderConfig = (Env, provider) => { - if (!checkConfig(Env)) { return; } - if (!provider) { return; } - const data = Env.sso.list.find((cfg) => { return cfg.name === provider; }); - return data; -}; -SSOUtils.isValidConfig = (cfg) => { - if (!cfg) { return; } - if (!cfg.type) { return; } - const type = cfg.type.toLowerCase(); - const idp = TYPES[type]; - if (!idp) { return; } - return idp.checkConfig(cfg); -}; - -SSOUtils.deleteRequest = (Env, id) => { - SSO.request.delete(Env, id, (err) => { - if (!err) { return; } - console.log(`Failed to delete SSO request ${id}`); - // XXX log? - }); -}; -SSOUtils.readRequest = (Env, id, cb) => { - SSO.request.read(Env, id, cb); -}; -SSOUtils.writeRequest = (Env, data, cb) => { - if (!data || !data.id || !data.type) { return void cb ('INVALID_REQUEST'); } - const id = data.id; - const value = { - type: data.type, - register: data.register, - provider: data.provider, - publicKey: data.publicKey, - time: +new Date() - }; - if (data.content) { value.content = data.content; } - - SSO.request.write(Env, id, JSON.stringify(value), cb); -}; - -SSOUtils.writeUser = (Env, provider, id, cb) => { - const seed = Nacl.util.encodeBase64(Nacl.randomBytes(24)); - SSO.user.write(Env, provider, id, JSON.stringify({ - seed: seed, - password: false - }), (err) => { - if (err) { return void cb(err); } - cb(void 0, { seed }); - }); -}; -SSOUtils.readUser = (Env, provider, id, cb) => { - SSO.user.read(Env, provider, id, (err, user) => { - if (err) { return void cb(err); } - cb(void 0, Util.tryParse(user)); - }); -}; -SSOUtils.deleteUser = (Env, provider, id, cb) => { - SSO.user.archive(Env, provider, id, cb); -}; -SSOUtils.updateUser = (Env, provider, id, data, cb) => { - SSO.user.archive(Env, provider, id, () => { - SSO.user.write(Env, provider, id, JSON.stringify(data), (err) => { - if (err) { return void cb(err); } - cb(); - }); - }); -}; - -SSOUtils.writeBlock = (Env, id, provider, ssoID, cb) => { - SSO.block.write(Env, id, JSON.stringify({ - id: ssoID, - provider: provider - }), (err) => { - if (err) { return void cb(err); } - cb(); - }); -}; -SSOUtils.readBlock = (Env, id, cb) => { - SSO.block.read(Env, id, (err, blockData) => { - if (err && err !== 'ENOENT' && err.code !== 'ENOENT') { - Env.Log.error("SSO_READ_BLOCK", { - error: Util.serializeError(err), - publicKey: id - }); - } - if (err) { return void cb(err.code || err); } - cb(void 0, Util.tryParse(blockData)); - }); -}; -SSOUtils.deleteBlock = (Env, id, cb) => { - SSO.block.archive(Env, id, (err) => { - if (err) { return void cb(err); } - cb(); - }); -}; - -// Archive SSO account data -SSOUtils.deleteAccount = (Env, publicKey, cb) => { - SSOUtils.readBlock(Env, publicKey, (err, data) => { - if (err && err !== 'ENOENT') { return void cb(err); } - if (!data) { return void cb(); } - let provider = data.provider; - let userId = data.id; - nThen((w) => { - SSOUtils.deleteUser(Env, provider, userId, w((err) => { - Env.Log.error("SSO_DELETE_USER", { - error: Util.serializeError(err), - provider: provider, - id: userId - }); - })); - SSOUtils.deleteBlock(Env, publicKey, w()); - }).nThen(() => { - cb(); - }); - }); -}; -SSOUtils.restoreAccount = (Env, publicKey, cb) => { - SSO.block.restore(Env, publicKey, (err) => { - if (err && err.code === 'ENOENT') { return void cb(); } - if (err) { return void cb(err); } - SSOUtils.readBlock(Env, publicKey, (err, data) => { - let provider = data.provider; - let userId = data.id; - SSO.user.restore(Env, provider, userId, (err) => { - cb(err); - }); - }); - }); -}; - - -// Store the SSO data (tokens, etc.) in a JWT while waiting for the user's CryptPad password -SSOUtils.createJWT = (Env, ssoId, provider, data, cb) => { - JWT.sign({ - sub: ssoId, - data: data, - provider: provider - }, Env.bearerSecret, { - // token integrity is ensured with HMAC SHA512 with the server's bearerSecret - // clients can inspect token parameters, but cannot modify them - algorithm: 'HS512', - // if you want it to expire you can set this for an arbitrary number of seconds in the future - expiresIn: 300, - }, function (err, token) { - if (err) { return void cb(err); } - cb(void 0, token); - }); -}; -SSOUtils.checkJWT = (Env, token, cb) => { - JWT.verify(token, Env.bearerSecret, { - algorithm: 'HS512', - }, function (err, payload) { - if (err) { - // the token could not be validated for some reason. - // it might have expired, the server might have rotated secrets, - // it might not be well-formed, etc. - // log and respond. - Env.Log.info('INVALID_JWT', { - error: err, - token: token, - }); - return void cb('INVALID_JWT'); - } - - // otherwise, it seems basically correct. - Env.Log.verbose("VALID_JWT", payload); - - cb(void 0, payload); - }); - -}; - -SSOUtils.makeSession = (Env, publicKey, provider, ssoData, cb) => { - const sessionId = Sessions.randomId(); - Sessions.write(Env, publicKey, sessionId, JSON.stringify({ - sso: { - exp: +new Date() + SESSION_EXPIRATIION, - provider: provider, - data: ssoData - } - }), function (err) { - if (err) { - Env.Log.error("SSO_SESSION_WRITE", { - error: Util.serializeError(err), - publicKey: publicKey, - sessionId: sessionId, - }); - return void cb("SSO_NO_SESSION"); - } - cb(void 0, { - bearer: sessionId, - }); - }); - -}; - diff --git a/scripts/saml-metadata.js b/scripts/saml-metadata.js deleted file mode 100644 index eec57ebef..000000000 --- a/scripts/saml-metadata.js +++ /dev/null @@ -1,16 +0,0 @@ -const config = require("../lib/load-config"); -const SSOUtils = require('../lib/sso-utils'); - -const sso = config.sso; -sso.list.filter((el) => { - return el.type === 'saml'; -}).forEach((cfg) => { - SSOUtils.TYPES.saml.getMetadata(cfg, (err, md) => { - console.log(`Name: ${cfg.name}`); - console.log('Metadata:'); - console.log(); - console.log(md); - console.log(); - console.log('===================================='); - }); -}); From aa3bbef4d1df874cc4b7096c1767719f7cba2038 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 6 Nov 2023 16:29:12 +0100 Subject: [PATCH 044/283] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9e410dc1c..09e6d593d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ customization .*.swp *.db /customize/ +/lib/plugins customize messages.log .DS_Store From 7f358408af8cdb85434db5433e3f1c87d8d32c80 Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:58:27 +0200 Subject: [PATCH 045/283] Fix ckedit context menu and paste dialog #631,#453 --- customize.dist/ckeditor-config.js | 4 ++-- www/pad/inner.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/customize.dist/ckeditor-config.js b/customize.dist/ckeditor-config.js index 9435c3d44..679123d9d 100644 --- a/customize.dist/ckeditor-config.js +++ b/customize.dist/ckeditor-config.js @@ -4,11 +4,11 @@ CKEDITOR.editorConfig = function( config ) { // https://dev.ckeditor.com/ticket/10907 config.needsBrFiller= fixThings; config.needsNbspFiller= fixThings; - config.removeButtons= 'Source,Maximize'; // magicline plugin inserts html crap into the document which is not part of the // document itself and causes problems when it's sent across the wire and reflected back - config.removePlugins= 'resize,elementspath'; + config.removePlugins= 'resize,elementspath,contextmenu,liststyle,tabletools,tableselection'; + config.forcePasteAsPlainText = true; config.resize_enabled= false; //bottom-bar config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print,blockbase64,mathjax,wordcount,comments'; config.toolbarGroups= [ diff --git a/www/pad/inner.js b/www/pad/inner.js index 39216c281..462973e13 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -1422,7 +1422,7 @@ define([ }; module.ckeditor = editor = Ckeditor.replace('editor1', { - customConfig: '/customize/ckeditor-config.js', + customConfig: '/customize.dist/ckeditor-config.js', }); editor.on('instanceReady', waitFor()); From ade5572473eb2cbdfc5c35b1fab7dc25fcb4454c Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 7 Nov 2023 15:31:51 +0100 Subject: [PATCH 046/283] SSO buttons UI in login and register pages --- customize.dist/pages/login.js | 14 +++++++++++--- customize.dist/pages/register.js | 12 +++++++++--- customize.dist/src/less2/pages/page-login.less | 12 ++++++++++-- customize.dist/src/less2/pages/page-register.less | 13 +++++++++++-- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/customize.dist/pages/login.js b/customize.dist/pages/login.js index 2db0743d5..9234a447f 100644 --- a/customize.dist/pages/login.js +++ b/customize.dist/pages/login.js @@ -7,13 +7,18 @@ define([ ], function (h, UI, Msg, Pages, Config) { return function () { document.title = Msg.login_login; + + var ssoEnabled = (Config.sso && Config.sso.list && Config.sso.list.length) ?'': '.cp-hidden'; + var ssoEnforced = (Config.sso && Config.sso.force) ? '.cp-hidden' : ''; + Msg.sso_login_description = "Login from SSO...."; // XXX + return [h('div#cp-main', [ Pages.infopageTopbar(), h('div.container.cp-container', [ h('div.row.cp-page-title', h('h1', Msg.login_login)), h('div.row', [ - h('div.col-md-3'), - h('div#userForm.form-group.hidden.col-md-6', [ + h('div.col-md-3'+ssoEnforced), + h('div#userForm.form-group.col-md-6'+ssoEnforced, [ h('div.cp-login-instance', Msg._getKey('login_instance', [ Pages.Instance.name ])), h('div.big-container', [ h('div.input-container', [ @@ -50,7 +55,10 @@ define([ ), h('button.login', Msg.login_login), ]), - Config.sso ? h('div.cp-login-sso') : undefined + ]), + 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') ]), diff --git a/customize.dist/pages/register.js b/customize.dist/pages/register.js index 7dff130f0..a2c6c2b0a 100644 --- a/customize.dist/pages/register.js +++ b/customize.dist/pages/register.js @@ -10,6 +10,10 @@ define([ document.title = Msg.register_header; var tos = $(UI.createCheckbox('accept-terms')).find('.cp-checkmark-label').append(Msg.register_acceptTerms).parent()[0]; + var ssoEnabled = (Config.sso && Config.sso.list && Config.sso.list.length) ?'': '.cp-hidden'; + var ssoEnforced = (Config.sso && Config.sso.force) ? '.cp-hidden' : ''; + Msg.sso_register_description = "Register from SSO...."; // XXX + var termsLink = Pages.customURLs.terms; $(tos).find('a').attr({ href: termsLink, @@ -49,7 +53,7 @@ define([ Pages.setHTML(h('div.cp-register-notes'), Msg.register_notes) ]), h('div.cp-reg-form.col-md-6', [ - h('div#userForm.form-group.hidden', [ + h('div#userForm.form-group'+ssoEnforced, [ h('div.cp-register-instance', [ Msg._getKey('register_instance', [Pages.Instance.name]), h('br'), @@ -90,8 +94,10 @@ define([ ]), termsCheck, h('button#register', Msg.login_register), - Config.sso ? h('div.cp-register-sso') : undefined - ]) + ]), + h('div#ssoForm.form-group.col-md-6'+ssoEnabled, [ + h('div.cp-register-sso', Msg.sso_register_description) + ]), ]), ]) ]); diff --git a/customize.dist/src/less2/pages/page-login.less b/customize.dist/src/less2/pages/page-login.less index 1745fdb7e..655a418e5 100644 --- a/customize.dist/src/less2/pages/page-login.less +++ b/customize.dist/src/less2/pages/page-login.less @@ -19,13 +19,16 @@ } } .cp-container { - #userForm { + .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-instance, .cp-login-sso-description { margin-bottom: 5px; } .form-control { @@ -42,6 +45,11 @@ color: @cryptpad_text_col; } } + #ssoForm { + button { + margin: 0 5px; + } + } .align-items-center { box-shadow: 0 5px 15px @cp_shadow-color; background: @cryptpad_color_white; diff --git a/customize.dist/src/less2/pages/page-register.less b/customize.dist/src/less2/pages/page-register.less index a0e4a0b21..662a03381 100644 --- a/customize.dist/src/less2/pages/page-register.less +++ b/customize.dist/src/less2/pages/page-register.less @@ -85,13 +85,17 @@ z-index: 0; } } - #userForm { + .cp-hidden { + display: none !important; + } + #userForm, #ssoForm { padding: 15px; background-color: @cp_static-card-bg; position: relative; z-index: 2; - margin-bottom: 100px; + //margin-bottom: 100px; border-radius: @infopages-radius-L; + max-width: 100%; .cp-shadow(); .form-control { border-radius: @infopages-radius; @@ -111,6 +115,11 @@ margin-top: 10px; } } + #ssoForm { + button { + margin: 0 5px; + } + } .cp-register-notes { ul.cp-notes-list { From 046e7abeb8f54117fac49b77b8b27ce5648d0b45 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 7 Nov 2023 16:02:27 +0100 Subject: [PATCH 047/283] option to enforce CryptPad password for SSO accounts --- lib/http-worker.js | 4 ++-- www/ssoauth/main.js | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/http-worker.js b/lib/http-worker.js index ac7e8835e..7fc6b05a1 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -546,9 +546,9 @@ var makeRouteCache = function (template, cacheName) { const ssoList = Env.sso && Env.sso.enabled && Array.isArray(Env.sso.list) && Env.sso.list.map(function (obj) { return obj.name; }) || []; -const ssoCfg = ssoList.length ? { +const ssoCfg = (SSOUtils && ssoList.length) ? { force: (Env.sso && Env.sso.enforced && 1) || 0, - password: (Env.sso && Env.sso.cpPassword && 1) || 0, + password: (Env.sso && Env.sso.cpPassword && (Env.sso.forceCpPassword ? 2 : 1)) || 0, list: ssoList } : false; var serveConfig = makeRouteCache(function () { diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index 186f41444..c5b3e1d7e 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -132,6 +132,9 @@ define([ if (data.register && pw && !Cred.isLongEnoughPassword(pw)) { return void UI.warn(Messages.register_passwordTooShort); } + if (data.register && !pw && ApiConfig.sso.password === 2) { + return void UI.warn(Messages.register_passwordTooShort); + } $button.prop('disabled', 'disabled'); if (data.register) { From 5348b35efcaa83a2405e6999b6d1d7909a56a035 Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Tue, 7 Nov 2023 17:13:43 +0200 Subject: [PATCH 048/283] Do not change formatting --- customize.dist/ckeditor-config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/customize.dist/ckeditor-config.js b/customize.dist/ckeditor-config.js index 679123d9d..6b2a86588 100644 --- a/customize.dist/ckeditor-config.js +++ b/customize.dist/ckeditor-config.js @@ -8,7 +8,6 @@ CKEDITOR.editorConfig = function( config ) { // magicline plugin inserts html crap into the document which is not part of the // document itself and causes problems when it's sent across the wire and reflected back config.removePlugins= 'resize,elementspath,contextmenu,liststyle,tabletools,tableselection'; - config.forcePasteAsPlainText = true; config.resize_enabled= false; //bottom-bar config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print,blockbase64,mathjax,wordcount,comments'; config.toolbarGroups= [ From 708203e9cdb2f047deb9c4283721191d13f60be3 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 8 Nov 2023 12:54:38 +0100 Subject: [PATCH 049/283] corrected format of csv exports for poll time type questions (timestamp > iso string) --- www/form/inner.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 91d1c8c34..3615b0aee 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2662,7 +2662,12 @@ define([ var q = form.q || Messages.form_default; if (answer === false) { var cols = extractValues(opts.values).map(function (key) { - return q + ' | ' + key; + if (opts.type === 'time') { + return q + ' | ' + new Date(parseInt(key)).toISOString(); + } else { + return q + ' | ' + key; + } + }); cols.unshift(q); return cols; @@ -2675,10 +2680,26 @@ define([ var str = ''; Object.keys(answer.values).sort().forEach(function (k, i) { if (i !== 0) { str += ';'; } - str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; + if (opts.type === 'time') { + Object.defineProperty( + answer.values, + new Date(parseInt(k)).toISOString(), + Object.getOwnPropertyDescriptor(answer.values, k), + ); + delete answer.values[k]; + str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + answer.values[ new Date(parseInt(k)).toISOString()] ; + } + else { + str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; + } }); var res = extractValues(opts.values).map(function (key) { - return answer.values[key] || ''; + if (opts.type === 'time') { + return answer.values[ new Date(parseInt(key)).toISOString()] || ''; + } else { + return answer.values[key] || ''; + } + }); res.unshift(str); return res; From 049fa08250eadcaddbc560557b92674966451cb0 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Wed, 8 Nov 2023 15:38:52 +0100 Subject: [PATCH 050/283] WIP build cryptpad: urls for images --- package-lock.json | 9 ++-- package.json | 2 +- www/common/image-dialog.js | 94 ++++++++++++++++++++++++++++---------- 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index d7547442c..ba74fc690 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+1", + "drawio": "file:../drawio-npm", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -68,6 +68,9 @@ "url": "https://opencollective.com/cryptpad" } }, + "../drawio-npm": { + "version": "21.8.2+1" + }, "node_modules/@mcrowe/minibloom": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mcrowe/minibloom/-/minibloom-0.2.0.tgz", @@ -1347,8 +1350,8 @@ } }, "node_modules/drawio": { - "version": "21.8.2+1", - "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#c1708e16bb816dd3bc9b95bd8f3ecf33216d8597" + "resolved": "../drawio-npm", + "link": true }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", diff --git a/package.json b/package.json index cecc49fd1..19f583950 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+1", + "drawio": "file:../drawio-npm", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/www/common/image-dialog.js b/www/common/image-dialog.js index df7d13aea..950e09f48 100644 --- a/www/common/image-dialog.js +++ b/www/common/image-dialog.js @@ -3,17 +3,64 @@ define([ '/common/common-util.js', '/file/file-crypto.js', + '/common/common-hash.js', ], function( Util, - FileCrypto + FileCrypto, + Hash ) { + const getCryptPadUrl = function(src, key, type) { + const url = new URL(src); + const params = new URLSearchParams(); + params.set('type', type); + url.search = params.toString(); + url.protocol = url.protocol === 'https:' ? 'cryptpads:' : 'cryptpad:'; + url.hash = key; + return url.href; + }; + + const parseCryptPadUrl = function(href) { + const url = new URL(href); + url.protocol = url.protocol === 'cryptpads:' ? 'https:' : 'http:'; + const key = url.hash.substring(1); // remove leading '#' + const type = url.searchParams.get('type'); + url.search = ''; + url.hash = ''; + return { src: url.href, key, type }; + } + const setBlobType = (blob, mimeType) => { const fixedBlob = new Blob([blob], {type: mimeType}); return fixedBlob; }; - const getImage = function(common, data, callback) { + const loadImage = function(common, href) { + return new Promise((resolve, reject) => { + const { src, key, type } = parseCryptPadUrl(href); + Util.fetch(src, function (err, u8) { + if (err) { + console.error(err); + return void reject(err); + } + try { + FileCrypto.decrypt(u8, nacl.util.decodeBase64(key), (err, res) => { + if (err || !res.content) { + console.error("Decrypting failed"); + return void reject(err); + } + + resolve(setBlobType(res.content, type)); + }); + } catch (e) { + console.error(e); + reject(err); + } + }, void 0, common.getCache()); + }); + }; + + const getImage = function(common, data, callback) { // TODO remove Util.fetch(data.src, function (err, u8) { if (err) { console.error(err); @@ -35,29 +82,30 @@ define([ }, void 0, common.getCache()); }; - return { - openImageDialog: function(common, integrationChannel, data, cb) { - if (integrationChannel) { - const ignoreFirstParam = (_, image) => cb(image); - integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, ignoreFirstParam, {raw: true}); - return; + const openImageDialog = function(common, integrationChannel, data, cb) { + if (integrationChannel) { + const ignoreFirstParam = (_, image) => cb(image); + integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, ignoreFirstParam, {raw: true}); + return; + } + common.openFilePicker({ + types: ['file'], + where: ['root'], + filter: { + fileType: ['image/', 'application/x-drawio'] } - common.openFilePicker({ - types: ['file'], - where: ['root'], - filter: { - fileType: ['image/', 'application/x-drawio'] - } - }, (data) => { - getImage(common, data, function(blob) { - common.setPadAttribute('atime', +new Date(), null, data.href); - cb({ - name: data.name, - fileType: data.fileType, - blob: blob - }); + }, (data) => { + loadImage(common, getCryptPadUrl(data.src, data.key, data.fileType)).then((blob) => { + cb({ + name: data.name, + fileType: data.fileType, + blob: blob }); }); - } + }); + }; + + return { + openImageDialog, }; }); From d850b06bf4599e67b8cc878867f6e72e0a989117 Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Wed, 8 Nov 2023 16:54:04 +0200 Subject: [PATCH 051/283] Undo folder change --- www/pad/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/pad/inner.js b/www/pad/inner.js index 462973e13..39216c281 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -1422,7 +1422,7 @@ define([ }; module.ckeditor = editor = Ckeditor.replace('editor1', { - customConfig: '/customize.dist/ckeditor-config.js', + customConfig: '/customize/ckeditor-config.js', }); editor.on('instanceReady', waitFor()); From 72cb827e18ecf450b304248605322d00e38faec8 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 8 Nov 2023 15:58:28 +0100 Subject: [PATCH 052/283] Make MFA session expiration configurable --- config/config.example.js | 14 ++++++++++++++ lib/challenge-commands/totp.js | 6 +++--- lib/http-worker.js | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/config/config.example.js b/config/config.example.js index 4f289b56b..f95da7a65 100644 --- a/config/config.example.js +++ b/config/config.example.js @@ -113,6 +113,20 @@ module.exports = { */ // maxWorkers: 4, + /* ===================== + * Sessions + * ===================== */ + + /* Accounts can be protected with an OTP (One Time Password) system + * to add a second authentication layer. Such accounts use a session + * with a given lifetime after which they are logged out and need + * to be re-authenticated. You can configure the lifetime of these + * sessions here. + * + * defaults to 7 days + */ + //otpSessionExpiration: 7*24, // hours + /* ===================== * Admin * ===================== */ diff --git a/lib/challenge-commands/totp.js b/lib/challenge-commands/totp.js index 61fd2f7af..8854d681f 100644 --- a/lib/challenge-commands/totp.js +++ b/lib/challenge-commands/totp.js @@ -8,6 +8,7 @@ const MFA = require("../storage/mfa"); const Sessions = require("../storage/sessions"); 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) {} @@ -59,9 +60,8 @@ var decode32 = S => { }; -// XXX Decide expire time -// Allow user settings? -var EXPIRATION = 7 * 24 * 3600 * 1000; // Sessions are valid 7 days +// TODO Allow user settings? +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) => { diff --git a/lib/http-worker.js b/lib/http-worker.js index 7fc6b05a1..94a68ae76 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -377,7 +377,7 @@ app.use('/block/', function (req, res, next) { // Same for SSO settings if (!SSOUtils) { return; } SSOUtils.readBlock(Env, name, w(function (err, content) { - if (err && err.code === 'ENOENT') { + if (err && (err.code === 'ENOENT' || err === 'ENOENT')) { return; } if (err) { From 1b032a06de10aa194a59df2ed88b7555cbd39324 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 8 Nov 2023 16:15:54 +0100 Subject: [PATCH 053/283] Hide password change form for SSO accounts when cp password disabled --- www/settings/inner.js | 1 + www/settings/main.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/www/settings/inner.js b/www/settings/inner.js index 7500e3c0a..041036739 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -662,6 +662,7 @@ define([ create['change-password'] = function() { if (!common.isLoggedIn()) { return; } + if (privateData.isSSO && ApiConfig.sso && ApiConfig.sso.password === 0) { return; } var $div = $('
', { 'class': 'cp-settings-change-password cp-sidebarlayout-element' }); diff --git a/www/settings/main.js b/www/settings/main.js index b5a2ec4a0..8f6a6f605 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -150,8 +150,9 @@ define([ category = window.location.hash.slice(1); window.location.hash = ''; } - var addData = function (obj) { + var addData = function (obj, Cryptpad, user, Utils) { if (category) { obj.category = category; } + obj.isSSO = Boolean(Utils.LocalStore.getSSOSeed()); }; SFCommonO.start({ noRealtime: true, From 3d022013aa741d78ca698992964a90c1a7d19e93 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 9 Nov 2023 11:46:27 +0100 Subject: [PATCH 054/283] WIP pass urls instead of blobs to draw.io --- www/common/image-dialog.js | 96 ++------------------------------------ www/diagram/inner.js | 60 ++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 96 deletions(-) diff --git a/www/common/image-dialog.js b/www/common/image-dialog.js index 950e09f48..4a648e0d5 100644 --- a/www/common/image-dialog.js +++ b/www/common/image-dialog.js @@ -1,86 +1,4 @@ -/* globals nacl */ - -define([ - '/common/common-util.js', - '/file/file-crypto.js', - '/common/common-hash.js', -], function( - Util, - FileCrypto, - Hash -) { - - const getCryptPadUrl = function(src, key, type) { - const url = new URL(src); - const params = new URLSearchParams(); - params.set('type', type); - url.search = params.toString(); - url.protocol = url.protocol === 'https:' ? 'cryptpads:' : 'cryptpad:'; - url.hash = key; - return url.href; - }; - - const parseCryptPadUrl = function(href) { - const url = new URL(href); - url.protocol = url.protocol === 'cryptpads:' ? 'https:' : 'http:'; - const key = url.hash.substring(1); // remove leading '#' - const type = url.searchParams.get('type'); - url.search = ''; - url.hash = ''; - return { src: url.href, key, type }; - } - - const setBlobType = (blob, mimeType) => { - const fixedBlob = new Blob([blob], {type: mimeType}); - return fixedBlob; - }; - - const loadImage = function(common, href) { - return new Promise((resolve, reject) => { - const { src, key, type } = parseCryptPadUrl(href); - Util.fetch(src, function (err, u8) { - if (err) { - console.error(err); - return void reject(err); - } - try { - FileCrypto.decrypt(u8, nacl.util.decodeBase64(key), (err, res) => { - if (err || !res.content) { - console.error("Decrypting failed"); - return void reject(err); - } - - resolve(setBlobType(res.content, type)); - }); - } catch (e) { - console.error(e); - reject(err); - } - }, void 0, common.getCache()); - }); - }; - - const getImage = function(common, data, callback) { // TODO remove - Util.fetch(data.src, function (err, u8) { - if (err) { - console.error(err); - return void callback(""); - } - try { - FileCrypto.decrypt(u8, nacl.util.decodeBase64(data.key), (err, res) => { - if (err || !res.content) { - console.error("Decrypting failed"); - return void callback(""); - } - - callback(setBlobType(res.content, data.fileType)); - }); - } catch (e) { - console.error(e); - callback(""); - } - }, void 0, common.getCache()); - }; +define([], function() { const openImageDialog = function(common, integrationChannel, data, cb) { if (integrationChannel) { @@ -92,17 +10,9 @@ define([ types: ['file'], where: ['root'], filter: { - fileType: ['image/', 'application/x-drawio'] + fileType: ['image/'] } - }, (data) => { - loadImage(common, getCryptPadUrl(data.src, data.key, data.fileType)).then((blob) => { - cb({ - name: data.name, - fileType: data.fileType, - blob: blob - }); - }); - }); + }, cb); }; return { diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 1ac1a5bed..a30fa01f7 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -4,6 +4,8 @@ define([ '/customize/messages.js', // translation keys '/components/pako/dist/pako.min.js', '/components/x2js/x2js.js', + '/common/common-util.js', + '/file/file-crypto.js', '/components/tweetnacl/nacl-fast.min.js', 'less!/diagram/app-diagram.less', 'css!/diagram/drawio.css', @@ -11,7 +13,9 @@ define([ Framework, Messages, pako, - X2JS) { + X2JS, + Util, + FileCrypto) { const Nacl = window.nacl; const APP = window.APP = {}; @@ -122,10 +126,60 @@ define([ autosave: onDrawioAutosave, }; + const getCryptPadUrl = function(src, key, type) { + const url = new URL(src); + const params = new URLSearchParams(); + params.set('type', type); + url.search = params.toString(); + url.protocol = url.protocol === 'https:' ? 'cryptpads:' : 'cryptpad:'; + url.hash = key; + return url.href; + }; + + const parseCryptPadUrl = function(href) { + const url = new URL(href); + url.protocol = url.protocol === 'cryptpads:' ? 'https:' : 'http:'; + const key = url.hash.substring(1); // remove leading '#' + const type = url.searchParams.get('type'); + url.search = ''; + url.hash = ''; + return { src: url.href, key, type }; + } + + const setBlobType = (blob, mimeType) => { + const fixedBlob = new Blob([blob], {type: mimeType}); + return fixedBlob; + }; + + APP.loadImage = function(href) { + return new Promise((resolve, reject) => { + const { src, key, type } = parseCryptPadUrl(href); + Util.fetch(src, function (err, u8) { + if (err) { + console.error(err); + return void reject(err); + } + try { + FileCrypto.decrypt(u8, nacl.util.decodeBase64(key), (err, res) => { + if (err || !res.content) { + console.error("Decrypting failed"); + return void reject(err); + } + + resolve(setBlobType(res.content, type)); + }); + } catch (e) { + console.error(e); + reject(err); + } + }, void 0, framework._.sfCommon.getCache()); + }); + }; + APP.addImage = function() { return new Promise((resolve) => { - framework.insertImage({}, (image) => { - resolve(image); + framework.insertImage({}, (imageData) => { + resolve(getCryptPadUrl(imageData.src, imageData.key, imageData.fileType)); }); }); }; From 982c15ae0e2ba481159082c4204e80fcef049e8f Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 9 Nov 2023 15:35:56 +0100 Subject: [PATCH 055/283] Add an option to enforce MFA for all accounts on the instance --- config/config.example.js | 8 +++ customize.dist/src/less2/include/loading.less | 3 +- .../src/less2/include/modals-ui-elements.less | 38 +++++++++++++ lib/env.js | 1 + lib/http-worker.js | 3 +- www/common/common-ui-elements.js | 16 ++++++ www/common/cryptpad-common.js | 17 ++++++ www/common/sframe-common-outer.js | 57 +++++++++++++++++++ www/common/sframe-common.js | 7 +++ www/settings/inner.js | 11 +++- www/settings/main.js | 40 ------------- 11 files changed, 158 insertions(+), 43 deletions(-) diff --git a/config/config.example.js b/config/config.example.js index f95da7a65..69e771bfd 100644 --- a/config/config.example.js +++ b/config/config.example.js @@ -127,6 +127,14 @@ module.exports = { */ //otpSessionExpiration: 7*24, // hours + /* Registered users can be forced to protect their account + * with a Multi-factor Authentication (MFA) tool like a TOTP + * authenticator application. + * + * defaults to false + */ + //enforceMFA: false, + /* ===================== * Admin * ===================== */ diff --git a/customize.dist/src/less2/include/loading.less b/customize.dist/src/less2/include/loading.less index c139ae667..6bd87718a 100644 --- a/customize.dist/src/less2/include/loading.less +++ b/customize.dist/src/less2/include/loading.less @@ -57,7 +57,7 @@ .cp-loading-container { width: 700px; max-width: 90vw; - height: 236px; + min-height: 236px; max-height: calc(100vh - 20px); margin: 50px; flex-shrink: 0; @@ -100,6 +100,7 @@ color: @cp_loading-fg; text-align: left; display: none; + overflow-y: auto; a { color: @cp_loading-link; } diff --git a/customize.dist/src/less2/include/modals-ui-elements.less b/customize.dist/src/less2/include/modals-ui-elements.less index 6bc1b9245..39a763626 100644 --- a/customize.dist/src/less2/include/modals-ui-elements.less +++ b/customize.dist/src/less2/include/modals-ui-elements.less @@ -35,6 +35,44 @@ } } + .cp-loading-missing-mfa { + .cp-settings-qr-container { + display: flex; + align-items: center; + justify-content: space-evenly; + .cp-settings-qr-code { + input { + max-width: 250px; + } + button { + margin-top: 10px; + } + } + } + .cp-settings-qr { + img { + border: 10px solid white; + border-radius: 10px; + } + margin: 10px 10px 10px 0; + } + .cp-password-container { + flex-wrap: wrap; + gap:0.5rem; + + justify-content:flex-start; + input { + flex-shrink: 1; + max-width: 400px; + } + label { + width: 100%; + font-weight: unset; + margin-bottom: 5px; + } + } + } + // Properties modal .cp-app-prop { margin-bottom: 10px; diff --git a/lib/env.js b/lib/env.js index 82870626e..9907500e7 100644 --- a/lib/env.js +++ b/lib/env.js @@ -224,6 +224,7 @@ module.exports.create = function (config) { commandTimers: {}, sso: config.sso, + enforceMFA: config.enforceMFA, // initialized as undefined bearerSecret: void 0, diff --git a/lib/http-worker.js b/lib/http-worker.js index 94a68ae76..0bbe4593d 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -577,7 +577,8 @@ var serveConfig = makeRouteCache(function () { shouldUpdateNode: Env.shouldUpdateNode || undefined, listMyInstance: Env.listMyInstance, accounts_api: Env.accounts_api, - sso: ssoCfg + sso: ssoCfg, + enforceMFA: Env.enforceMFA }, null, '\t'), '});' ].join(';\n'); diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 3a03807f2..7fc4002e1 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -4040,5 +4040,21 @@ define([ modal = UI.openCustomModal(UI.dialog.customModal(content, {buttons: buttons })); }; + Messages.loading_mfa_required = "Multi-factor Authentication is required on this instance. Please update your account using an anthenticator app and the form below."; // XXX + UIElements.onMissingMFA = (common, config, cb) => { + let content = h('div'); + let msg = h('div.cp-loading-missing-mfa', [ + h('div.alert.alert-warning', Messages.loading_mfa_required), + content + ]); + common.totpSetup(config, content, false, (newState) => { + if (!newState) { + return void UI.errorLoadingScreen(Messages.error); + } + cb({state: true}); + }); + return UI.errorLoadingScreen(msg, false, false); + }; + return UIElements; }); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index f0a4d3801..7a27350da 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -2160,6 +2160,7 @@ define([ // Loading events common.loading = {}; common.loading.onDriveEvent = Util.mkEvent(); + common.loading.onMissingMFAEvent = Util.mkEvent(); // (Auto)store pads common.autoStore = {}; @@ -2484,6 +2485,22 @@ define([ if (AppConfig.beforeLogin) { AppConfig.beforeLogin(LocalStore.isLoggedIn(), waitFor()); } + }).nThen(function (waitFor) { + var blockHash = LocalStore.getBlockHash(); + if (!blockHash || !Config.enforceMFA) { return; } + + // If this instance is configured to enforce MFA for all registered users, + // request the login block with no credential to check if it is protected. + var parsed = Block.parseBlockHash(blockHash); + Util.getBlock(parsed.href, { }, waitFor((err, response) => { + // If this account is already protected, nothing to do + if (err === 401 && response.method) { return; } + + // Missing MFA protection, show set up screen + common.loading.onMissingMFAEvent.fire({ + cb: waitFor() + }); + })); }).nThen(function (waitFor) { // if a block URL is present then the user is probably logged in with a modern account diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 4ccda4b68..a8d1e401a 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -226,6 +226,61 @@ define([ } } }; + + var addFirstHandlers = () => { + sframeChan.on('Q_SETTINGS_CHECK_PASSWORD', function (data, cb) { + var blockHash = Utils.LocalStore.getBlockHash(); + var userHash = Utils.LocalStore.getUserHash(); + var correct = (blockHash && blockHash === data.blockHash) || + (!blockHash && userHash === data.userHash); + cb({correct: correct}); + }); + sframeChan.on('Q_SETTINGS_TOTP_SETUP', function (obj, cb) { + require([ + '/common/outer/http-command.js', + ], function (ServerCommand) { + var data = obj.data; + data.command = 'TOTP_SETUP'; + data.session = Utils.LocalStore.getSessionToken(); + ServerCommand(obj.key, data, function (err, response) { + cb({ success: Boolean(!err && response && response.bearer) }); + if (response && response.bearer) { + Utils.LocalStore.setSessionToken(response.bearer); + } + }); + }); + }); + sframeChan.on('Q_SETTINGS_TOTP_REVOKE', function (obj, cb) { + require([ + '/common/outer/http-command.js', + ], function (ServerCommand) { + ServerCommand(obj.key, obj.data, function (err, response) { + cb({ success: Boolean(!err && response && response.success) }); + if (response && response.success) { + Utils.LocalStore.setSessionToken(''); + } + }); + }); + }); + sframeChan.on('Q_SETTINGS_GET_SSO_SEED', function (obj, _cb) { + var cb = Utils.Util.mkAsync(_cb); + cb({ + seed: Utils.LocalStore.getSSOSeed() + }); + }); + Cryptpad.loading.onMissingMFAEvent.reg((data) => { + var cb = data.cb; + if (!sframeChan) { return void cb('EINVAL'); } + sframeChan.query('Q_LOADING_MISSING_AUTH', { + accountName: Utils.LocalStore.getAccountName(), + origin: window.location.origin, + }, (err, obj) => { + if (obj && obj.state) { return void cb(true); } + console.error(err || obj); + }); + }); + }; + var whenReady = waitFor(function (msg) { if (msg.source !== iframe) { return; } var data = typeof(msg.data) === "string" ? JSON.parse(msg.data) : msg.data; @@ -242,6 +297,7 @@ define([ }); SFrameChannel.create(msgEv, postMsg, waitFor(function (sfc) { Utils.sframeChan = sframeChan = sfc; + addFirstHandlers(); window.CryptPad_loadingError = function (e) { sfc.event('EV_LOADING_ERROR', e); }; @@ -267,6 +323,7 @@ define([ } } catch (e) { console.error(e); } + // NOTE: Driveless mode should only work for existing pads, but we can't check that // before creating the worker because we need the anon RPC to do so. // We're only going to check if a hash exists in the URL or not. diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 8f56cb242..b63096bf0 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -15,6 +15,7 @@ define([ '/common/sframe-common-mailbox.js', '/common/inner/cache.js', '/common/inner/common-mediatag.js', + '/common/inner/mfa.js', '/common/metadata-manager.js', '/customize/application_config.js', @@ -46,6 +47,7 @@ define([ Mailbox, Cache, MT, + MFA, MetadataMgr, AppConfig, Pages, @@ -119,6 +121,7 @@ define([ funcs.importMediaTagMenu = callWithCommon(MT.importMediaTagMenu); funcs.getMediaTagPreview = callWithCommon(MT.getMediaTagPreview); funcs.getMediaTag = callWithCommon(MT.getMediaTag); + funcs.totpSetup = callWithCommon(MFA.totpSetup); // Thumb funcs.displayThumbnail = callWithCommon(Thumb.displayThumbnail); @@ -889,6 +892,10 @@ define([ UI.updateLoadingProgress(data); }); + ctx.sframeChan.on('Q_LOADING_MISSING_AUTH', function (data, cb) { + UIElements.onMissingMFA(funcs, data, cb); + }); + ctx.sframeChan.on('EV_NEW_VERSION', function () { // TODO lock the UI and do the same in non-framework apps var $err = $('
').append(Messages.newVersionError); diff --git a/www/settings/inner.js b/www/settings/inner.js index 041036739..26a66ebf8 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -1236,7 +1236,16 @@ define([ sframeChan.query('Q_SETTINGS_MFA_CHECK', {}, function (err, obj) { if (err || !obj || (obj && obj.err === 'NOBLOCK')) { return void cb(false); } var enabled = obj && obj.mfa && obj.type === 'TOTP'; - drawMfa(content, Boolean(enabled)); + var config = { + accountName: privateData.accountName, + origin: privateData.origin + }; + var draw = (state) => { + common.totpSetup(config, content, state, (newState) => { + draw(newState); + }); + }; + draw(Boolean(enabled)); cb(content); }); }, true); diff --git a/www/settings/main.js b/www/settings/main.js index 8f6a6f605..21a488803 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -70,40 +70,6 @@ define([ sframeChan.on('Q_SETTINGS_IMPORT_LOCAL', function (data, cb) { Cryptpad.mergeAnonDrive(cb); }); - sframeChan.on('Q_SETTINGS_CHECK_PASSWORD', function (data, cb) { - var blockHash = Utils.LocalStore.getBlockHash(); - var userHash = Utils.LocalStore.getUserHash(); - var correct = (blockHash && blockHash === data.blockHash) || - (!blockHash && userHash === data.userHash); - cb({correct: correct}); - }); - sframeChan.on('Q_SETTINGS_TOTP_SETUP', function (obj, cb) { - require([ - '/common/outer/http-command.js', - ], function (ServerCommand) { - var data = obj.data; - data.command = 'TOTP_SETUP'; - data.session = Utils.LocalStore.getSessionToken(); - ServerCommand(obj.key, data, function (err, response) { - cb({ success: Boolean(!err && response && response.bearer) }); - if (response && response.bearer) { - Utils.LocalStore.setSessionToken(response.bearer); - } - }); - }); - }); - sframeChan.on('Q_SETTINGS_TOTP_REVOKE', function (obj, cb) { - require([ - '/common/outer/http-command.js', - ], function (ServerCommand) { - ServerCommand(obj.key, obj.data, function (err, response) { - cb({ success: Boolean(!err && response && response.success) }); - if (response && response.success) { - Utils.LocalStore.setSessionToken(''); - } - }); - }); - }); sframeChan.on('Q_SETTINGS_MFA_CHECK', function (obj, cb) { require([ '/common/outer/login-block.js', @@ -120,12 +86,6 @@ define([ }); }); }); - sframeChan.on('Q_SETTINGS_GET_SSO_SEED', function (obj, _cb) { - var cb = Utils.Util.mkAsync(_cb); - cb({ - seed: Utils.LocalStore.getSSOSeed() - }); - }); sframeChan.on('Q_SETTINGS_REMOVE_OWNED_PADS', function (data, cb) { Cryptpad.removeOwnedPads(data, cb); }); From 2e13c041617f087ac9c8446273ca375116485dc5 Mon Sep 17 00:00:00 2001 From: DianaXWiki <139217939+DianaXWiki@users.noreply.github.com> Date: Thu, 9 Nov 2023 17:35:01 +0200 Subject: [PATCH 056/283] Make ricktext toolbar keyboard accesible #1272 --- customize.dist/ckeditor-config.js | 10 ++++++++-- www/pad/csp.js | 5 +++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/customize.dist/ckeditor-config.js b/customize.dist/ckeditor-config.js index 6b2a86588..b2cb6cdb6 100644 --- a/customize.dist/ckeditor-config.js +++ b/customize.dist/ckeditor-config.js @@ -28,7 +28,7 @@ CKEDITOR.editorConfig = function( config ) { config.mathJaxLib = '/pad/mathjax/MathJax.js?config=TeX-AMS_HTML'; config.font_defaultLabel = 'Arial'; config.fontSize_defaultLabel = '16'; - + config.accessibility = 'true'; config.keystrokes = [ [ CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' ], [ CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' ], @@ -46,7 +46,13 @@ CKEDITOR.editorConfig = function( config ) { [ CKEDITOR.CTRL + 73 /*I*/, 'italic' ], [ CKEDITOR.CTRL + 85 /*U*/, 'underline' ], - [ CKEDITOR.ALT + 109 /*-*/, 'toolbarCollapse' ] + [CKEDITOR.ALT + 109 /*-*/, 'toolbarCollapse' ], + [37 /* Left Arrow */, 'focusPreviousButton'], + [39 /* Right Arrow */, 'focusNextButton'], + //enter + [13, 'clickFocusedButton'], + //space bar + [32, 'clickFocusedButton'] ]; //skin: 'moono-cryptpad,/pad/themes/moono-cryptpad/' diff --git a/www/pad/csp.js b/www/pad/csp.js index 39cf032f0..2f27855fc 100644 --- a/www/pad/csp.js +++ b/www/pad/csp.js @@ -14,11 +14,12 @@ define(['jquery'], function ($) { CKEDITOR.tools.callFunction(Number(m[1]), e.currentTarget); $iframe.scrollTop(s); }); - + // Buttons var $a = $('.cke_toolbox_main').find('.cke_button, .cke_combo_button'); $a.each(function (i, el) { var $el = $(el); + $el.attr('tabindex', '0'); var $icon = $el.find('span.cke_button_icon'); if ($icon.length) { try { @@ -30,7 +31,7 @@ define(['jquery'], function ($) { } catch (e) { console.error(e); } } $el.on('keydown blur focus click dragstart', function (e) { - e.preventDefault(); + //e.preventDefault(); var attr = $(el).attr('oon'+e.type); if (!attr) { return; } if (['blur', 'dragstart'].indexOf(e.type) !== -1) { return false; } From 0a1ac01a458962f334cdd9933d89fb18f1500a6c Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 9 Nov 2023 16:58:53 +0100 Subject: [PATCH 057/283] Fix date parser on Daylight Saving time day with 12h format #1011 --- www/calendar/inner.js | 12 +++++++----- www/common/notifications.js | 6 +++--- www/common/outer/calendar.js | 8 ++++---- www/form/inner.js | 6 ++++-- www/lib/calendar/date-picker.js | 14 ++++++++++---- www/lib/calendar/moment.min.js | 2 ++ www/lib/changelog.md | 1 + 7 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 www/lib/calendar/moment.min.js diff --git a/www/calendar/inner.js b/www/calendar/inner.js index 89370dde4..f121a6e63 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -19,6 +19,7 @@ define([ '/calendar/export.js', '/calendar/recurrence.js', '/lib/datepicker/flatpickr.js', + '/lib/calendar/date-picker.js', '/common/inner/share.js', '/common/inner/access.js', @@ -51,6 +52,7 @@ define([ Export, Rec, Flatpickr, + DatePicker, Share, Access, Properties ) { @@ -283,9 +285,9 @@ define([ var obj = data.content[uid]; obj.title = obj.title || ""; obj.location = obj.location || ""; - if (obj.isAllDay && obj.startDay) { obj.start = +Flatpickr.parseDate((obj.startDay)); } + if (obj.isAllDay && obj.startDay) { obj.start = +DatePicker.parseDate((obj.startDay)); } if (obj.isAllDay && obj.endDay) { - var endDate = Flatpickr.parseDate(obj.endDay); + var endDate = DatePicker.parseDate(obj.endDay); endDate.setHours(23); endDate.setMinutes(59); endDate.setSeconds(59); @@ -1639,7 +1641,7 @@ APP.recurrenceRule = { minDate: date, //dateFormat: dateFormat, onChange: function () { - //endPickr.set('minDate', startPickr.parseDate(s.value)); + //endPickr.set('minDate', DatePicker.parseDate(s.value)); } }); var endDate = new Date(+date); @@ -1817,7 +1819,7 @@ APP.recurrenceRule = { if (until === "count") { rec.count = $(radioCount).find('input[type="number"]').val(); } else if (until === "date") { - var _date = Flatpickr.parseDate(pickr.value); + var _date = DatePicker.parseDate(pickr.value); _date.setDate(_date.getDate()+1); rec.until = +_date - 1; } @@ -2110,7 +2112,7 @@ APP.recurrenceRule = { var $button = $el.find('.tui-full-calendar-section-button-save'); var $startDate = $el.find('#tui-full-calendar-schedule-start-date'); - var startDate = Flatpickr.parseDate($startDate.val()); + var startDate = DatePicker.parseDate($startDate.val()); var divRec = getRecurrenceInput(startDate); $button.before(divRec); diff --git a/www/common/notifications.js b/www/common/notifications.js index a9c3ee06f..3ef82c898 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -8,8 +8,8 @@ define([ '/common/common-constants.js', '/customize/messages.js', '/customize/pages.js', - '/lib/datepicker/flatpickr.js', -], function($, h, Hash, UI, UIElements, Util, Constants, Messages, Pages, Flatpickr) { + '/lib/calendar/date-picker.js', +], function($, h, Hash, UI, UIElements, Util, Constants, Messages, Pages, DatePicker) { var handlers = {}; @@ -544,7 +544,7 @@ define([ var nowDateStr = new Date().toLocaleDateString(); var startDate = new Date(start); if (msg.isAllDay && msg.startDay) { - startDate = Flatpickr.parseDate(msg.startDay); + startDate = DatePicker.parseDate(msg.startDay); } // Missed events diff --git a/www/common/outer/calendar.js b/www/common/outer/calendar.js index e10db796f..80df99e80 100644 --- a/www/common/outer/calendar.js +++ b/www/common/outer/calendar.js @@ -8,10 +8,10 @@ define([ '/customize/messages.js', '/components/nthen/index.js', 'chainpad-listmap', - '/lib/datepicker/flatpickr.js', + '/lib/calendar/date-picker.js', '/components/chainpad-crypto/crypto.js', '/components/chainpad/chainpad.dist.js', -], function (Util, Hash, Constants, Realtime, Cache, Rec, Messages, nThen, Listmap, FP, Crypto, ChainPad) { +], function (Util, Hash, Constants, Realtime, Cache, Rec, Messages, nThen, Listmap, DatePicker, Crypto, ChainPad) { var Calendar = {}; var getStore = function (ctx, id) { @@ -132,9 +132,9 @@ define([ var last = ctx.store.data.lastVisit; if (ev.isAllDay) { - if (ev.startDay) { ev.start = +FP.parseDate(ev.startDay); } + if (ev.startDay) { ev.start = +DatePicker.parseDate(ev.startDay); } if (ev.endDay) { - var endDate = FP.parseDate(ev.endDay); + var endDate = DatePicker.parseDate(ev.endDay); endDate.setHours(23); endDate.setMinutes(59); endDate.setSeconds(59); diff --git a/www/form/inner.js b/www/form/inner.js index 624ce7d50..d68c677ed 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -23,6 +23,7 @@ define([ '/common/text-cursor.js', 'cm/lib/codemirror', '/components/chainpad/chainpad.dist.js', + '/lib/calendar/date-picker.js', '/common/inner/share.js', '/common/inner/access.js', @@ -70,6 +71,7 @@ define([ TextCursor, CMeditor, ChainPad, + DatePicker, Share, Access, Properties, Flatpickr, Sortable @@ -2046,7 +2048,7 @@ define([ tag: tag, isEmpty: function () { return !$tag.val().trim(); }, getValue: function () { - var d = picker.parseDate(tag.value); + var d = DatePicker.parseDate(tag.value); return +d; }, setValue: function (val) { @@ -4797,7 +4799,7 @@ define([ if (datePicker.value === '') { return void refreshEndDate(); } - var d = picker.parseDate(datePicker.value); + var d = DatePicker.parseDate(datePicker.value); content.answers.endDate = +d; framework.localChange(); framework._.cpNfInner.chainpad.onSettle(function () { diff --git a/www/lib/calendar/date-picker.js b/www/lib/calendar/date-picker.js index 19b6dccb3..e4fdbb21c 100644 --- a/www/lib/calendar/date-picker.js +++ b/www/lib/calendar/date-picker.js @@ -1,9 +1,10 @@ define([ 'jquery', '/lib/datepicker/flatpickr.js', + '/lib/calendar/moment.min.js', 'css!/lib/datepicker/flatpickr.min.css', -], function ($, Flatpickr) { +], function ($, Flatpickr, Moment) { var createRangePicker = function (cfg) { var start = cfg.startpicker; var end = cfg.endpicker; @@ -15,6 +16,10 @@ define([ } catch (e) {} if (!is24h) { dateFormat = "Y-m-d h:i K"; } + var parseDate = (value) => { + return Moment(value, 'YYYY-MM-DD HH:mm a').toDate(); + }; + var e = $(end.input)[0]; var endPickr = Flatpickr(e, { enableTime: true, @@ -30,7 +35,7 @@ define([ time_24hr: is24h, dateFormat: dateFormat, onChange: function () { - endPickr.set('minDate', startPickr.parseDate(s.value)); + endPickr.set('minDate', parseDate(s.value)); } }); startPickr.setDate(start.date); @@ -39,11 +44,11 @@ define([ var getStartDate = function () { setTimeout(function () { $(startPickr.calendarContainer).remove(); }); - return startPickr.parseDate(s.value); + return parseDate(s.value); }; var getEndDate = function () { setTimeout(function () { $(endPickr.calendarContainer).remove(); }); - var d = endPickr.parseDate(e.value); + var d = parseDate(e.value); if (endPickr.config.dateFormat === "Y-m-d") { // All day event // Tui-calendar will remove 1s (1000ms) to the date for an unknown reason... @@ -59,6 +64,7 @@ define([ }; }; return { + parseDate: parseDate, createRangePicker: createRangePicker }; }); diff --git a/www/lib/calendar/moment.min.js b/www/lib/calendar/moment.min.js new file mode 100644 index 000000000..3427886d1 --- /dev/null +++ b/www/lib/calendar/moment.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var H;function f(){return H.apply(null,arguments)}function a(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function F(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function c(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function L(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(c(e,t))return;return 1}function o(e){return void 0===e}function u(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function V(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function G(e,t){for(var n=[],s=e.length,i=0;i>>0,s=0;sAe(e)?(r=e+1,t-Ae(e)):(r=e,t);return{year:r,dayOfYear:n}}function qe(e,t,n){var s,i,r=ze(e.year(),t,n),r=Math.floor((e.dayOfYear()-r-1)/7)+1;return r<1?s=r+P(i=e.year()-1,t,n):r>P(e.year(),t,n)?(s=r-P(e.year(),t,n),i=e.year()+1):(i=e.year(),s=r),{week:s,year:i}}function P(e,t,n){var s=ze(e,t,n),t=ze(e+1,t,n);return(Ae(e)-s+t)/7}s("w",["ww",2],"wo","week"),s("W",["WW",2],"Wo","isoWeek"),t("week","w"),t("isoWeek","W"),n("week",5),n("isoWeek",5),v("w",p),v("ww",p,w),v("W",p),v("WW",p,w),Te(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=g(e)});function Be(e,t){return e.slice(t,7).concat(e.slice(0,t))}s("d",0,"do","day"),s("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),s("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),s("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),s("e",0,0,"weekday"),s("E",0,0,"isoWeekday"),t("day","d"),t("weekday","e"),t("isoWeekday","E"),n("day",11),n("weekday",11),n("isoWeekday",11),v("d",p),v("e",p),v("E",p),v("dd",function(e,t){return t.weekdaysMinRegex(e)}),v("ddd",function(e,t){return t.weekdaysShortRegex(e)}),v("dddd",function(e,t){return t.weekdaysRegex(e)}),Te(["dd","ddd","dddd"],function(e,t,n,s){s=n._locale.weekdaysParse(e,s,n._strict);null!=s?t.d=s:m(n).invalidWeekday=e}),Te(["d","e","E"],function(e,t,n,s){t[s]=g(e)});var Je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Qe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Xe="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ke=k,et=k,tt=k;function nt(){function e(e,t){return t.length-e.length}for(var t,n,s,i=[],r=[],a=[],o=[],u=0;u<7;u++)s=l([2e3,1]).day(u),t=M(this.weekdaysMin(s,"")),n=M(this.weekdaysShort(s,"")),s=M(this.weekdays(s,"")),i.push(t),r.push(n),a.push(s),o.push(t),o.push(n),o.push(s);i.sort(e),r.sort(e),a.sort(e),o.sort(e),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+r.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+i.join("|")+")","i")}function st(){return this.hours()%12||12}function it(e,t){s(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function rt(e,t){return t._meridiemParse}s("H",["HH",2],0,"hour"),s("h",["hh",2],0,st),s("k",["kk",2],0,function(){return this.hours()||24}),s("hmm",0,0,function(){return""+st.apply(this)+r(this.minutes(),2)}),s("hmmss",0,0,function(){return""+st.apply(this)+r(this.minutes(),2)+r(this.seconds(),2)}),s("Hmm",0,0,function(){return""+this.hours()+r(this.minutes(),2)}),s("Hmmss",0,0,function(){return""+this.hours()+r(this.minutes(),2)+r(this.seconds(),2)}),it("a",!0),it("A",!1),t("hour","h"),n("hour",13),v("a",rt),v("A",rt),v("H",p),v("h",p),v("k",p),v("HH",p,w),v("hh",p,w),v("kk",p,w),v("hmm",ge),v("hmmss",we),v("Hmm",ge),v("Hmmss",we),D(["H","HH"],x),D(["k","kk"],function(e,t,n){e=g(e);t[x]=24===e?0:e}),D(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),D(["h","hh"],function(e,t,n){t[x]=g(e),m(n).bigHour=!0}),D("hmm",function(e,t,n){var s=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s)),m(n).bigHour=!0}),D("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s,2)),t[N]=g(e.substr(i)),m(n).bigHour=!0}),D("Hmm",function(e,t,n){var s=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s))}),D("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[x]=g(e.substr(0,s)),t[T]=g(e.substr(s,2)),t[N]=g(e.substr(i))});k=de("Hours",!0);var at,ot={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ce,monthsShort:Ue,week:{dow:0,doy:6},weekdays:Je,weekdaysMin:Xe,weekdaysShort:Qe,meridiemParse:/[ap]\.?m?\.?/i},R={},ut={};function lt(e){return e&&e.toLowerCase().replace("_","-")}function ht(e){for(var t,n,s,i,r=0;r=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s=t-1)break;t--}r++}return at}function dt(t){var e;if(void 0===R[t]&&"undefined"!=typeof module&&module&&module.exports&&null!=t.match("^[^/\\\\]*$"))try{e=at._abbr,require("./locale/"+t),ct(e)}catch(e){R[t]=null}return R[t]}function ct(e,t){return e&&((t=o(t)?mt(e):ft(e,t))?at=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),at._abbr}function ft(e,t){if(null===t)return delete R[e],null;var n,s=ot;if(t.abbr=e,null!=R[e])Q("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=R[e]._config;else if(null!=t.parentLocale)if(null!=R[t.parentLocale])s=R[t.parentLocale]._config;else{if(null==(n=dt(t.parentLocale)))return ut[t.parentLocale]||(ut[t.parentLocale]=[]),ut[t.parentLocale].push({name:e,config:t}),null;s=n._config}return R[e]=new K(X(s,t)),ut[e]&&ut[e].forEach(function(e){ft(e.name,e.config)}),ct(e),R[e]}function mt(e){var t;if(!(e=e&&e._locale&&e._locale._abbr?e._locale._abbr:e))return at;if(!a(e)){if(t=dt(e))return t;e=[e]}return ht(e)}function _t(e){var t=e._a;return t&&-2===m(e).overflow&&(t=t[O]<0||11We(t[Y],t[O])?b:t[x]<0||24P(r,u,l)?m(s)._overflowWeeks=!0:null!=h?m(s)._overflowWeekday=!0:(d=$e(r,a,o,u,l),s._a[Y]=d.year,s._dayOfYear=d.dayOfYear)),null!=e._dayOfYear&&(i=bt(e._a[Y],n[Y]),(e._dayOfYear>Ae(i)||0===e._dayOfYear)&&(m(e)._overflowDayOfYear=!0),h=Ze(i,0,e._dayOfYear),e._a[O]=h.getUTCMonth(),e._a[b]=h.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=n[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[x]&&0===e._a[T]&&0===e._a[N]&&0===e._a[Ne]&&(e._nextDay=!0,e._a[x]=0),e._d=(e._useUTC?Ze:je).apply(null,c),r=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[x]=24),e._w&&void 0!==e._w.d&&e._w.d!==r&&(m(e).weekdayMismatch=!0)}}function Tt(e){if(e._f===f.ISO_8601)St(e);else if(e._f===f.RFC_2822)Ot(e);else{e._a=[],m(e).empty=!0;for(var t,n,s,i,r,a=""+e._i,o=a.length,u=0,l=ae(e._f,e._locale).match(te)||[],h=l.length,d=0;de.valueOf():e.valueOf()"}),i.toJSON=function(){return this.isValid()?this.toISOString():null},i.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},i.unix=function(){return Math.floor(this.valueOf()/1e3)},i.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},i.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},i.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;nthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},i.isLocal=function(){return!!this.isValid()&&!this._isUTC},i.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},i.isUtc=At,i.isUTC=At,i.zoneAbbr=function(){return this._isUTC?"UTC":""},i.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},i.dates=e("dates accessor is deprecated. Use date instead.",ke),i.months=e("months accessor is deprecated. Use month instead",Ge),i.years=e("years accessor is deprecated. Use year instead",Ie),i.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?(this.utcOffset(e="string"!=typeof e?-e:e,t),this):-this.utcOffset()}),i.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!o(this._isDSTShifted))return this._isDSTShifted;var e,t={};return $(t,this),(t=Nt(t))._a?(e=(t._isUTC?l:W)(t._a),this._isDSTShifted=this.isValid()&&0 Date: Thu, 9 Nov 2023 17:26:18 +0100 Subject: [PATCH 058/283] Add missing file --- www/common/inner/mfa.js | 321 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 www/common/inner/mfa.js diff --git a/www/common/inner/mfa.js b/www/common/inner/mfa.js new file mode 100644 index 000000000..0f4fdbba5 --- /dev/null +++ b/www/common/inner/mfa.js @@ -0,0 +1,321 @@ +define([ + 'jquery', + '/customize/messages.js', + '/common/hyperscript.js', + '/common/common-interface.js', + '/components/nthen/index.js', + '/customize.dist/login.js', + '/common/common-util.js', + +], function ($, Messages, h, UI, nThen, Login, Util) { + const MFA = {}; + + MFA.totpSetup = function (common, config, content, enabled, cb) { + + var sframeChan = common.getSframeChannel(); + // NOTE privateData may not be defined yet + var accountName = config.accountName; + var origin = config.origin; + + var $content = $(content).empty(); + $content.append(h('div.cp-settings-mfa-hint.cp-settings-mfa-status' + (enabled ? '.mfa-enabled' : '.mfa-disabled'), [ + h('i.fa' + (enabled ? '.fa-check' : '.fa-times')), + h('span', enabled ? Messages.mfa_status_on : Messages.mfa_status_off) + ])); + + if (enabled) { + (function () { + var button = h('button.btn', Messages.mfa_disable); + button.classList.add('disable-button'); + var $mfaRevokeBtn = $(button); + var pwInput; + var pwContainer = h('div.cp-password-container', [ + h('label.cp-settings-mfa-hint', { for: 'cp-mfa-password' }, Messages.mfa_revoke_label), + pwInput = h('input#cp-mfa-password', { + type: 'password', + placeholder: Messages.login_password, + }), + button + ]); + $content.append(pwContainer); + + // submit password on enter keyup + $(pwInput).on('keyup', e => { + if (e.which === 13) { $mfaRevokeBtn.click(); } + }); + + var spinner = UI.makeSpinner($mfaRevokeBtn); + $mfaRevokeBtn.click(function () { + var name = accountName; + var password = $(pwInput).val(); + if (!password) { return void UI.warn(Messages.login_noSuchUser); } + + spinner.spin(); + $(pwInput).prop('disabled', 'disabled'); + $mfaRevokeBtn.prop('disabled', 'disabled'); + var blockKeys; + + nThen(function (waitFor) { + var next = waitFor(); + // scrypt locks up the UI before the DOM has a chance + // to update (displaying logs, etc.), so do a set timeout + setTimeout(function () { + Login.Cred.deriveFromPassphrase(name, password, Login.requiredBytes, function (bytes) { + var result = Login.allocateBytes(bytes); + sframeChan.query("Q_SETTINGS_CHECK_PASSWORD", { + blockHash: result.blockHash, + }, function (err, obj) { + if (!obj || !obj.correct) { + spinner.hide(); + UI.warn(Messages.login_noSuchUser); + $mfaRevokeBtn.removeAttr('disabled'); + $(pwInput).removeAttr('disabled'); + waitFor.abort(); + return; + } + spinner.done(); + blockKeys = result.blockKeys; + next(); + }); + }); + }, 100); + }).nThen(function () { + $(pwContainer).remove(); + var OTPEntry; + var disable = h('button.btn.disable-button', Messages.mfa_revoke_button); + $content.append(h('div.cp-password-container', [ + h('label.cp-settings-mfa-hint', { for: 'cp-mfa-password' }, Messages.mfa_revoke_code), + OTPEntry = h('input', { + placeholder: Messages.settings_otp_code + }), + disable + ])); + var $OTPEntry = $(OTPEntry); + var $d = $(disable).click(function () { + $d.prop('disabled', 'disabled'); + var code = $OTPEntry.val(); + sframeChan.query("Q_SETTINGS_TOTP_REVOKE", { + key: blockKeys.sign, + data: { + command: 'TOTP_REVOKE', + code: code, + } + }, function (err, obj) { + $OTPEntry.val(""); + if (err || !obj || !obj.success) { + $d.removeAttr('disabled'); + return void UI.warn(Messages.settings_otp_invalid); + } + cb(false); + }, {raw: true}); + + }); + OTPEntry.focus(); + // submit OTP on enter keyup + $OTPEntry.on('keyup', e => { + if (e.which === 13) { $d.click(); } + }); + }); + }); + + })(); + return; + } + + var button = h('button.btn.btn-primary', Messages.mfa_setup_button); + var $mfaSetupBtn = $(button); + var pwInput; + $content.append(h('div.cp-password-container', [ + h('label.cp-settings-mfa-hint', { for: 'cp-mfa-password' }, Messages.mfa_setup_label), + pwInput = h('input#cp-mfa-password', { + type: 'password', + placeholder: Messages.login_password, + }), + button + ])); + var spinner = UI.makeSpinner($mfaSetupBtn); + + // submit password on enter keyup + $(pwInput).on('keyup', e => { + if (e.which === 13) { $(button).click(); } + }); + + $(button).click(function () { + var name = accountName; + var password = $(pwInput).val(); + if (!password) { return void UI.warn(Messages.login_noSuchUser); } + + spinner.spin(); + $(pwInput).prop('disabled', 'disabled'); + $mfaSetupBtn.prop('disabled', 'disabled'); + + var Base32, QRCode, Nacl; + var blockKeys; + var recoverySecret; + var ssoSeed; + nThen(function (waitFor) { + require([ + '/auth/base32.js', + '/lib/qrcode.min.js', + '/components/tweetnacl/nacl-fast.min.js', + ], waitFor(function (_Base32) { + Base32 = _Base32; + QRCode = window.QRCode; + Nacl = window.nacl; + })); + }).nThen(function (waitFor) { + sframeChan.query("Q_SETTINGS_GET_SSO_SEED", { + }, waitFor(function (err, obj) { + if (!obj || !obj.seed) { return; } // Not an sso account? + ssoSeed = obj.seed; + })); + }).nThen(function (waitFor) { + var next = waitFor(); + // scrypt locks up the UI before the DOM has a chance + // to update (displaying logs, etc.), so do a set timeout + setTimeout(function () { + var salt = ssoSeed || name; + Login.Cred.deriveFromPassphrase(salt, password, Login.requiredBytes, function (bytes) { + console.error(bytes); + var result = Login.allocateBytes(bytes); + sframeChan.query("Q_SETTINGS_CHECK_PASSWORD", { + blockHash: result.blockHash, + }, function (err, obj) { + console.error(obj); + if (!obj || !obj.correct) { + spinner.hide(); + UI.warn(Messages.login_noSuchUser); + $mfaSetupBtn.removeAttr('disabled'); + $(pwInput).removeAttr('disabled'); + waitFor.abort(); + return; + } + console.warn(obj); + spinner.done(); + blockKeys = result.blockKeys; + next(); + }); + }); + }, 100); + }).nThen(function (waitFor) { + $content.empty(); + var next = waitFor(); + recoverySecret = Nacl.util.encodeBase64(Nacl.randomBytes(24)); + var button = h('button.btn.btn-primary', [ + h('i.fa.fa-check'), + h('span', Messages.done) + ]); + $content.append(h('div.alert.alert-danger', [ + h('h2', Messages.mfa_recovery_title), + h('p', Messages.mfa_recovery_hint), + h('p', Messages.mfa_recovery_warning), + h('div.cp-password-container', [ + UI.dialog.selectable(recoverySecret), + button + ]) + ])); + + var nextButton = h('button.btn.btn-primary', { + 'disabled': 'disabled' + }, Messages.continue); + $(nextButton).click(function () { + next(); + }).appendTo($content); + + $(button).click(function () { + $content.find('.alert-danger').removeClass('alert-danger').addClass('alert-success'); + $(button).prop('disabled', 'disabled'); + $(nextButton).removeAttr('disabled'); + }); + }).nThen(function () { + var randomSecret = function () { + var U8 = Nacl.randomBytes(20); + return Base32.encode(U8); + }; + $content.empty(); + + var updateQR = Util.mkAsync(function (uri, target) { + new QRCode(target, uri); + }); + var updateURI = function (secret) { + var username = accountName; + var hostname = new URL(origin).hostname; + var label = "CryptPad"; + + var uri = `otpauth://totp/${label}:${username}@${hostname}?secret=${secret}`; + + var qr = h('div.cp-settings-qr'); + var uriInput = UI.dialog.selectable(uri); + + updateQR(uri, qr); + + var OTPEntry = h('input', { + placeholder: Messages.settings_otp_code + }); + var $OTPEntry = $(OTPEntry); + + var description = h('p.cp-settings-mfa-hint', Messages.settings_otp_tuto); + var confirmOTP = h('button.btn.btn-primary', [ + h('i.fa.fa-check'), + h('span', Messages.mfa_enable) + ]); + var lock = false; + + confirmOTP.addEventListener('click', function () { + var code = $OTPEntry.val(); + if (code.length !== 6 || /\D/.test(code)) { + return void UI.warn(Messages.settings_otp_invalid); + } + confirmOTP.disabled = true; + lock = true; + + var data = { + secret: secret, + contact: "secret:" + recoverySecret, // TODO other recovery options + code: code, + }; + + sframeChan.query("Q_SETTINGS_TOTP_SETUP", { + key: blockKeys.sign, + data: data + }, function (err, obj) { + lock = false; + $OTPEntry.val(""); + if (err || !obj || !obj.success) { + confirmOTP.disabled = false; + console.error(err); + return void UI.warn(Messages.error); + } + cb(true); + }, { raw: true }); + }); + + $content.append([ + description, + uriInput, + h('div.cp-settings-qr-container', [ + qr, + h('div.cp-settings-qr-code', [ + OTPEntry, + h('br'), + confirmOTP + ]) + ]) + ]); + OTPEntry.focus(); + // submit OTP on enter keyup + $OTPEntry.on('keyup', e => { + if (e.which === 13) { $(confirmOTP).click(); } + }); + }; + + + var secret = randomSecret(); + updateURI(secret); + }); + + }); + }; + + return MFA; +}); From 7b86af5ac4085da09b9e993ee66c3a2a4c2ef683 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 9 Nov 2023 17:56:53 +0100 Subject: [PATCH 059/283] Fix calendar not loading after latest commit --- www/calendar/inner.js | 2 +- www/common/notifications.js | 2 +- www/form/inner.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index f121a6e63..0969ddd54 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -19,7 +19,7 @@ define([ '/calendar/export.js', '/calendar/recurrence.js', '/lib/datepicker/flatpickr.js', - '/lib/calendar/date-picker.js', + 'tui-date-picker', '/common/inner/share.js', '/common/inner/access.js', diff --git a/www/common/notifications.js b/www/common/notifications.js index 3ef82c898..c3a0df25b 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -8,7 +8,7 @@ define([ '/common/common-constants.js', '/customize/messages.js', '/customize/pages.js', - '/lib/calendar/date-picker.js', + 'tui-date-picker' ], function($, h, Hash, UI, UIElements, Util, Constants, Messages, Pages, DatePicker) { var handlers = {}; diff --git a/www/form/inner.js b/www/form/inner.js index d68c677ed..5e12ea574 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -23,7 +23,7 @@ define([ '/common/text-cursor.js', 'cm/lib/codemirror', '/components/chainpad/chainpad.dist.js', - '/lib/calendar/date-picker.js', + 'tui-date-picker', '/common/inner/share.js', '/common/inner/access.js', From e33443235d51dd4fe964b21fedbcbdd76558c2bf Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 10 Nov 2023 16:52:50 +0100 Subject: [PATCH 060/283] Different team slots config value for premium users --- www/common/application_config_internal.js | 4 ++++ www/common/common-constants.js | 2 ++ www/common/common-ui-elements.js | 2 +- www/teams/inner.js | 23 +++++++++++++++-------- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/www/common/application_config_internal.js b/www/common/application_config_internal.js index cdcf6014c..bb045cfc5 100644 --- a/www/common/application_config_internal.js +++ b/www/common/application_config_internal.js @@ -270,6 +270,10 @@ define(function() { // You can change the value here. // AppConfig.maxOwnedTeams = 5; + // Same settings but for premium users (users with a custom limit included) + // AppConfig.maxPremiumTeamsSlots = 10; + // AppConfig.maxPremiumTeamsOwned = 10; + // The userlist displayed in collaborative documents is stored alongside the document data. // Everytime someone with edit rights joins a document or modify their user data (display // name, avatar, color, etc.), they update the "userlist" part of the document. When too many diff --git a/www/common/common-constants.js b/www/common/common-constants.js index 888edeafd..35d6fa0ab 100644 --- a/www/common/common-constants.js +++ b/www/common/common-constants.js @@ -18,6 +18,8 @@ define(['/customize/application_config.js'], function (AppConfig) { deprecatedKey: 'deprecated', MAX_TEAMS_SLOTS: AppConfig.maxTeamsSlots || 5, MAX_TEAMS_OWNED: AppConfig.maxOwnedTeams || 5, + MAX_PREMIUM_TEAMS_SLOTS: Math.max(AppConfig.maxTeamsSlots || 0, AppConfig.maxPremiumTeamsSlots || 0) || 5, + MAX_PREMIUM_TEAMS_OWNED: Math.max(AppConfig.maxTeamsOwned || 0, AppConfig.maxPremiumTeamsOwned || 0) || 5, // Apps criticalApps: ['profile', 'settings', 'debug', 'admin', 'support', 'notifications', 'calendar'], earlyAccessApps: ['doc', 'presentation'] diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 3a03807f2..8059caff0 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -3599,9 +3599,9 @@ define([ }); }; - var MAX_TEAMS_SLOTS = Constants.MAX_TEAMS_SLOTS; var todo = function (yes) { var priv = common.getMetadataMgr().getPrivateData(); + var MAX_TEAMS_SLOTS = priv.plan ? Constants.MAX_PREMIUM_TEAMS_SLOTS : Constants.MAX_TEAMS_SLOTS; var numberOfTeams = Object.keys(priv.teams || {}).length; if (yes) { if (numberOfTeams >= MAX_TEAMS_SLOTS) { diff --git a/www/teams/inner.js b/www/teams/inner.js index 80cad3bd6..d8291ab7b 100644 --- a/www/teams/inner.js +++ b/www/teams/inner.js @@ -393,7 +393,6 @@ define([ ]); }); - var MAX_TEAMS_SLOTS = Constants.MAX_TEAMS_SLOTS; var openTeam = function (common, id, team) { var sframeChan = common.getSframeChannel(); APP.module.execCommand('SUBSCRIBE', id, function () { @@ -421,14 +420,18 @@ define([ }); }); }; - var canCreateTeams = function (teams) { + var canCreateTeams = function (common, teams) { var owned = Object.keys(teams || {}).filter(function (id) { return teams[id].owner; }).length; - return Constants.MAX_TEAMS_OWNED - owned; + var priv = common.getMetadataMgr().getPrivateData(); + var MAX_TEAMS_OWNED = priv.plan ? Constants.MAX_PREMIUM_TEAMS_OWNED : Constants.MAX_TEAMS_OWNED; + return MAX_TEAMS_OWNED - owned; }; var refreshList = function (common, cb) { var content = []; + var priv = common.getMetadataMgr().getPrivateData(); + var MAX_TEAMS_SLOTS = priv.plan ? Constants.MAX_PREMIUM_TEAMS_SLOTS : Constants.MAX_TEAMS_SLOTS; APP.module.execCommand('LIST_TEAMS', null, function (obj) { if (!obj) { return; } if (obj.error === "OFFLINE") { return UI.alert(Messages.driveOfflineError); } @@ -436,7 +439,7 @@ define([ var list = []; var keys = Object.keys(obj).slice(0,MAX_TEAMS_SLOTS); var slots = '('+Math.min(keys.length, MAX_TEAMS_SLOTS)+'/'+MAX_TEAMS_SLOTS+')'; - var createSlots = canCreateTeams(obj); + var createSlots = canCreateTeams(common, obj); for (var i = keys.length; i < MAX_TEAMS_SLOTS; i++) { obj[i] = { empty: true @@ -513,9 +516,12 @@ define([ var privateData = metadataMgr.getPrivateData(); var content = []; + var MAX_TEAMS_OWNED = privateData.plan ? Constants.MAX_PREMIUM_TEAMS_OWNED : Constants.MAX_TEAMS_OWNED; + var MAX_TEAMS_SLOTS = privateData.plan ? Constants.MAX_PREMIUM_TEAMS_SLOTS : Constants.MAX_TEAMS_SLOTS; + var isOwner = Object.keys(privateData.teams || {}).filter(function (id) { return privateData.teams[id].owner; - }).length >= Constants.MAX_TEAMS_OWNED && !privateData.devMode; + }).length >= MAX_TEAMS_OWNED && !privateData.devMode; var getWarningBox = function () { return h('div.alert.alert-warning', { @@ -523,7 +529,7 @@ define([ }, Messages._getKey('team_maxTeams', [MAX_TEAMS_SLOTS])); }; - if (Object.keys(privateData.teams || {}).length >= Constants.MAX_TEAMS_SLOTS || isOwner) { + if (Object.keys(privateData.teams || {}).length >= MAX_TEAMS_SLOTS || isOwner) { content.push(getWarningBox()); return void cb(content); } @@ -1252,12 +1258,13 @@ define([ var password = hashData.password; var seeds = InviteInner.deriveSeeds(hashData.key); var sframeChan = common.getSframeChannel(); + var MAX_TEAMS_SLOTS = privateData.plan ? Constants.MAX_PREMIUM_TEAMS_SLOTS : Constants.MAX_TEAMS_SLOTS; - if (Object.keys(privateData.teams || {}).length >= Constants.MAX_TEAMS_SLOTS) { + if (Object.keys(privateData.teams || {}).length >= MAX_TEAMS_SLOTS) { return void cb([ h('div.alert.alert-danger', { role: 'alert' - }, Messages._getKey('team_maxTeams', [Constants.MAX_TEAMS_SLOTS])) + }, Messages._getKey('team_maxTeams', [MAX_TEAMS_SLOTS])) ]); } From e24703e4e684b0a0f07a065d4611b5c75d6f16cd Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 10 Nov 2023 11:17:20 -0500 Subject: [PATCH 061/283] Fix wrong event start/end time in calendar on Daylight Saving Time days --- www/calendar/inner.js | 5 ++++- www/calendar/recurrence.js | 20 +++++++------------- www/common/outer/calendar.js | 8 ++++---- www/lib/calendar/date-picker.js | 9 +++++---- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index 0969ddd54..07bde0e3a 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -105,6 +105,8 @@ define([ var startDate = event.start._date; var endDate = event.end._date; + var timeZone; + try { timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (e) {} var data = { id: Util.uid(), calendarId: event.calendarId, @@ -115,7 +117,8 @@ define([ isAllDay: event.isAllDay, end: +endDate, reminders: reminders, - recurrenceRule: event.recurrenceRule + recurrenceRule: event.recurrenceRule, + timeZone: timeZone }; APP.module.execCommand('CREATE_EVENT', data, function (obj) { diff --git a/www/calendar/recurrence.js b/www/calendar/recurrence.js index 6a0cdff01..cd547a3e4 100644 --- a/www/calendar/recurrence.js +++ b/www/calendar/recurrence.js @@ -590,25 +590,14 @@ define([ // Return the difference in timestamps, as minutes (60*1000) return -(utcDate - date); - } + }; var myTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; var offset = getOffset(origin, evTimeZone) - getOffset(target, evTimeZone); var myOffset = getOffset(origin, myTimeZone) - getOffset(target, myTimeZone); - return offset - myOffset; + return myOffset - offset; }; -/* -XXX to test - var first = new Date(2023, 09, 10, 15) - var second = new Date(2023, 09, 30, 15) - fixTimeZone('America/New_York', first, second) ==> should return +1h - -*/ - - - - Rec.getRecurring = function (months, events) { if (window.CP_DEV_MODE) { debug = console.warn; } @@ -767,6 +756,11 @@ XXX to test } // Add this event + if (_origin.timeZone && !_ev.isAllDay) { + var offset = fixTimeZone(_origin.timeZone, _start, _evS); + _ev.start += offset; + _ev.end += offset; + } toAdd.push(_ev); if (newrule) { useNewRule(); diff --git a/www/common/outer/calendar.js b/www/common/outer/calendar.js index 80df99e80..e10db796f 100644 --- a/www/common/outer/calendar.js +++ b/www/common/outer/calendar.js @@ -8,10 +8,10 @@ define([ '/customize/messages.js', '/components/nthen/index.js', 'chainpad-listmap', - '/lib/calendar/date-picker.js', + '/lib/datepicker/flatpickr.js', '/components/chainpad-crypto/crypto.js', '/components/chainpad/chainpad.dist.js', -], function (Util, Hash, Constants, Realtime, Cache, Rec, Messages, nThen, Listmap, DatePicker, Crypto, ChainPad) { +], function (Util, Hash, Constants, Realtime, Cache, Rec, Messages, nThen, Listmap, FP, Crypto, ChainPad) { var Calendar = {}; var getStore = function (ctx, id) { @@ -132,9 +132,9 @@ define([ var last = ctx.store.data.lastVisit; if (ev.isAllDay) { - if (ev.startDay) { ev.start = +DatePicker.parseDate(ev.startDay); } + if (ev.startDay) { ev.start = +FP.parseDate(ev.startDay); } if (ev.endDay) { - var endDate = DatePicker.parseDate(ev.endDay); + var endDate = FP.parseDate(ev.endDay); endDate.setHours(23); endDate.setMinutes(59); endDate.setSeconds(59); diff --git a/www/lib/calendar/date-picker.js b/www/lib/calendar/date-picker.js index e4fdbb21c..298dd9be5 100644 --- a/www/lib/calendar/date-picker.js +++ b/www/lib/calendar/date-picker.js @@ -5,6 +5,11 @@ define([ 'css!/lib/datepicker/flatpickr.min.css', ], function ($, Flatpickr, Moment) { + + var parseDate = (value) => { + return Moment(value, 'YYYY-MM-DD HH:mm a').toDate(); + }; + var createRangePicker = function (cfg) { var start = cfg.startpicker; var end = cfg.endpicker; @@ -16,10 +21,6 @@ define([ } catch (e) {} if (!is24h) { dateFormat = "Y-m-d h:i K"; } - var parseDate = (value) => { - return Moment(value, 'YYYY-MM-DD HH:mm a').toDate(); - }; - var e = $(end.input)[0]; var endPickr = Flatpickr(e, { enableTime: true, From 4924c8664a35b4cc77ebeeff17afdbf2a57999be Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 16 Nov 2023 10:23:22 +0100 Subject: [PATCH 062/283] Simplify CryptPad URLs --- www/diagram/inner.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/www/diagram/inner.js b/www/diagram/inner.js index a30fa01f7..2af3caef4 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -130,15 +130,16 @@ define([ const url = new URL(src); const params = new URLSearchParams(); params.set('type', type); + params.set('protocol', url.protocol); url.search = params.toString(); - url.protocol = url.protocol === 'https:' ? 'cryptpads:' : 'cryptpad:'; + url.protocol = 'cryptpad:'; url.hash = key; return url.href; }; const parseCryptPadUrl = function(href) { const url = new URL(href); - url.protocol = url.protocol === 'cryptpads:' ? 'https:' : 'http:'; + url.protocol = url.searchParams.get('protocol'); const key = url.hash.substring(1); // remove leading '#' const type = url.searchParams.get('type'); url.search = ''; From 223dc9394ba989a64ffc590c974eca399f614c4d Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 17 Nov 2023 17:19:04 +0100 Subject: [PATCH 063/283] New plugin structure --- lib/archive-account.js | 3 ++- lib/challenge-commands/totp.js | 3 +-- lib/commands/admin-rpc.js | 4 ++-- lib/commands/block.js | 4 ++-- lib/env.js | 3 +++ lib/http-commands.js | 3 ++- lib/http-worker.js | 3 ++- lib/plugin-manager.js | 18 ++++++++++++++++++ 8 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 lib/plugin-manager.js diff --git a/lib/archive-account.js b/lib/archive-account.js index 31256336b..2e9217572 100644 --- a/lib/archive-account.js +++ b/lib/archive-account.js @@ -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"); diff --git a/lib/challenge-commands/totp.js b/lib/challenge-commands/totp.js index 8854d681f..9be38a1ed 100644 --- a/lib/challenge-commands/totp.js +++ b/lib/challenge-commands/totp.js @@ -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 diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 55f5b7a9d..a2c1686cb 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -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); diff --git a/lib/commands/block.js b/lib/commands/block.js index 18e1d21a6..d7f33a295 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -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, () => {}); diff --git a/lib/env.js b/lib/env.js index 82870626e..20f0c4afa 100644 --- a/lib/env.js +++ b/lib/env.js @@ -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(), diff --git a/lib/http-commands.js b/lib/http-commands.js index dcac23421..f32c998fb 100644 --- a/lib/http-commands.js +++ b/lib/http-commands.js @@ -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 diff --git a/lib/http-worker.js b/lib/http-worker.js index 94a68ae76..0de5db29d 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -13,11 +13,12 @@ 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); const response = Util.response(function (errLabel, info) { diff --git a/lib/plugin-manager.js b/lib/plugin-manager.js new file mode 100644 index 000000000..e7a209ad5 --- /dev/null +++ b/lib/plugin-manager.js @@ -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) { + console.error(err); +} + +module.exports = plugins; From 5d6591e7314ca16b6b74d5432c2e624db42369ef Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Thu, 23 Nov 2023 15:55:28 +0100 Subject: [PATCH 064/283] added button to duplicate questions in forms --- www/form/app-form.less | 9 +++++++++ www/form/inner.js | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 4738eb934..f3bd752b6 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -127,6 +127,14 @@ } } + @media (min-width: 1350px) { + .cp-form-copy-button { + margin-right: -70%; + } + + } + + &.cp-form-readonly { .cp-form-creator-inline-add { display: none; @@ -137,6 +145,7 @@ .cp-form-edit-buttons-container button { display: none; } + .cp-form-edit-save { display: none; } diff --git a/www/form/inner.js b/www/form/inner.js index 3615b0aee..a513877d4 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -75,6 +75,8 @@ define([ Sortable ) { + Messages.form_copyQuestion = 'Duplicate' //XXX + var APP = window.APP = { blocks: {} }; @@ -4096,7 +4098,39 @@ define([ h('i.fa.fa-pencil'), h('span', Messages.form_editBlock) ]); - editButtons = h('div.cp-form-edit-buttons-container', [ edit, del ]); + var copy = h('button.btn.btn-default.cp-form-copy-button', [ + h('i.fa.fa-copy'), + h('span', Messages.form_copyQuestion) + ]); + $(copy).click(function() { + if (!APP.isEditor) { return; } + var full = !uid; + var arr = content.order; + var idx = content.order.indexOf(uid); + if (!full) { + var obj = getSectionFromQ(content, uid); + arr = obj.arr; + idx = obj.idx; + var _uid = Util.uid(); + } + + var model = TYPES[type] || STATIC_TYPES[type]; + if (!model) { return; } + content.form[_uid] = { + //q: Messages.form_default, + opts: model.defaultOpts ? Util.clone(model.defaultOpts) : undefined, + type: type, + }; + if (full) { + arr.push(_uid); + } else { + arr.splice(idx, 0, _uid); + } + framework.localChange(); + updateForm(framework, content, true); + }) + + editButtons = h('div.cp-form-edit-buttons-container', [ edit, copy, del ]); editContainer = h('div'); if (type === 'poll' && block.opts.values.length === 0) { $(editButtons).addClass('cp-empty-poll-edit-buttons') @@ -4137,6 +4171,7 @@ define([ $(editContainer).find('.cp-form-preview-button').prependTo(editButtons); $(edit).hide(); + $(copy).hide() }; $(edit).click(function () { onEdit(); @@ -4229,7 +4264,6 @@ define([ if (APP.isEditor) { elements.push(getFormCreator()); } - var _content = elements; if (!editable) { _content = []; From 027d1de6fe56f4354a3f5b6cb8371b6da8ade1ad Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Fri, 24 Nov 2023 11:23:07 +0100 Subject: [PATCH 065/283] corrections and improvements to question duplication feature #868 --- www/form/app-form.less | 9 ++++----- www/form/inner.js | 21 +++++++++++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index f3bd752b6..433d02ca3 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -127,14 +127,13 @@ } } - @media (min-width: 1350px) { - .cp-form-copy-button { - margin-right: -70%; - } - + .cp-form-copy-button { + margin-right: 5px; } + + &.cp-form-readonly { .cp-form-creator-inline-add { display: none; diff --git a/www/form/inner.js b/www/form/inner.js index a513877d4..64a9a8784 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4026,7 +4026,6 @@ define([ value: block.q || Messages.form_default }); var $inputQ = $(inputQ); - var saving = false; var cancel = false; var onSaveQ = function (e) { @@ -4116,9 +4115,21 @@ define([ var model = TYPES[type] || STATIC_TYPES[type]; if (!model) { return; } + var question; + if (content.form[uid].q) { + question = content.form[uid].q + } else { + question = Messages.form_default + } + var options; + if (content.form[uid].opts) { + options = content.form[uid].opts + } else { + options = Util.clone(model.defaultOpts) + } content.form[_uid] = { - //q: Messages.form_default, - opts: model.defaultOpts ? Util.clone(model.defaultOpts) : undefined, + q: question, + opts: options, type: type, }; if (full) { @@ -4130,7 +4141,8 @@ define([ updateForm(framework, content, true); }) - editButtons = h('div.cp-form-edit-buttons-container', [ edit, copy, del ]); + copydelContainer = h('div', [copy, del]) + editButtons = h('div.cp-form-edit-buttons-container', [ edit, copydelContainer]); editContainer = h('div'); if (type === 'poll' && block.opts.values.length === 0) { $(editButtons).addClass('cp-empty-poll-edit-buttons') @@ -4141,6 +4153,7 @@ define([ $(editContainer).empty(); var $oldTag = $(data.tag); $(edit).show(); + $(copy).show(); $(previewDiv).show(); $(requiredDiv).hide(); From 078095c3e25d39707bdaab7ec066ceed6cb7158b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 24 Nov 2023 11:52:57 +0100 Subject: [PATCH 066/283] reimplement proper service logging after mistake in e80b6c2 --- docs/cryptpad.service | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/cryptpad.service b/docs/cryptpad.service index 28de3485d..472554bc6 100644 --- a/docs/cryptpad.service +++ b/docs/cryptpad.service @@ -10,6 +10,10 @@ Restart=always # Restart service after 10 seconds if node service crashes RestartSec=2 +# Proper logging to journald +StandardOutput=journal +StandardError=journal+console + User=cryptpad Group=cryptpad # modify to match your working directory From f82b68438f4fbf9f1ab788233011a0462aecf7e0 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 27 Nov 2023 12:56:24 +0100 Subject: [PATCH 067/283] added margin to 'clear filter' button in mobile view #1103 --- www/kanban/app-kanban.less | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/www/kanban/app-kanban.less b/www/kanban/app-kanban.less index 6a7032c21..539d45535 100644 --- a/www/kanban/app-kanban.less +++ b/www/kanban/app-kanban.less @@ -462,6 +462,10 @@ button.cp-kanban-filterTags-reset { cursor: pointer; white-space: normal !important; + @media (max-width: 505px) { + margin-bottom: 10px; + margin-right: 10px; + } .tools_unselectable(); i { margin-right: 5px; From 85977dda7f8975ea258329556364bf18d26bceb3 Mon Sep 17 00:00:00 2001 From: Mathilde <41020854+mthld@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:30:06 +0100 Subject: [PATCH 068/283] Create SECURITY.md --- SECURITY.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..133723221 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +Considering the amount of resources necessary to backport security or bug fixes to previous, unsupported CryptPad versions, it's not something we do. +However, we quickly release new minor versions in case of need. + +Please keep up with the latest release published here: https://github.com/cryptpad/cryptpad/releases + +Note that every GitHub release page has an RSS compatible feed that you can subscribe on to be informed of every new release. + +We do also communicate about this topic on: +- [Our blog](https://blog.cryptpad.org) +- [Our Matrix public space](https://matrix.to/#/#cryptpad:matrix.xwiki.com) +- [Our Mastodon account](https://fosstodon.org/@cryptpad) + +## Reporting a Vulnerability + +Vulnerabilities can be reported using the GitHub Security interface. You can also send us an email at security@cryptpad.org From 7157af4323c076f1f70b8db34266cc3a46d1d9b0 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 29 Nov 2023 15:04:32 +0100 Subject: [PATCH 069/283] layout improvements in question blocks; correction to date export bug fix --- www/form/inner.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 64a9a8784..a10754117 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -214,7 +214,7 @@ define([ var editOptions = function (v, isDefaultOpts, setCursorGetter, cb, tmp) { var evOnSave = Util.mkEvent(); - var add = h('button.btn.btn-secondary', [ + var add = h('button.btn', [ h('i.fa.fa-plus'), h('span', Messages.form_add_option) ]); @@ -328,11 +328,15 @@ define([ } var del = h('button.btn.btn-danger-outline', h('i.fa.fa-times')); + var formHandle; + if (v.type !== 'time') { + formHandle = h('span.cp-form-handle', [ + h('i.fa.fa-ellipsis-v'), + h('i.fa.fa-ellipsis-v'), + ]) + } var el = h('div.cp-form-edit-block-input', [ - h('span.cp-form-handle', [ - h('i.fa.fa-ellipsis-v'), - h('i.fa.fa-ellipsis-v'), - ]), + formHandle, input, del ]); @@ -2669,7 +2673,7 @@ define([ } else { return q + ' | ' + key; } - + }); cols.unshift(q); return cols; @@ -2680,16 +2684,12 @@ define([ return empty; } var str = ''; + var timeValues = {}; Object.keys(answer.values).sort().forEach(function (k, i) { if (i !== 0) { str += ';'; } if (opts.type === 'time') { - Object.defineProperty( - answer.values, - new Date(parseInt(k)).toISOString(), - Object.getOwnPropertyDescriptor(answer.values, k), - ); - delete answer.values[k]; - str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + answer.values[ new Date(parseInt(k)).toISOString()] ; + timeValues[new Date(parseInt(k)).toISOString()] = answer.values[k] + str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + timeValues[new Date(parseInt(k)).toISOString()] ; } else { str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; @@ -2697,13 +2697,14 @@ define([ }); var res = extractValues(opts.values).map(function (key) { if (opts.type === 'time') { - return answer.values[ new Date(parseInt(key)).toISOString()] || ''; + return timeValues[new Date(parseInt(key)).toISOString()] || ''; } else { return answer.values[key] || ''; } }); res.unshift(str); + return res; }, icon: h('i.cptools.cptools-form-poll') From f506e5a8cf310898d52cdd42bcb31bc23879e5e6 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 1 Dec 2023 15:44:20 +0100 Subject: [PATCH 070/283] Instance invitation and user management prototype --- customize.dist/login.js | 33 ++- customize.dist/pages/register.js | 17 +- .../src/less2/pages/page-register.less | 11 + lib/commands/admin-rpc.js | 40 +++ lib/commands/block.js | 33 ++- lib/commands/invitation.js | 82 ++++++ lib/commands/users.js | 53 ++++ lib/storage/invite.js | 78 ++++++ lib/storage/user.js | 75 ++++++ www/admin/inner.js | 251 ++++++++++++++++-- www/common/cryptpad-common.js | 2 + www/common/outer/login-block.js | 4 +- www/install/main.js | 36 +-- www/login/main.js | 14 +- www/register/main.js | 28 +- 15 files changed, 686 insertions(+), 71 deletions(-) create mode 100644 lib/commands/invitation.js create mode 100644 lib/commands/users.js create mode 100644 lib/storage/invite.js create mode 100644 lib/storage/user.js diff --git a/customize.dist/login.js b/customize.dist/login.js index df2d66316..b010d071b 100644 --- a/customize.dist/login.js +++ b/customize.dist/login.js @@ -140,7 +140,8 @@ define([ Exports.mergeAnonDrive = 1; }; - Exports.loginOrRegister = function (uname, passwd, isRegister, shouldImport, onOTP, cb) { + Exports.loginOrRegister = function (config, cb) { + let { uname, passwd, token, isRegister, shouldImport, onOTP } = config; if (typeof(cb) !== 'function') { return; } // Usernames are all lowercase. No going back on this one @@ -519,14 +520,20 @@ define([ toPublish[Constants.userHashKey] = userHash; toPublish.edPublic = RT.proxy.edPublic; + var userData; + if (token) { userData = [uname, RT.proxy.edPublic]; } + Block.writeLoginBlock({ blockKeys: blockKeys, + token: token, + userData, content: toPublish - }, waitFor(function (e) { + }, waitFor(function (e, errData) { if (e) { - console.error(e); + console.error(e, errData); waitFor.abort(); - return void cb(e); + + return void cb(errData ? (errData.errorCode || errData.error) : e); } })); }).nThen(function (waitFor) { @@ -565,14 +572,16 @@ define([ }; var hashing; - Exports.loginOrRegisterUI = function (uname, passwd, isRegister, shouldImport, onOTP, testing, test) { + + Messages.register_invalidToken = "Registration is closed and the invitation link is invalid"; // XXX + Exports.loginOrRegisterUI = function (config) { + let { uname, token, cb } = config; if (hashing) { return void console.log("hashing is already in progress"); } hashing = true; var proceed = function (result) { hashing = false; - // NOTE: test is also use as a cb for the install page - if (test && typeof test === "function" && test(result)) { return; } + if (cb && typeof cb === "function" && cb(result)) { return; } LocalStore.clearLoginToken(); Realtime.whenRealtimeSyncs(result.realtime, function () { Exports.redirect(); @@ -590,11 +599,12 @@ define([ // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed // after hashing the password window.setTimeout(function () { - Exports.loginOrRegister(uname, passwd, isRegister, shouldImport, onOTP, function (err, result) { - var proxy; + Exports.loginOrRegister(config, function (err, result) { + var proxy = {}; if (result) { proxy = result.proxy; } if (err) { + console.warn(err); switch (err) { case 'NO_SUCH_USER': UI.removeLoadingScreen(function () { @@ -664,6 +674,9 @@ define([ }); break; case 'E_RESTRICTED': + if (token) { + return UI.errorLoadingScreen(Messages.register_invalidToken); + } UI.errorLoadingScreen(Messages.register_registrationIsClosed); break; default: // UNHANDLED ERROR @@ -673,8 +686,6 @@ define([ return; } - //if (testing) { return void proceed(result); } - if (!(proxy.curvePrivate && proxy.curvePublic && proxy.edPrivate && proxy.edPublic)) { diff --git a/customize.dist/pages/register.js b/customize.dist/pages/register.js index a34aad460..bf97ef1af 100644 --- a/customize.dist/pages/register.js +++ b/customize.dist/pages/register.js @@ -29,20 +29,21 @@ define([ ]; }; - if (Config.restrictRegistration) { - return frame([ - h('div.cp-restricted-registration', [ - h('p', Msg.register_registrationIsClosed), - ]) - ]); - } - var termsCheck; if (termsLink) { termsCheck = h('div.checkbox-container', tos); } + var closed = Config.restrictRegistration; + if (closed) { + $('body').addClass('cp-register-closed'); + } + + return frame([ + h('div.cp-restricted-registration', [ + h('p', Msg.register_registrationIsClosed), + ]), h('div.row.cp-register-det', [ h('div#data.hidden.col-md-6', [ h('h2', Msg.register_notes_title), diff --git a/customize.dist/src/less2/pages/page-register.less b/customize.dist/src/less2/pages/page-register.less index a0e4a0b21..fce440b15 100644 --- a/customize.dist/src/less2/pages/page-register.less +++ b/customize.dist/src/less2/pages/page-register.less @@ -11,6 +11,17 @@ .alertify_main(); .checkmark_main(20px); + &:not(.cp-register-closed) { + .cp-restricted-registration { + display: none; + } + } + &.cp-register-closed { + div.cp-register-det { + display: none; + } + } + .cp-container { .form-group { .cp-register-instance { diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 512fd001b..c4aad4f1d 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -8,6 +8,8 @@ const Decrees = require("../decrees"); const Pinning = require("./pin-rpc"); const Core = require("./core"); const Channel = require("./channel"); +const Invitation = require("./invitation"); +const Users = require("./users"); const BlockStore = require("../storage/block"); const MFA = require("../storage/mfa"); const ArchiveAccount = require('../archive-account'); @@ -850,6 +852,37 @@ var getMetadataHistory = function (Env, Server, cb, data) { }); }; +var getKnownUsers = (Env, Server, cb) => { + Users.getAll(Env, cb); +}; +var addKnownUser = (Env, Server, cb, data, unsafeKey) => { + var obj = Array.isArray(data) && data[1]; + var edPublic = obj.edPublic; + var block = obj.block; + var alias = obj.alias; + var userData = { + edPublic, + block, + alias, + name, + type: 'manual' + }; + Users.add(Env, edPublic, userData, unsafeKey, cb); +}; +// XXX delete user, update user (add block, update storage limit, etc.) + +var getInvitations = (Env, Server, cb) => { + Invitation.getAll(Env, cb); +}; +var createInvitation = (Env, Server, cb, data, unsafeKey) => { + var alias = Array.isArray(data) && data[1]; + Invitation.create(Env, alias, cb, unsafeKey); +}; +var deleteInvitation = (Env, Server, cb, data) => { + var id = Array.isArray(data) && data[1]; + Invitation.delete(Env, id, cb); +}; + var commands = { ACTIVE_SESSIONS: getActiveSessions, ACTIVE_PADS: getActiveChannelCount, @@ -908,6 +941,13 @@ var commands = { GET_USER_TOTAL_SIZE: getUserTotalSize, REMOVE_DOCUMENT: removeDocument, + + GET_ALL_INVITATIONS: getInvitations, + CREATE_INVITATION: createInvitation, + DELETE_INVITATION: deleteInvitation, + + GET_ALL_USERS: getKnownUsers, + ADD_KNOWN_USER: addKnownUser, }; // addFirstAdmin is an anon_rpc command diff --git a/lib/commands/block.js b/lib/commands/block.js index ca4a77e1e..6a830729b 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -5,6 +5,8 @@ const Nacl = require("tweetnacl/nacl-fast"); const nThen = require("nthen"); const Util = require("../common-util"); const BlockStore = require("../storage/block"); +const Invitation = require("./invitation"); +const Users = require("./users"); var isString = s => typeof(s) === 'string'; Block.isValidBlockId = id => { @@ -105,13 +107,21 @@ Block.validateAncestorProof = function (Env, proof, _cb) { Block.writeLoginBlock = function (Env, msg, _cb) { var cb = Util.once(Util.mkAsync(_cb)); - const { publicKey, signature, ciphertext, registrationProof } = msg; + const { publicKey, signature, ciphertext, registrationProof, userData, inviteToken } = msg; var previousKey; var validatedBlock, path; + var validatedInvite; nThen(function (w) { if (!Env.restrictRegistration) { return; } - if (!registrationProof) { + if (!inviteToken) { return; } + Invitation.check(Env, inviteToken, w((err, state) => { + if (err || !state) { return; } // Invalid token, don't abort, check registration proof + validatedInvite = true; + })); + }).nThen(function (w) { + if (!Env.restrictRegistration) { return; } + if (!registrationProof && !validatedInvite) { // we allow users with existing blocks to create new ones // call back with error if registration is restricted and no proof of an existing block was provided w.abort(); @@ -122,6 +132,7 @@ Block.writeLoginBlock = function (Env, msg, _cb) { } Block.validateAncestorProof(Env, registrationProof, w(function (err, provenKey) { if (err || !provenKey) { // double check that a key was validated + if (validatedInvite) { return; } w.abort(); Env.Log.warn('BLOCK_REJECTED_INVALID_ANCESTOR', { error: err, @@ -158,6 +169,24 @@ Block.writeLoginBlock = function (Env, msg, _cb) { path: path, }); cb(err); + if (!err && registrationProof) { + Users.checkUpdate(Env, userData, publicKey, (err) => { + if (!err) { return; } + Env.Log.error('UPDATE_KNOWN_USER', { + userData, + publicKey + }); + }); + } + }); + if (!validatedInvite) { return; } + Invitation.use(Env, inviteToken, publicKey, userData, (err) => { + if (!err) { return; } + Env.Log.error('USE_INVITATION_LINK', { + inviteToken, + userData, + publicKey + }); }); }); }; diff --git a/lib/commands/invitation.js b/lib/commands/invitation.js new file mode 100644 index 000000000..e8c0437cf --- /dev/null +++ b/lib/commands/invitation.js @@ -0,0 +1,82 @@ +/*jshint esversion: 6 */ +const Invitation = module.exports; + +const Invite = require('../storage/invite'); +const Util = require("../common-util"); +const Users = require("./users"); + +const getUid = () => { + return Util.uid() + Util.uid() + Util.uid(); +}; + +Invitation.getAll = (Env, cb) => { + Invite.getAll(Env, (err, data) => { + if (err) { return void cb(err); } + cb(null, data); + }); +}; + +Invitation.create = (Env, alias, _cb, unsafeKey) => { + const cb = Util.once(Util.mkAsync(_cb)); + const id = getUid(); + const invitation = { + alias: alias, + createdBy: unsafeKey, + time: +new Date() + }; + Invite.write(Env, id, invitation, (err) => { + if (err) { return void cb(err); } + cb(null, id); + }); +}; + +Invitation.delete = (Env, id, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + Invite.delete(Env, id, (err) => { + if (err && err !== 'ENOENT') { return void cb(err); } + cb(void 0, true); + }); +}; + +Invitation.check = (Env, id, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + Invite.read(Env, id, (err) => { + if (err) { return void cb(err); } + cb(void 0, true); + }); +}; + +Invitation.use = (Env, id, blockId, userData, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + Invite.read(Env, id, (err, _data) => { + if (err) { return void cb(err); } + + let data = Util.clone(_data); + if (!Array.isArray(userData)) { userData = []; } + let name = userData[0]; + let edPublic = userData[1]; + data.block = blockId; + data.name = name; + data.edPublic = edPublic; + data.type = 'invite:' + id; + let adminKey = data.createdBy; + Users.add(Env, edPublic, data, adminKey, (err) => { + if (err) { + Env.Log.error('INVITATION_ADD_USER', { + error: err, + data: data + }); + } + }); + + Invite.delete(Env, id, (err) => { + if (err) { + Env.Log.error('INVITATION_DELETE_USE', { + error: err, + id: id + }); + } + }); + }); +}; + diff --git a/lib/commands/users.js b/lib/commands/users.js new file mode 100644 index 000000000..3fc161190 --- /dev/null +++ b/lib/commands/users.js @@ -0,0 +1,53 @@ +/*jshint esversion: 6 */ +const Users = module.exports; + +const User = require('../storage/user'); +const Util = require("../common-util"); + +Users.getAll = (Env, cb) => { + User.getAll(Env, (err, data) => { + if (err) { return void cb(err); } + cb(null, data); + }); +}; + +Users.add = (Env, edPublic, data, adminKey, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + data.createdBy = adminKey; + data.time = +new Date(); + const safeKey = Util.escapeKeyCharacters(edPublic); + User.write(Env, safeKey, data, (err) => { + if (err) { return void cb(err); } + cb(); + }); +}; + +Users.delete = (Env, id, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + User.delete(Env, id, (err) => { + if (err && err !== 'ENOENT') { return void cb(err); } + cb(void 0, true); + }); +}; + +Users.read = (Env, edPublic, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + User.read(Env, edPublic, (err, data) => { + if (err) { return void cb(err); } + cb(void 0, data); + }); +}; + +// On password change, update the block +Users.checkUpdate = (Env, userData, newBlock, cb) => { + if (!Array.isArray(userData)) { userData = []; } + let edPublic = userData[1]; + if (!edPublic) { return void cb('INVALID_PUBLIC_KEY'); } + Users.read(Env, edPublic, (err, data) => { + if (err === 'ENOENT') { return void cb(); } + if (err) { return void cb(err); } + // User exists, update their block + data.block = newBlock; + User.update(Env, edPublic, data, cb); + }); +}; diff --git a/lib/storage/invite.js b/lib/storage/invite.js new file mode 100644 index 000000000..032cf6341 --- /dev/null +++ b/lib/storage/invite.js @@ -0,0 +1,78 @@ +const Basic = require("./basic.js"); +const Path = require("node:path"); +const nThen = require('nthen'); +const Util = require('../common-util'); + +const Invite = module.exports; +/* This module manages storage used to implement instance invitations when registration + is closed. This "database" will store individual invitation and their state. + + An invitation is created with a random uid and an alias (username, email, etc.) + Once it is used by the user, their newly created blockId is added which will mark + it as completed. +*/ + +const pathFromId = function (Env, id) { + if (!id || typeof(id) !== 'string') { return void console.error('INVITE_BAD_ID', id); } + return Path.join(Env.paths.base, "invitations", id.slice(0, 2), id); +}; + +Invite.read = function (Env, id, cb) { + var path = pathFromId(Env, id); + Basic.read(Env, path, (err, data) => { + if (err) { return void cb(err.code); } + cb(void 0, Util.tryParse(data)); + }); +}; + +Invite.getAll = function (Env, cb) { + let invitations = {}; + + + nThen((waitFor) => { + let dirPath = Path.join(Env.paths.base, "invitations"); + Basic.readDir(Env, dirPath, waitFor((err, prefixes) => { + if (err && err.code === 'ENOENT') { return void cb(void 0, {}); } + if (err) { waitFor.abort(); return void cb(err.code); } + prefixes.forEach((prefix) => { + var dirPath2 = Path.join(Env.paths.base, "invitations", prefix); + Basic.readDir(Env, dirPath2, waitFor((err, files) => { + if (err) { waitFor.abort(); return void cb(err.code); } + files.forEach((id) => { + Invite.read(Env, id, waitFor((err, data) => { + invitations[id] = data || { error: err }; + })); + }); + })); + }); + })); + }).nThen(() => { + cb(null, invitations); + }); + +}; + +Invite.write = function (Env, id, data, cb) { + var path = pathFromId(Env, id); + Basic.write(Env, path, JSON.stringify(data), (err) => { + if (err) { return void cb(err.code); } + cb(); + }); +}; + +Invite.delete = function (Env, id, cb) { + var path = pathFromId(Env, id); + Basic.delete(Env, path, (err) => { + if (err) { return void cb(err.code); } + cb(); + }); +}; + +Invite.update = function (Env, id, data, cb) { + Invite.delete(Env, id, (err) => { + if (err) { return void cb(err); } + Invite.write(Env, id, data, cb); + }); +}; + + diff --git a/lib/storage/user.js b/lib/storage/user.js new file mode 100644 index 000000000..b0d25ba74 --- /dev/null +++ b/lib/storage/user.js @@ -0,0 +1,75 @@ +const Basic = require("./basic.js"); +const Path = require("node:path"); +const nThen = require('nthen'); +const Util = require('../common-util'); + +const User = module.exports; +/* This module manages storage used to implement user management. "Known users" can + be added here in order to store their public key, their block ID and an alias + used to recognize them. +*/ + +const pathFromId = function (Env, id) { + if (!id || typeof(id) !== 'string') { return void console.error('KNWONUSER_BAD_ID', id); } + return Path.join(Env.paths.base, "users", id.slice(0, 2), id); +}; + +User.read = function (Env, id, cb) { + var path = pathFromId(Env, id); + Basic.read(Env, path, (err, data) => { + if (err) { return void cb(err.code); } + cb(void 0, Util.tryParse(data)); + }); +}; + +User.getAll = function (Env, cb) { + let users = {}; + + + nThen((waitFor) => { + let dirPath = Path.join(Env.paths.base, "users"); + Basic.readDir(Env, dirPath, waitFor((err, prefixes) => { + if (err && err.code === 'ENOENT') { return void cb(void 0, {}); } + if (err) { waitFor.abort(); return void cb(err.code); } + prefixes.forEach((prefix) => { + var dirPath2 = Path.join(Env.paths.base, "users", prefix); + Basic.readDir(Env, dirPath2, waitFor((err, files) => { + if (err) { waitFor.abort(); return void cb(err.code); } + files.forEach((id) => { + User.read(Env, id, waitFor((err, data) => { + users[id] = data || { error: err }; + })); + }); + })); + }); + })); + }).nThen(() => { + cb(null, users); + }); + +}; + +User.write = function (Env, id, data, cb) { + var path = pathFromId(Env, id); + Basic.write(Env, path, JSON.stringify(data), (err) => { + if (err) { return void cb(err.code); } + cb(); + }); +}; + +User.delete = function (Env, id, cb) { + var path = pathFromId(Env, id); + Basic.delete(Env, path, (err) => { + if (err) { return void cb(err.code); } + cb(); + }); +}; + +User.update = function (Env, id, data, cb) { + User.delete(Env, id, (err) => { + if (err) { return void cb(err); } + User.write(Env, id, data, cb); + }); +}; + + diff --git a/www/admin/inner.js b/www/admin/inner.js index 4d5ae11b7..a38354eab 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -57,7 +57,6 @@ define([ 'general': [ // Msg.admin_cat_general 'cp-admin-flush-cache', 'cp-admin-update-limit', - 'cp-admin-registration', 'cp-admin-enableembeds', 'cp-admin-email', @@ -68,6 +67,11 @@ define([ 'cp-admin-jurisdiction', 'cp-admin-notice', ], + 'users': [ // Msg.admin_cat_quota + 'cp-admin-registration', + 'cp-admin-invitation', + 'cp-admin-users', + ], 'quota': [ // Msg.admin_cat_quota 'cp-admin-defaultlimit', 'cp-admin-setlimit', @@ -1202,6 +1206,25 @@ define([ return tableObj.table; }; + var getBlockId = (val) => { + var url; + try { + url = new URL(val, ApiConfig.httpUnsafeOrigin); + } catch (err) { } + var getKey = function () { + var parts = val.split('/'); + return parts[parts.length - 1]; + }; + var isValidBlockURL = function (url) { + if (!url) { return; } + return /* url.origin === ApiConfig.httpUnsafeOrigin && */ /^\/block\/.*/.test(url.pathname) && getKey().length === 44; + }; + if (isValidBlockURL(url)) { + return getKey(); + } + return; + }; + create['block-metadata'] = function () { var key = 'block-metadata'; var $div = makeBlock(key, true); // Msg.admin_blockMetadataHint.admin_blockMetadataTitle @@ -1234,21 +1257,10 @@ define([ key: '', }; - var url; - try { - url = new URL(val, ApiConfig.httpUnsafeOrigin); - } catch (err) { } - var getKey = function () { - var parts = val.split('/'); - return parts[parts.length - 1]; - }; - var isValidBlockURL = function (url) { - if (!url) { return; } - return /* url.origin === ApiConfig.httpUnsafeOrigin && */ /^\/block\/.*/.test(url.pathname) && getKey().length === 44; - }; - if (isValidBlockURL(url)) { + var key = getBlockId(val); + if (key) { state.valid = true; - state.key = getKey(); + state.key = key; } return state; }; @@ -1503,6 +1515,215 @@ Example }, }); + Messages.admin_invitationCreate = "Create invitation link"; // XXX + create['invitation'] = function () { + var key = 'invitation'; + var $div = makeBlock(key); // Msg.admin_invitationHint, admin_invitationTitle + + var list = h('table'); + var input = h('input', { placeholder: 'ALIAS' }); // XXX + var button = h('button.btn.btn-primary', Messages.admin_invitationCreate); + var add = h('div', [input, button]); + + var $b = $(button); + + var metadataMgr = common.getMetadataMgr(); + var privateData = metadataMgr.getPrivateData(); + + var refreshInvite = function () {}; + + var deleteInvite = function (id) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'DELETE_INVITATION', + data: id + }, function (e, response) { + $b.prop('disabled', false); + if (e || response.error) { + UI.warn(Messages.error); + return void console.error(e, response); + } + refreshInvite(); + }); + }; + var $list = $(list); + refreshInvite = function () { + $list.empty(); + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'GET_ALL_INVITATIONS', + }, function (e, response) { + if (e || response.error) { + if (!response || response.error !== "ENOENT") { UI.warn(Messages.error); } + console.error(e, response); + return; + } + if (!Array.isArray(response)) { return; } + var all = response[0]; + Object.keys(all).forEach(function (key) { + var data = all[key]; + var url = privateData.origin + Hash.hashToHref(key, 'register'); + + var del = h('button.btn.btn-danger.fa.fa-trash'); + $(del).click(function () { + // XXX CONFIRM + deleteInvite(key); + }); + var copy = h('button.btn.btn-secondary.fa.fa-clipboard'); + $(copy).click(function () { + var success = Clipboard.copy(url, () => { + UI.log(Messages.genericCopySuccess); + }); + if (success) { UI.log(Messages.genericCopySuccess); } // XXX merge staging delete this line + }); + var line = h('tr', [ + h('td', UI.dialog.selectable(url)), + h('td', data.alias), + h('td', new Date(data.time).toLocaleString()), + //h('td', data.createdBy), + copy, + del + ]); + $list.append(line); + }); + }); + }; + refreshInvite(); + + $b.on('click', () => { + $b.prop('disabled', true); + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'CREATE_INVITATION', + data: $(input).val() + }, function (e, response) { + $b.prop('disabled', false); + if (e || response.error) { + UI.warn(Messages.error); + return void console.error(e, response); + } + $(input).val('').focus(); + refreshInvite(); + }); + }); + + $div.append([add, list]); + return $div; + }; + + Messages.admin_usersAdd = "Add known user"; + create['users'] = function () { + var key = 'users'; + var $div = makeBlock(key); // Msg.admin_usersHint, admin_usersTitle + + var list = h('table'); + var userAlias = h('input', { placeholder: 'ALIAS' }); // XXX + var userEdPublic = h('input', { placeholder: 'USER PUBLIC KEY' }); // XXX + var userBlock = h('input', { placeholder: 'USER BLOCK (optional)' }); // XXX + var button = h('button.btn.btn-primary', Messages.admin_usersAdd); + var add = h('div', [userAlias, userEdPublic, userBlock, button]); + + var $b = $(button); + + var refreshUsers = function () {}; + + var deleteUser = function (/*id*/) { + /* + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'DELETE_KNOWN_USER', + data: id + }, function (e, response) { + $b.prop('disabled', false); + if (e || response.error) { + UI.warn(Messages.error); + return void console.error(e, response); + } + refreshUsers(); + });*/ + }; + var $list = $(list); + refreshUsers = function () { + $list.empty(); + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'GET_ALL_USERS', + }, function (e, response) { + if (e || response.error) { + if (!response || response.error !== "ENOENT") { UI.warn(Messages.error); } + console.error(e, response); + return; + } + if (!Array.isArray(response)) { return; } + var all = response[0]; + console.log(all); + Object.keys(all).forEach(function (key) { + var data = all[key]; + + var del = h('button.btn.btn-danger.fa.fa-trash'); + $(del).click(function () { + // XXX CONFIRM + deleteUser(key); + }); + var copy = h('button.btn.btn-secondary.fa.fa-clipboard'); + $(copy).click(function () { + var success = Clipboard.copy(key, () => { + UI.log(Messages.genericCopySuccess); + }); + if (success) { UI.log(Messages.genericCopySuccess); } // XXX merge staging delete this line + }); + var line = h('tr', [ + h('td', data.alias), + h('td', h('pre', key)), + h('td', new Date(data.time).toLocaleString()), + //h('td', data.createdBy), + copy, + del + ]); + $list.append(line); + }); + }); + }; + refreshUsers(); + + $b.on('click', () => { + $b.prop('disabled', true); + // XXX CHECK ALL VALUES ARE AVAILABLE + // XXX PARSE FULL KEY INTO EDPUBLIC + // XXX PARSE BLOCK HASH INTO BLOCK KEY + // XXX GET BLOCK FROM PIN LOG? + + var done = () => { $b.prop('disabled', false); }; + + var keyStr = $(userEdPublic).val().trim(); + var parsed = keyStr && Keys.parseUser(keyStr); + if (!parsed || !parsed.edPublic) { + done(); + return void UI.warn(Messages.admin_invalKey); + } + var block = getBlockId($(userBlock).val()); + + var obj = { + alias: $(userAlias).val(), + block: block, + edPublic: parsed.edPublic, + name: parsed.user + }; + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'ADD_KNOWN_USER', + data: obj + }, function (e, response) { + done(); + if (e || response.error) { + UI.warn(Messages.error); + return void console.error(e, response); + } + $(userAlias).val('').focus(); + $(userBlock).val(''); + $(userEdPublic).val(''); + refreshUsers(); + }); + }); + + $div.append([add, list]); + return $div; + }; + // Msg.admin_enableembedsHint, .admin_enableembedsTitle create['enableembeds'] = makeAdminCheckbox({ key: 'enableembeds', diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 3ab33e5b8..11cff693a 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -2042,8 +2042,10 @@ define([ User_hash: newHash, edPublic: edPublic, }; + var userData = [undefined, edPublic]; Block.writeLoginBlock({ auth: auth, + userData: userData, blockKeys: blockKeys, oldBlockKeys: oldBlockKeys, content: content diff --git a/www/common/outer/login-block.js b/www/common/outer/login-block.js index 39dea3884..5712bb2db 100644 --- a/www/common/outer/login-block.js +++ b/www/common/outer/login-block.js @@ -175,7 +175,7 @@ define([ }, cb); }; Block.writeLoginBlock = function (data, cb) { - const { content, blockKeys, oldBlockKeys, auth } = data; + const { content, blockKeys, oldBlockKeys, token, userData, auth } = data; var command = 'WRITE_BLOCK'; if (auth && auth.type === 'TOTP') { @@ -185,6 +185,8 @@ define([ var block = Block.serialize(JSON.stringify(content), blockKeys); block.auth = auth && auth.data; block.registrationProof = oldBlockKeys && Block.proveAncestor(oldBlockKeys); + if (token) { block.inviteToken = token; } + if (userData) { block.userData = userData; } ServerCommand(blockKeys.sign, { command: command, diff --git a/www/install/main.js b/www/install/main.js index 88635588a..5d8aee13e 100644 --- a/www/install/main.js +++ b/www/install/main.js @@ -126,24 +126,30 @@ define([ function (yes) { if (!yes) { return; } - Login.loginOrRegisterUI(uname, passwd, true, shouldImport, false, function (data) { - var proxy = data.proxy; - if (!proxy || !proxy.edPublic) { UI.alert(Messages.error); return true; } + Login.loginOrRegisterUI({ + uname, + passwd, + isRegister: true, + shouldImport, + cb: function (data) { + var proxy = data.proxy; + if (!proxy || !proxy.edPublic) { UI.alert(Messages.error); return true; } - Rpc.createAnonymous(data.network, function (e, call) { - if (e) { UI.alert(Messages.error); return console.error(e); } - var anon_rpc = call; - - anon_rpc.send('ADD_FIRST_ADMIN', { - token: token, - edPublic: proxy.edPublic - }, function (e) { + Rpc.createAnonymous(data.network, function (e, call) { if (e) { UI.alert(Messages.error); return console.error(e); } - window.location.href = '/drive/'; - }); - }); + var anon_rpc = call; - return true; + anon_rpc.send('ADD_FIRST_ADMIN', { + token: token, + edPublic: proxy.edPublic + }, function (e) { + if (e) { UI.alert(Messages.error); return console.error(e); } + window.location.href = '/drive/'; + }); + }); + + return true; + } }); registering = true; }, { diff --git a/www/login/main.js b/www/login/main.js index fe3f9fbf4..083f39972 100644 --- a/www/login/main.js +++ b/www/login/main.js @@ -49,15 +49,11 @@ define([ var shouldImport = $checkImport[0].checked; var uname = $uname.val(); var passwd = $passwd.val(); - Login.loginOrRegisterUI(uname, passwd, false, shouldImport, - UI.getOTPScreen, /*Test.testing */ false, function () { - /* - if (test) { - localStorage.clear(); - //test.pass(); - return true; - } - */ + Login.loginOrRegisterUI({ + uname, + passwd, + shouldImport, + onOTP: UI.getOTPScreen }); }); $('#register').on('click', function () { diff --git a/www/register/main.js b/www/register/main.js index 9420ff8ad..097e2ab01 100644 --- a/www/register/main.js +++ b/www/register/main.js @@ -1,8 +1,8 @@ define([ + '/api/config', 'jquery', '/customize/login.js', '/common/cryptpad-common.js', - //'/common/test.js', '/common/common-credential.js', '/common/common-interface.js', '/common/common-util.js', @@ -14,7 +14,7 @@ define([ '/customize/pages.js', 'css!/components/components-font-awesome/css/font-awesome.min.css', -], function ($, Login, Cryptpad, /*Test,*/ Cred, UI, Util, Realtime, Constants, Feedback, LocalStore, h, Pages) { +], function (Config, $, Login, Cryptpad, Cred, UI, Util, Realtime, Constants, Feedback, LocalStore, h, Pages) { if (window.top !== window) { return; } var Messages = Cryptpad.Messages; $(function () { @@ -24,6 +24,14 @@ define([ return; } + // If the token is provided in the URL, hide the field + var token; + if (window.location.hash) { + var hash = window.location.hash.slice(1); + token = hash; + $('body').removeClass('cp-register-closed'); + } + // text and password input fields var $uname = $('#username'); var $passwd = $('#password'); @@ -44,7 +52,6 @@ define([ var $register = $('button#register'); var registering = false; - var test; var I_REALLY_WANT_TO_USE_MY_EMAIL_FOR_MY_USERNAME = false; var br = function () { return h('br'); }; @@ -69,7 +76,7 @@ define([ try { // if this throws there's either a horrible bug (which someone will report) // or the instance admins did not configure a terms page. - doesAccept = $checkAcceptTerms[0].checked; + doesAccept = $checkAcceptTerms.length && $checkAcceptTerms[0].checked; } catch (err) { console.error(err); } @@ -126,12 +133,13 @@ define([ function (yes) { if (!yes) { return; } - Login.loginOrRegisterUI(uname, passwd, true, shouldImport, false /*Test.testing*/, function () { - if (test) { - localStorage.clear(); - test.pass(); - return true; - } + Login.loginOrRegisterUI({ + uname, + passwd, + token, + isRegister: true, + shouldImport, + onOTP: false, }); registering = true; }, { From 65a4fbd22a5735ffb7f7639c81a3dbc8bf6968e1 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Sun, 3 Dec 2023 17:16:15 +0100 Subject: [PATCH 071/283] don't show hidden pages in conditional sections and update page count #1076 --- www/form/inner.js | 76 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index a10754117..b56ba5416 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4278,6 +4278,7 @@ define([ if (APP.isEditor) { elements.push(getFormCreator()); } + var _content = elements; if (!editable) { _content = []; @@ -4306,19 +4307,79 @@ define([ _content.push(pageContainer); var refreshPage = APP.refreshPage = function (current) { $page.empty(); + var hiddenPages; + + var checkEmptyPages = function() { + var shownContent = []; + hiddenPages = 0; + _content.forEach(function(div) { + var hiddenQs = 0; + for (child of div.children) { + if ($(child).attr('data-title') == 'hidden') { + hiddenQs++; + } + } + if (hiddenQs == div.children.length && $(div).attr('class') !== 'cp-form-page-container') { + div['empty'] = true; + hiddenPages ++; + } + else { + div['empty'] = false; + if ($(div).attr('class') !== 'cp-form-page-container' && shownContent.indexOf(div) == -1) { + shownContent.push(div) + } + } + }) + return shownContent; + } + var shownContent = checkEmptyPages() + var shownPages = checkEmptyPages().length + if (!current || current < 1) { current = 1; } - if (current > pages) { current = pages; } + + checkEmptyPages(); + + var state = h('span', Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])); + evOnChange.reg(function(){ + checkEmptyPages(); + shownContent = checkEmptyPages() + shownPages = checkEmptyPages().length + $(state).html(Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])) + + }) var left = h('button.btn.btn-secondary.cp-prev', [ h('i.fa.fa-arrow-left'), ]); - var state = h('span', Messages._getKey('form_page', [current, pages])); var right = h('button.btn.btn-secondary.cp-next', [ h('i.fa.fa-arrow-right'), ]); if (current === pages) { $(right).css('visibility', 'hidden'); } if (current === 1) { $(left).css('visibility', 'hidden'); } - $(left).click(function () { refreshPage(current - 1); }); - $(right).click(function () { refreshPage(current + 1); }); + + $(left).click(function () { + checkEmptyPages(); + var prevPage = -1; + if (_content[current+prevPage-1]['empty']) { + prevPage--; + while (_content[current+prevPage-1]['empty']) { + prevPage --; + } + } + checkEmptyPages(); + $(state).html(Messages._getKey('form_page', [current, pages-hiddenPages])) + refreshPage(current + prevPage); + }); + $(right).click(function () { + checkEmptyPages(); + var nextPage = 1; + if (_content[current]['empty']) { + nextPage++; + while (_content[(current+nextPage)-1]['empty']) { + nextPage ++; + } + } + refreshPage(current + nextPage); + }); $page.append([left, state, right]); $container.find('.cp-form-page').hide(); $($container.find('.cp-form-page').get(current-1)).show(); @@ -4468,10 +4529,15 @@ define([ var show = checkCondition(block); block.opts.questions.forEach(function (_uid) { $container.find('.cp-form-block[data-id="'+_uid+'"]').toggle(show); + if (!show) { + $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'hidden') + } else { + $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'visible') + } }); }); }); - + // If the form is already submitted, show an info message var lastTime = (answers && answers._time) || APP.editingTime; if (APP.hasAnswered && lastTime) { From 7712dc7b4e5aa97ca8366c8ce16f8c2c9363dced Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 4 Dec 2023 11:41:04 +0100 Subject: [PATCH 072/283] linting + restricting question draggability on mobile #1080 + added margins on form submission page #1322 --- www/form/app-form.less | 1 + www/form/inner.js | 85 +++++++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 433d02ca3..fa0b33f5f 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -823,6 +823,7 @@ padding-bottom: 20px; } .cp-form-submit-success { + margin: 20px; div.cp-form-submit-success-actions { button:not(:last-child) { margin-right: 10px; diff --git a/www/form/inner.js b/www/form/inner.js index b56ba5416..6a8b34be4 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -75,7 +75,7 @@ define([ Sortable ) { - Messages.form_copyQuestion = 'Duplicate' //XXX + Messages.form_copyQuestion = 'Duplicate'; //XXX var APP = window.APP = { blocks: {} @@ -333,7 +333,7 @@ define([ formHandle = h('span.cp-form-handle', [ h('i.fa.fa-ellipsis-v'), h('i.fa.fa-ellipsis-v'), - ]) + ]); } var el = h('div.cp-form-edit-block-input', [ formHandle, @@ -437,7 +437,7 @@ define([ // Calendar inline for "day" type var calendarInput = h('input'); calendarView = h('div', calendarInput); - var calendarDefault = new Date() + var calendarDefault = new Date(); Flatpickr(calendarInput, { mode: 'multiple', inline: true, @@ -516,20 +516,20 @@ define([ setTimeout(evOnSave.fire); if (val !== "text") { $container.find('.cp-form-edit-block-input').remove(); - + var time, el; if (val === "time") { - var time = new Date(); + time = new Date(); time.setHours(14); time.setMinutes(0); time.setSeconds(0); time.setMilliseconds(0); - var el = getOption(+time, false, false, Util.uid()); + el = getOption(+time, false, false, Util.uid()); $add.before(el); $(el).find('input').focus(); return; } else if (val === "day") { - var time = new Date(); - var el = getOption(+time, false, false, Util.uid()); + time = new Date(); + el = getOption(+time, false, false, Util.uid()); $add.before(el); $(el).find('input').focus(); return; @@ -538,9 +538,9 @@ define([ return; } - if (parseInt($container.find('input')[0].value) !== NaN && parseInt($container.find('input')[0].value).toString().length > 4) { - var dateInput = new Date(parseInt($container.find('input')[0].value)) - $container.find('input')[0].value = dateInput.toDateString() + if (!isNaN(parseInt($container.find('input')[0].value))&& parseInt($container.find('input')[0].value).toString().length > 4) { + var dateInput = new Date(parseInt($container.find('input')[0].value)); + $container.find('input')[0].value = dateInput.toDateString(); } $container.find('input').each(function (i, input) { if (input._flatpickr) { @@ -2688,8 +2688,8 @@ define([ Object.keys(answer.values).sort().forEach(function (k, i) { if (i !== 0) { str += ';'; } if (opts.type === 'time') { - timeValues[new Date(parseInt(k)).toISOString()] = answer.values[k] - str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + timeValues[new Date(parseInt(k)).toISOString()] ; + timeValues[new Date(parseInt(k)).toISOString()] = answer.values[k]; + str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + timeValues[new Date(parseInt(k)).toISOString()]; } else { str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; @@ -4107,26 +4107,27 @@ define([ var full = !uid; var arr = content.order; var idx = content.order.indexOf(uid); + var _uid; if (!full) { var obj = getSectionFromQ(content, uid); arr = obj.arr; idx = obj.idx; - var _uid = Util.uid(); + _uid = Util.uid(); } var model = TYPES[type] || STATIC_TYPES[type]; if (!model) { return; } var question; if (content.form[uid].q) { - question = content.form[uid].q + question = content.form[uid].q; } else { - question = Messages.form_default + question = Messages.form_default; } var options; if (content.form[uid].opts) { - options = content.form[uid].opts + options = content.form[uid].opts; } else { - options = Util.clone(model.defaultOpts) + options = Util.clone(model.defaultOpts); } content.form[_uid] = { q: question, @@ -4140,13 +4141,13 @@ define([ } framework.localChange(); updateForm(framework, content, true); - }) + }); - copydelContainer = h('div', [copy, del]) + var copydelContainer = h('div', [copy, del]); editButtons = h('div.cp-form-edit-buttons-container', [ edit, copydelContainer]); editContainer = h('div'); if (type === 'poll' && block.opts.values.length === 0) { - $(editButtons).addClass('cp-empty-poll-edit-buttons') + $(editButtons).addClass('cp-empty-poll-edit-buttons'); } var onSave = function (newOpts, close) { if (close) { // Cancel edit @@ -4185,7 +4186,7 @@ define([ $(editContainer).find('.cp-form-preview-button').prependTo(editButtons); $(edit).hide(); - $(copy).hide() + $(copy).hide(); }; $(edit).click(function () { onEdit(); @@ -4314,26 +4315,26 @@ define([ hiddenPages = 0; _content.forEach(function(div) { var hiddenQs = 0; - for (child of div.children) { - if ($(child).attr('data-title') == 'hidden') { + for (var child of div.children) { + if ($(child).attr('data-title') === 'hidden') { hiddenQs++; } } - if (hiddenQs == div.children.length && $(div).attr('class') !== 'cp-form-page-container') { + if (hiddenQs === div.children.length && $(div).attr('class') !== 'cp-form-page-container') { div['empty'] = true; hiddenPages ++; } else { div['empty'] = false; - if ($(div).attr('class') !== 'cp-form-page-container' && shownContent.indexOf(div) == -1) { - shownContent.push(div) + if ($(div).attr('class') !== 'cp-form-page-container' && shownContent.indexOf(div) === -1) { + shownContent.push(div); } } - }) + }); return shownContent; - } - var shownContent = checkEmptyPages() - var shownPages = checkEmptyPages().length + }; + var shownContent = checkEmptyPages(); + var shownPages = checkEmptyPages().length; if (!current || current < 1) { current = 1; } @@ -4342,11 +4343,10 @@ define([ var state = h('span', Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])); evOnChange.reg(function(){ checkEmptyPages(); - shownContent = checkEmptyPages() - shownPages = checkEmptyPages().length - $(state).html(Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])) - - }) + shownContent = checkEmptyPages(); + shownPages = checkEmptyPages().length; + $(state).html(Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])); + }); var left = h('button.btn.btn-secondary.cp-prev', [ h('i.fa.fa-arrow-left'), ]); @@ -4366,7 +4366,7 @@ define([ } } checkEmptyPages(); - $(state).html(Messages._getKey('form_page', [current, pages-hiddenPages])) + $(state).html(Messages._getKey('form_page', [current, pages-hiddenPages])); refreshPage(current + prevPage); }); $(right).click(function () { @@ -4495,7 +4495,14 @@ define([ if (editable) { if (APP.mainSortable) { APP.mainSortable.destroy(); } + var grabHandle; + if (window.matchMedia("(pointer: coarse)").matches) { + grabHandle = '.cp-form-block-drag-handle'; + } else { + grabHandle = null; + } APP.mainSortable = Sortable.create($container[0], { + handle: grabHandle, group: 'nested', direction: "vertical", filter: "input, button, .CodeMirror, .cp-form-type-sort, .cp-form-block-type.editable", @@ -4530,9 +4537,9 @@ define([ block.opts.questions.forEach(function (_uid) { $container.find('.cp-form-block[data-id="'+_uid+'"]').toggle(show); if (!show) { - $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'hidden') + $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'hidden'); } else { - $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'visible') + $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'visible'); } }); }); From 89d0481484d750fef48d657b26268cdd9ca8fff6 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 4 Dec 2023 11:59:50 +0100 Subject: [PATCH 073/283] removed blank lines --- www/form/app-form.less | 4 ---- www/form/inner.js | 22 ++++++---------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index fa0b33f5f..2c2941dda 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -131,9 +131,6 @@ margin-right: 5px; } - - - &.cp-form-readonly { .cp-form-creator-inline-add { display: none; @@ -144,7 +141,6 @@ .cp-form-edit-buttons-container button { display: none; } - .cp-form-edit-save { display: none; } diff --git a/www/form/inner.js b/www/form/inner.js index 6a8b34be4..ae5039302 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -260,9 +260,7 @@ define([ }, content: Messages['form_poll_'+t] }; - - }); - + }); var dropdownConfig = { text: '', // Button initial text options: options, // Entries displayed in the menu @@ -298,7 +296,6 @@ define([ if (uid) { $input.data('uid', uid); } // If the input is a date, initialize flatpickr - if (v.type === 'time') { Flatpickr(input, { disableMobile: true, @@ -498,8 +495,7 @@ define([ } else { $(addMultiple).hide(); } - } - else { + } else { $(addMultiple).hide(); $calendar.show(); $container.hide(); @@ -508,7 +504,6 @@ define([ refreshView(); // Doodle type change: empty current values and change input types? - if (typeSelect) { typeSelect.onChange.reg(function (prettyVal, val) { v.type = val; @@ -2545,7 +2540,6 @@ define([ poll: { defaultOpts: { type: 'text', // Text or Days or Time - values: [1, 2, 3].map(function (i) { return { uid: Util.uid(), @@ -2633,7 +2627,6 @@ define([ }, edit: function (cb, tmp) { var v = Util.clone(opts); - return editOptions(v, isDefaultOpts, setCursorGetter, cb, tmp); }, getCursor: function () { return cursorGetter(); }, @@ -2673,7 +2666,6 @@ define([ } else { return q + ' | ' + key; } - }); cols.unshift(q); return cols; @@ -2690,8 +2682,7 @@ define([ if (opts.type === 'time') { timeValues[new Date(parseInt(k)).toISOString()] = answer.values[k]; str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + timeValues[new Date(parseInt(k)).toISOString()]; - } - else { + } else { str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; } }); @@ -2701,10 +2692,8 @@ define([ } else { return answer.values[key] || ''; } - }); res.unshift(str); - return res; }, icon: h('i.cptools.cptools-form-poll') @@ -4027,6 +4016,7 @@ define([ value: block.q || Messages.form_default }); var $inputQ = $(inputQ); + var saving = false; var cancel = false; var onSaveQ = function (e) { @@ -4084,6 +4074,7 @@ define([ framework.localChange(); updateAddInline(); }); + editButtons = h('div.cp-form-edit-buttons-container', [ fakeEdit, del ]); changeType = h('div.cp-form-block-type', [ @@ -4093,7 +4084,6 @@ define([ // Values if (data.edit) { - var edit = h('button.btn.btn-default.cp-form-edit-button', [ h('i.fa.fa-pencil'), h('span', Messages.form_editBlock) @@ -4544,7 +4534,7 @@ define([ }); }); }); - + // If the form is already submitted, show an info message var lastTime = (answers && answers._time) || APP.editingTime; if (APP.hasAnswered && lastTime) { From de06952ca1c0fe78c638f48154e0d356826b07d9 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 4 Dec 2023 12:14:08 +0100 Subject: [PATCH 074/283] more cleaning --- www/form/app-form.less | 7 +++---- www/form/inner.js | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/www/form/app-form.less b/www/form/app-form.less index 2c2941dda..2d8d7bc8a 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -127,10 +127,6 @@ } } - .cp-form-copy-button { - margin-right: 5px; - } - &.cp-form-readonly { .cp-form-creator-inline-add { display: none; @@ -646,6 +642,9 @@ display: flex; justify-content: space-between; } + .cp-form-copy-button { + margin-right: 5px; + } .cp-empty-poll-edit-buttons { padding-top: 40px } diff --git a/www/form/inner.js b/www/form/inner.js index ae5039302..1261699ef 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4355,8 +4355,6 @@ define([ prevPage --; } } - checkEmptyPages(); - $(state).html(Messages._getKey('form_page', [current, pages-hiddenPages])); refreshPage(current + prevPage); }); $(right).click(function () { From 0cf4237423de3528e199edd8f5918f7cf1fe6d68 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 4 Dec 2023 23:12:21 +0100 Subject: [PATCH 075/283] see less/more tag button on mobile --- www/kanban/app-kanban.less | 8 +++++++- www/kanban/inner.js | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/www/kanban/app-kanban.less b/www/kanban/app-kanban.less index 539d45535..70dd7facf 100644 --- a/www/kanban/app-kanban.less +++ b/www/kanban/app-kanban.less @@ -164,7 +164,10 @@ } margin-bottom: 15px; } - + .kanban-tag-btn-toggle { + margin-top: 10px; + margin-left: 10px + } #cp-app-kanban-container { flex: 1; display: flex; @@ -474,6 +477,9 @@ .cp-kanban-filterTags-list { margin-right: 10px; margin-left: 10px; + @media (max-width: 405px) { + padding-top: 15px + } display: flex; flex-wrap: wrap; &:not(.cp-empty) { diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 22db72ca4..9a7ce2654 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -56,6 +56,9 @@ define([ jKanban, Export) { + Messages.kanban_showTags = 'See all tags'; //XX + Messages.kanban_hideTags = 'See less tags'; //XX + var verbose = function (x) { console.log(x); }; verbose = function () {}; // comment out to enable verbose logging var onRedraw = Util.mkEvent(); @@ -937,6 +940,8 @@ define([ //framework._.sfCommon.setPadAttribute('quickMode', false); }); + var toggleTagsButton = h('button.btn.kanban-tag-btn-toggle', Messages.kanban_showTags); + // Tags filter var existing = getExistingTags(kanban.options.boards); var list = h('div.cp-kanban-filterTags-list'); @@ -946,12 +951,14 @@ define([ ]); var hint = h('span.cp-kanban-filterTags-name', Messages.kanban_tags); var tags = h('div.cp-kanban-filterTags', [ + h('span.cp-kanban-filterTags-toggle', [ hint, reset, ]), list, ]); + var $reset = $(reset); var $list = $(list); var $hint = $(hint); @@ -967,6 +974,7 @@ define([ return String($(this).data('tag')); }).get(); }; + var commitTags = function () { var t = getTags(); setTagFilterState(t.length); @@ -1024,6 +1032,40 @@ define([ commitTags(); }); + + if ($(window).width() < 500) { + + $(tags).append(toggleTagsButton); + + var hideTags = function () { + for (var tag of list.children) { + if (existing.indexOf(tag.innerHTML) > 10) { + $(tag).hide(); + } + } + }; + hideTags(); + + var toggleTags = function () { + for (var tag of list.children) { + if (existing.indexOf(tag.innerHTML) > 10 && kanban.options.tags.indexOf(tag.innerHTML) === -1) { + if ($(tag).is(":visible")) { + $(tag).hide(); + $(toggleTagsButton).html(Messages.kanban_showTags); + } else { + $(tag).show(); + $(toggleTagsButton).html(Messages.kanban_hideTags); + } + } + } + }; + + $(toggleTagsButton).click(function() { + toggleTags(); + }); + + } + var container = h('div#cp-kanban-controls', [ tags, h('div.cp-kanban-changeView', [ From fe656c16a30e27cf180753502e2a7326fcddae88 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Tue, 5 Dec 2023 11:38:59 +0100 Subject: [PATCH 076/283] changed button class --- www/kanban/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 9a7ce2654..8b41e9fa6 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -940,7 +940,7 @@ define([ //framework._.sfCommon.setPadAttribute('quickMode', false); }); - var toggleTagsButton = h('button.btn.kanban-tag-btn-toggle', Messages.kanban_showTags); + var toggleTagsButton = h('button.btn.btn-default.kanban-tag-btn-toggle', Messages.kanban_showTags); // Tags filter var existing = getExistingTags(kanban.options.boards); From 5d801a00fc901297874878506d0457e37c964216 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 5 Dec 2023 16:14:59 +0100 Subject: [PATCH 077/283] Remove incorrect error logs --- lib/plugin-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugin-manager.js b/lib/plugin-manager.js index e7a209ad5..5326fb3f9 100644 --- a/lib/plugin-manager.js +++ b/lib/plugin-manager.js @@ -12,7 +12,7 @@ try { } }); } catch (err) { - console.error(err); + if (err.code !== 'ENOENT') { console.error(err); } } module.exports = plugins; From 23a799d960411d5dc832afc584821f3e167cb8c8 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 5 Dec 2023 17:10:45 +0100 Subject: [PATCH 078/283] Fix missing plugin functions in HTTP workers --- lib/http-worker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/http-worker.js b/lib/http-worker.js index 0de5db29d..76df5caea 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -21,6 +21,7 @@ const PID = process.pid; 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); From 0f7cc0f8a7751e9726f8b2c258a68c2a70679e3a Mon Sep 17 00:00:00 2001 From: nisbet-hubbard <87453615+nisbet-hubbard@users.noreply.github.com> Date: Wed, 6 Dec 2023 15:24:32 +0800 Subject: [PATCH 079/283] Create example.httpd.conf --- docs/example.httpd.conf | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/example.httpd.conf diff --git a/docs/example.httpd.conf b/docs/example.httpd.conf new file mode 100644 index 000000000..3776a72ed --- /dev/null +++ b/docs/example.httpd.conf @@ -0,0 +1,35 @@ +# This file is included strictly as an example of how Apache httpd can be +# configured to work with CryptPad. If you are using CryptPad in production +# and require professional support please contact sales@cryptpad.fr + +# This configuration requires mod_ssl, mod_socache_shmcb, mod_proxy, +# mod_proxy_http and mod_headers + +Listen 443 + +SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 +SSLProxyCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 +SSLHonorCipherOrder off +SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 +SSLProxyProtocol all -SSLv3 -TLSv1 -TLSv1.1 +SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_scache(512000)" +SSLSessionCacheTimeout 86400 +SSLSessionTickets off +SSLUseStapling on +SSLStaplingCache "shmcb:logs/ssl_stapling(32768)" + + + ServerName cryptpad.your-domain.com + ServerAlias sandbox.your-domain.com + Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" + SSLEngine on + SSLCertificateFile /etc/letsencrypt/live/your-domain.com/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem + BrowserMatch "MSIE [2-5]" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + Protocols h2 http/1.1 + LimitRequestBody 157286400 + ProxyPass / http://localhost:3000/ upgrade=websocket + ProxyPassReverse / http://localhost:3000/ + From 3ea05fddb7d85f1a5f07a56434b78a7a85ec1808 Mon Sep 17 00:00:00 2001 From: nisbet-hubbard <87453615+nisbet-hubbard@users.noreply.github.com> Date: Wed, 6 Dec 2023 15:53:18 +0800 Subject: [PATCH 080/283] Edit for consistency --- docs/example.httpd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/example.httpd.conf b/docs/example.httpd.conf index 3776a72ed..d8b0d8d00 100644 --- a/docs/example.httpd.conf +++ b/docs/example.httpd.conf @@ -12,7 +12,7 @@ SSLProxyCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:EC SSLHonorCipherOrder off SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLProxyProtocol all -SSLv3 -TLSv1 -TLSv1.1 -SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_scache(512000)" +SSLSessionCache "shmcb:logs/ssl_scache(512000)" SSLSessionCacheTimeout 86400 SSLSessionTickets off SSLUseStapling on From 4407b5c048357bd0404d943c1debc5ba54b3d478 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 28 Nov 2023 09:57:01 +0100 Subject: [PATCH 081/283] Handle old version Nextcloud image import --- package-lock.json | 483 +++++++++++-------------------------- package.json | 2 +- www/common/image-dialog.js | 6 +- www/diagram/inner.js | 11 +- 4 files changed, 156 insertions(+), 346 deletions(-) diff --git a/package-lock.json b/package-lock.json index ba74fc690..bb832d524 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "file:../drawio-npm", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+2", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -68,9 +68,6 @@ "url": "https://opencollective.com/cryptpad" } }, - "../drawio-npm": { - "version": "21.8.2+1" - }, "node_modules/@mcrowe/minibloom": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mcrowe/minibloom/-/minibloom-0.2.0.tgz", @@ -109,9 +106,9 @@ } }, "node_modules/@types/http-proxy": { - "version": "1.17.13", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.13.tgz", - "integrity": "sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw==", + "version": "1.17.14", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", "dependencies": { "@types/node": "*" } @@ -123,11 +120,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.8.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", - "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "version": "20.10.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", + "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", "dependencies": { - "undici-types": "~5.25.1" + "undici-types": "~5.26.4" } }, "node_modules/@xmldom/xmldom": { @@ -798,12 +795,13 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -951,66 +949,17 @@ "node": ">=0.10.0" } }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/cli": { @@ -1041,9 +990,9 @@ } }, "node_modules/codemirror": { - "version": "5.65.15", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.15.tgz", - "integrity": "sha512-YC4EHbbwQeubZzxLl5G4nlbLc1T21QTrKGaOal/Pkm9dVDMZXMH7+ieSPEOZCtO9I68i8/oteJKOxzHC2zR+0g==" + "version": "5.65.16", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", + "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==" }, "node_modules/collection-visit": { "version": "1.0.0", @@ -1064,9 +1013,12 @@ "dev": true }, "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/components-font-awesome": { "version": "4.7.0", @@ -1227,6 +1179,19 @@ "node": ">=0.10" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", @@ -1350,8 +1315,8 @@ } }, "node_modules/drawio": { - "resolved": "../drawio-npm", - "link": true + "version": "21.8.2+2", + "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#d216a8ac7ac190ec1d6a61b06651916a0aa3d09e" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", @@ -1466,66 +1431,17 @@ "node": ">=0.10.0" } }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/express": { @@ -1916,14 +1832,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2022,17 +1938,31 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", "integrity": "sha512-zGRpnr2l5w/s8PxkrquUJoVeR06KvqPelrYqiSyQV7QEBqCYivpb6UzXYWC6JDBVtNFOT0rzJRFhkfJgxzmILA==" }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "engines": { - "node": ">= 0.4.0" + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { @@ -2120,6 +2050,17 @@ "node": ">=0.10.0" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/html2canvas": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", @@ -2277,22 +2218,14 @@ } }, "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", "dependencies": { - "kind-of": "^6.0.0" + "hasown": "^2.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.10" } }, "node_modules/is-arrayish": { @@ -2307,43 +2240,26 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", "dependencies": { - "kind-of": "^6.0.0" + "hasown": "^2.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/is-directory": { @@ -3133,47 +3049,16 @@ "node": ">=0.10.0" } }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/object-copy/node_modules/kind-of": { @@ -3188,9 +3073,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.0.tgz", - "integrity": "sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3945,6 +3830,20 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-getter": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.1.tgz", @@ -4086,66 +3985,17 @@ "node": ">=0.10.0" } }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/snapdragon/node_modules/source-map": { @@ -4158,9 +4008,9 @@ } }, "node_modules/sortablejs": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", - "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.1.tgz", + "integrity": "sha512-P5Cjvb0UG1ZVNiDPj/n4V+DinttXG6K8n7vM/HQf0C25K3YKQTQY6fsr/sEGsJGpQ9exmPxluHxKBc0mLKU1lQ==" }, "node_modules/sortify": { "version": "1.0.4", @@ -4266,61 +4116,16 @@ "node": ">=0.10.0" } }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, "node_modules/statuses": { @@ -4595,9 +4400,9 @@ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "node_modules/undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/union-value": { "version": "1.0.1", diff --git a/package.json b/package.json index 19f583950..94a4df7e9 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "file:../drawio-npm", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+2", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/www/common/image-dialog.js b/www/common/image-dialog.js index 4a648e0d5..31de9b6a5 100644 --- a/www/common/image-dialog.js +++ b/www/common/image-dialog.js @@ -2,8 +2,10 @@ define([], function() { const openImageDialog = function(common, integrationChannel, data, cb) { if (integrationChannel) { - const ignoreFirstParam = (_, image) => cb(image); - integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, ignoreFirstParam, {raw: true}); + const handleImage = (_, image) => { + cb(image); + }; + integrationChannel.query('Q_INTEGRATION_ON_INSERT_IMAGE', data, handleImage, {raw: true}); return; } common.openFilePicker({ diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 2af3caef4..2dd854e27 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -132,9 +132,8 @@ define([ params.set('type', type); params.set('protocol', url.protocol); url.search = params.toString(); - url.protocol = 'cryptpad:'; url.hash = key; - return url.href; + return url.href.replace(/https?:\/\//, 'cryptpad://'); }; const parseCryptPadUrl = function(href) { @@ -161,7 +160,7 @@ define([ return void reject(err); } try { - FileCrypto.decrypt(u8, nacl.util.decodeBase64(key), (err, res) => { + FileCrypto.decrypt(u8, Nacl.util.decodeBase64(key), (err, res) => { if (err || !res.content) { console.error("Decrypting failed"); return void reject(err); @@ -180,7 +179,11 @@ define([ APP.addImage = function() { return new Promise((resolve) => { framework.insertImage({}, (imageData) => { - resolve(getCryptPadUrl(imageData.src, imageData.key, imageData.fileType)); + if (imageData.blob) { + resolve(imageData.blob); + } else { + resolve(getCryptPadUrl(imageData.src, imageData.key, imageData.fileType)); + } }); }); }; From 15c3d9433e4f4b96a1d653c44be04d29e539cde0 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Wed, 6 Dec 2023 15:48:04 +0100 Subject: [PATCH 082/283] Embed images in diagrams when exporting them --- www/diagram/export.js | 80 +++++++++++++++++++++++++++++++++++++++++-- www/diagram/inner.js | 70 +++++++------------------------------ www/diagram/util.js | 66 +++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 61 deletions(-) create mode 100644 www/diagram/util.js diff --git a/www/diagram/export.js b/www/diagram/export.js index 1b7089559..07b12a463 100644 --- a/www/diagram/export.js +++ b/www/diagram/export.js @@ -4,15 +4,89 @@ define([ '/components/x2js/x2js.js', + '/diagram/util.js', ], function ( - X2JS) { + X2JS, + DiagramUtil, +) { const x2js = new X2JS(); const jsonContentAsXML = (content) => x2js.js2xml(content); + const parseDrawioStyle = (styleAttrValue) => { + if (!styleAttrValue) return; + + const result = {}; + for (const part of styleAttrValue.split(';')) { + const s = part.split(/=(.*)/); + result[s[0]] = s[1]; + } + + return result; + }; + + const stringifyDrawioStyle = (styleAttrValue) => { + const parts = []; + for (const [key, value] of Object.entries(styleAttrValue)) { + parts.push(`${key}=${value}`); + } + return parts.join(';'); + }; + + const findCryptPadImages = (doc) => { + return Array.from(doc .querySelectorAll('mxCell')) + .map((element) => [element, parseDrawioStyle(element.getAttribute('style'))]) + .filter(([element, style]) => style && style.image && style.image.startsWith('cryptpad://')) + }; + + const parseXML = (xmlStr) => { + const parser = new DOMParser(); + const doc = parser.parseFromString(xmlStr, "application/xml"); + const errorNode = doc.querySelector("parsererror"); + if (errorNode) { + throw Error("error while parsing " + errorNode); + } + return doc; + }; + + const blobToImage = (blob) => { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = function() { + resolve(reader.result); + }; + reader.readAsDataURL(blob); + }); + }; + + const loadImage = async (url) => { + const blob = await DiagramUtil.loadImage(url); + return await blobToImage(blob); + }; + return { - main: function(userDoc, cb) { + main: async function(userDoc, cb) { delete userDoc.metadata; - cb(jsonContentAsXML(userDoc), '.drawio'); + + const xml = jsonContentAsXML(userDoc); + + let doc; + try { + doc = parseXML(xml); + } catch(e) { + console.error(e); + return; + } + + const elements = findCryptPadImages(doc) + .map(([element, style]) => [element, style, loadImage(style.image)]); + + for (const [element, style, imagePromise] of elements) { + const dataUrl = await imagePromise; + style.image = dataUrl.replace(';base64', ''); // ';' breaks draw.ios style format + element.setAttribute('style', stringifyDrawioStyle(style)); + } + + cb(new XMLSerializer().serializeToString(doc), '.drawio'); } }; }); diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 7a7baade9..ace3d6bae 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -8,8 +8,7 @@ define([ '/customize/messages.js', // translation keys '/components/pako/dist/pako.min.js', '/components/x2js/x2js.js', - '/common/common-util.js', - '/file/file-crypto.js', + '/diagram/util.js', '/components/tweetnacl/nacl-fast.min.js', 'less!/diagram/app-diagram.less', 'css!/diagram/drawio.css', @@ -18,8 +17,8 @@ define([ Messages, pako, X2JS, - Util, - FileCrypto) { + DiagramUtil, +) { const Nacl = window.nacl; const APP = window.APP = {}; @@ -130,63 +129,14 @@ define([ autosave: onDrawioAutosave, }; - const getCryptPadUrl = function(src, key, type) { - const url = new URL(src); - const params = new URLSearchParams(); - params.set('type', type); - params.set('protocol', url.protocol); - url.search = params.toString(); - url.hash = key; - return url.href.replace(/https?:\/\//, 'cryptpad://'); - }; - - const parseCryptPadUrl = function(href) { - const url = new URL(href); - url.protocol = url.searchParams.get('protocol'); - const key = url.hash.substring(1); // remove leading '#' - const type = url.searchParams.get('type'); - url.search = ''; - url.hash = ''; - return { src: url.href, key, type }; - } - - const setBlobType = (blob, mimeType) => { - const fixedBlob = new Blob([blob], {type: mimeType}); - return fixedBlob; - }; - - APP.loadImage = function(href) { - return new Promise((resolve, reject) => { - const { src, key, type } = parseCryptPadUrl(href); - Util.fetch(src, function (err, u8) { - if (err) { - console.error(err); - return void reject(err); - } - try { - FileCrypto.decrypt(u8, Nacl.util.decodeBase64(key), (err, res) => { - if (err || !res.content) { - console.error("Decrypting failed"); - return void reject(err); - } - - resolve(setBlobType(res.content, type)); - }); - } catch (e) { - console.error(e); - reject(err); - } - }, void 0, framework._.sfCommon.getCache()); - }); - }; - + APP.loadImage = DiagramUtil.loadImage; APP.addImage = function() { return new Promise((resolve) => { framework.insertImage({}, (imageData) => { if (imageData.blob) { resolve(imageData.blob); } else { - resolve(getCryptPadUrl(imageData.src, imageData.key, imageData.fileType)); + resolve(DiagramUtil.getCryptPadUrl(imageData.src, imageData.key, imageData.fileType)); } }); }); @@ -218,9 +168,13 @@ define([ framework.setFileExporter( '.drawio', - () => { - return new Blob([jsonContentAsXML(lastContent)], {type: 'application/x-drawio'}); - } + (cb) => { + require(['/diagram/export.js'], (exporter) => { + exporter.main(lastContent, (xml) => { + cb(new Blob([xml], {type: 'application/x-drawio'})); + }); + }); + }, true ); framework.onEditableChange(function () { diff --git a/www/diagram/util.js b/www/diagram/util.js new file mode 100644 index 000000000..7099183af --- /dev/null +++ b/www/diagram/util.js @@ -0,0 +1,66 @@ +define([ + '/common/common-util.js', + '/file/file-crypto.js', + '/common/outer/cache-store.js', +], function ( + Util, + FileCrypto, + Cache, +) { + const Nacl = window.nacl; + + const parseCryptPadUrl = function(href) { + const url = new URL(href); + const protocol = url.searchParams.get('protocol'); + const key = url.hash.substring(1); // remove leading '#' + const type = url.searchParams.get('type'); + url.search = ''; + url.hash = ''; + return { src: url.href.replace(/cryptpad?:\/\//, `${protocol}//`), key, type }; + } + + const getCryptPadUrl = function(src, key, type) { + const url = new URL(src); + const params = new URLSearchParams(); + params.set('type', type); + params.set('protocol', url.protocol); + url.search = params.toString(); + url.hash = key; + return url.href.replace(/https?:\/\//, 'cryptpad://'); + }; + + const setBlobType = (blob, mimeType) => { + const fixedBlob = new Blob([blob], {type: mimeType}); + return fixedBlob; + }; + + return { + parseCryptPadUrl, + getCryptPadUrl, + + loadImage: function(href) { + return new Promise((resolve, reject) => { + const { src, key, type } = parseCryptPadUrl(href); + Util.fetch(src, function (err, u8) { + if (err) { + console.error(err); + return void reject(err); + } + try { + FileCrypto.decrypt(u8, Nacl.util.decodeBase64(key), (err, res) => { + if (err || !res.content) { + console.error("Decrypting failed"); + return void reject(err); + } + + resolve(setBlobType(res.content, type)); + }); + } catch (e) { + console.error(e); + reject(err); + } + }, void 0, Cache); + }); + } + }; +}); From 38d350319be0ccaeb53349a47206073fbbcb513f Mon Sep 17 00:00:00 2001 From: Fabrice Mouhartem Date: Wed, 6 Dec 2023 16:54:55 +0100 Subject: [PATCH 083/283] Uniform background color for fields in dark mode Related to #1299 + #1171 --- www/calendar/app-calendar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/calendar/app-calendar.less b/www/calendar/app-calendar.less index 232f3467d..e96c15f86 100644 --- a/www/calendar/app-calendar.less +++ b/www/calendar/app-calendar.less @@ -250,7 +250,7 @@ } .CodeMirror { margin-top: 5px; - background: @cp_forms-bg; + background: @cp_forms-bg !important; color: @cryptpad_text_col; border: 1px solid @cp_forms-border; border-radius: @variables_radius; From 4163bd8b30b58968e5c04eb0387114eb5e46e92c Mon Sep 17 00:00:00 2001 From: Fabrice Mouhartem Date: Wed, 6 Dec 2023 17:18:02 +0100 Subject: [PATCH 084/283] =?UTF-8?q?Replace=20=E2=80=9CLocation:=E2=80=9D?= =?UTF-8?q?=20with=20an=20icon=20and=20remove=20the=20=E2=80=9CDescription?= =?UTF-8?q?:=E2=80=9D=20text=20in=20the=20popup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related to #1299 + #1171 --- www/calendar/app-calendar.less | 5 ++++- www/calendar/inner.js | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/www/calendar/app-calendar.less b/www/calendar/app-calendar.less index e96c15f86..3c40ac5d6 100644 --- a/www/calendar/app-calendar.less +++ b/www/calendar/app-calendar.less @@ -162,9 +162,12 @@ color: @cryptpad_text_col; border-radius: @variables_radius_L; font-weight: normal; - .tui-full-calendar-icon:not(.tui-full-calendar-calendar-dot):not(.tui-full-calendar-dropdown-arrow):not(.tui-full-calendar-ic-checkbox) { + .tui-full-calendar-icon:not(.tui-full-calendar-calendar-dot):not(.tui-full-calendar-dropdown-arrow):not(.tui-full-calendar-ic-checkbox):not(.fa-map-marker) { display: none; } + .tui-full-calendar-icon { + text-align:center; + } .tui-full-calendar-popup-detail-item { a { color: @cryptpad_color_link; diff --git a/www/calendar/inner.js b/www/calendar/inner.js index 447deb0a0..cb71ff1b1 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -74,7 +74,7 @@ define([ Messages.calendar_rec_change_first = "You moved the first repeating event to different calendar. You can only apply this change to all repeated events."; // XXX New translation key Messages.calendar_rec_change = "You moved a repeating event to different calendar. You can only apply this change to this event or all repeated events."; // XXX New translation key Messages.calendar_desc = "Description"; // XXX maybe rename in `description`? - Messages.calendar_description = "Description:{0}{1}"; // XXX + delete Messages.calendar_location // XXX Remove Messages.calendar_location from translation keys as it is not used anymore? var SaveAs = window.saveAs; var APP = window.APP = { @@ -408,13 +408,13 @@ define([ str = `${str}`; APP.nextLocationUid = uid; } - - return Messages._getKey('calendar_location', [str]); + let location_icon = h('i.fa.fa-map-marker.tui-full-calendar-icon', { 'aria-label': Messages.calendar_loc }, []); + return location_icon.outerHTML + str; }, popupDetailBody: function(schedule) { var str = schedule.body; delete APP.eventBody; - return Messages._getKey('calendar_description', ['
', diffMk.render(str, true)]); + return diffMk.render(str, true); }, popupIsAllDay: function() { return Messages.calendar_allDay; }, titlePlaceholder: function() { return Messages.calendar_title; }, From 5c8e8c5bff65e85f837dac1d3dae938df4d3bbc1 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 7 Dec 2023 09:20:18 +0100 Subject: [PATCH 085/283] Fix eslint warnings --- www/diagram/export.js | 59 +++++++++++++++++++++++-------------------- www/diagram/inner.js | 2 +- www/diagram/util.js | 4 +-- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/www/diagram/export.js b/www/diagram/export.js index 07b12a463..6f59957b0 100644 --- a/www/diagram/export.js +++ b/www/diagram/export.js @@ -7,13 +7,15 @@ define([ '/diagram/util.js', ], function ( X2JS, - DiagramUtil, + DiagramUtil ) { const x2js = new X2JS(); const jsonContentAsXML = (content) => x2js.js2xml(content); const parseDrawioStyle = (styleAttrValue) => { - if (!styleAttrValue) return; + if (!styleAttrValue) { + return; + } const result = {}; for (const part of styleAttrValue.split(';')) { @@ -32,10 +34,31 @@ define([ return parts.join(';'); }; - const findCryptPadImages = (doc) => { + const blobToImage = (blob) => { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.onloadend = function() { + resolve(reader.result); + }; + reader.readAsDataURL(blob); + }); + }; + + const loadImage = (url) => { + return DiagramUtil.loadImage(url).then((blob) => blobToImage(blob)); + }; + + const loadCryptPadImages = (doc) => { return Array.from(doc .querySelectorAll('mxCell')) .map((element) => [element, parseDrawioStyle(element.getAttribute('style'))]) .filter(([element, style]) => style && style.image && style.image.startsWith('cryptpad://')) + .map(([element, style]) => { + return loadImage(style.image) + .then((dataUrl) => { + style.image = dataUrl.replace(';base64', ''); // ';' breaks draw.ios style format + element.setAttribute('style', stringifyDrawioStyle(style)); + }); + }); }; const parseXML = (xmlStr) => { @@ -48,23 +71,8 @@ define([ return doc; }; - const blobToImage = (blob) => { - return new Promise((resolve) => { - const reader = new FileReader(); - reader.onloadend = function() { - resolve(reader.result); - }; - reader.readAsDataURL(blob); - }); - }; - - const loadImage = async (url) => { - const blob = await DiagramUtil.loadImage(url); - return await blobToImage(blob); - }; - return { - main: async function(userDoc, cb) { + main: function(userDoc, cb) { delete userDoc.metadata; const xml = jsonContentAsXML(userDoc); @@ -77,16 +85,11 @@ define([ return; } - const elements = findCryptPadImages(doc) - .map(([element, style]) => [element, style, loadImage(style.image)]); + const promises = loadCryptPadImages(doc); - for (const [element, style, imagePromise] of elements) { - const dataUrl = await imagePromise; - style.image = dataUrl.replace(';base64', ''); // ';' breaks draw.ios style format - element.setAttribute('style', stringifyDrawioStyle(style)); - } - - cb(new XMLSerializer().serializeToString(doc), '.drawio'); + Promise.all(promises).then(() => { + cb(new XMLSerializer().serializeToString(doc), '.drawio'); + }); } }; }); diff --git a/www/diagram/inner.js b/www/diagram/inner.js index ace3d6bae..387abaa59 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -17,7 +17,7 @@ define([ Messages, pako, X2JS, - DiagramUtil, + DiagramUtil ) { const Nacl = window.nacl; const APP = window.APP = {}; diff --git a/www/diagram/util.js b/www/diagram/util.js index 7099183af..ec0249446 100644 --- a/www/diagram/util.js +++ b/www/diagram/util.js @@ -5,7 +5,7 @@ define([ ], function ( Util, FileCrypto, - Cache, + Cache ) { const Nacl = window.nacl; @@ -17,7 +17,7 @@ define([ url.search = ''; url.hash = ''; return { src: url.href.replace(/cryptpad?:\/\//, `${protocol}//`), key, type }; - } + }; const getCryptPadUrl = function(src, key, type) { const url = new URL(src); From 3fedc35bed14732de32ad5958614e4e7b656bd5f Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 7 Dec 2023 09:27:00 +0100 Subject: [PATCH 086/283] Disable internal diagram export which is broken for images --- package-lock.json | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb832d524..2807a8521 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+2", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+3", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -120,9 +120,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.3.tgz", - "integrity": "sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==", + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", "dependencies": { "undici-types": "~5.26.4" } @@ -1316,7 +1316,7 @@ }, "node_modules/drawio": { "version": "21.8.2+2", - "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#d216a8ac7ac190ec1d6a61b06651916a0aa3d09e" + "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#20bb1d9ac9ee504002fa39c44c6585b6ac7f2282" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", diff --git a/package.json b/package.json index 94a4df7e9..b076ce14d 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+2", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+3", "pako": "^2.1.0", "x2js": "^3.4.4" }, From a24bc397a62cb04711c3abdb3404f224764e9357 Mon Sep 17 00:00:00 2001 From: Fabrice Mouhartem Date: Thu, 7 Dec 2023 18:10:59 +0100 Subject: [PATCH 087/283] Lint compliance --- www/calendar/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index cb71ff1b1..fbd56ce07 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -74,7 +74,7 @@ define([ Messages.calendar_rec_change_first = "You moved the first repeating event to different calendar. You can only apply this change to all repeated events."; // XXX New translation key Messages.calendar_rec_change = "You moved a repeating event to different calendar. You can only apply this change to this event or all repeated events."; // XXX New translation key Messages.calendar_desc = "Description"; // XXX maybe rename in `description`? - delete Messages.calendar_location // XXX Remove Messages.calendar_location from translation keys as it is not used anymore? + delete Messages.calendar_location; // XXX Remove Messages.calendar_location from translation keys as it is not used anymore? var SaveAs = window.saveAs; var APP = window.APP = { From c829a871c7285429e42e4830daee00e275733651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 09:56:35 +0100 Subject: [PATCH 088/283] remove .flowconfig file, unused by anyone since 2017 --- .flowconfig | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .flowconfig diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 7f1aa684c..000000000 --- a/.flowconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -[ignore] -.*/components/.* -.*/node_modules/lesshint/* -[include] - -[libs] - -[options] From bfd3e91d9bd2f1f3d80204d4f8d1bcbb1ad47e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 09:56:48 +0100 Subject: [PATCH 089/283] remove .editorconfig file, who added this to the repo? --- .editorconfig | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 31d399ad6..000000000 --- a/.editorconfig +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true -indent_style = space -indent_size = 4 -charset = utf-8 From 6c9a99a5e4206b7247779357ccc22a93e924288e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 09:57:08 +0100 Subject: [PATCH 090/283] remove debugging.md, almost empty file --- docs/debugging.md | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 docs/debugging.md diff --git a/docs/debugging.md b/docs/debugging.md deleted file mode 100644 index 2899016ca..000000000 --- a/docs/debugging.md +++ /dev/null @@ -1,8 +0,0 @@ - - -* compare your conf against `cryptpad/docs/example.nginx.conf` -* From 7280cc54a655b0177dd9088c1b76e7e5bff77bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:29:36 +0100 Subject: [PATCH 091/283] move adding translations instructions to developer guide https://github.com/cryptpad/documentation/pull/33/commits/ea75dac5994e2b091afc7ca479c0dcf8ef5072da --- www/common/translations/README.md | 135 ------------------------------ 1 file changed, 135 deletions(-) delete mode 100644 www/common/translations/README.md diff --git a/www/common/translations/README.md b/www/common/translations/README.md deleted file mode 100644 index 3b61e46be..000000000 --- a/www/common/translations/README.md +++ /dev/null @@ -1,135 +0,0 @@ - - -# Adding Translations - -To illustrate the process of translating, this guide will make an english-pirate translation of Cryptpad. -We'll assume that you have a work locally-installed, properly functioning installation of Cryptpad. -If you don't have Cryptpad installed locally, start by following the steps in the main readme. - -## Getting started - -Once everything is working, copy the default (English) source file (`/www/common/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/www/common/translations/messages.fr.js`. -There is no ISO 639-1 language code for _English-pirate_, so we'll just call it `messages.pirate.js`. - -```Bash -cd www/common/translations/ -cp messages.js messages.pirate.js -``` - -## Including your translation - -To include your translation in the list, you'll need to add it to `/customize.dist/messages.js`. -There are comments indicating what to modify in three places: - -```javascript -(function () { -// add your module to this map so it gets used -// please use the translated name of your language ("Français" and not "French") -var map = { - 'fr': 'Français', - 'es': 'Español', - 'pl': 'Polski', - 'de': 'Deutsch', - 'pt-br': 'Português do Brasil', - 'ro': 'Română', - 'zh': '繁體中文', - 'el': 'Ελληνικά', -}; -``` - -We need to modify that map to include our translation: - -```javascript -(function () { -// add your module to this map so it gets used -// please use the translated name of your language ("Français" and not "French") -var map = { - 'fr': 'Français', - 'es': 'Español', - 'pl': 'Polski', - 'de': 'Deutsch', - 'pt-br': 'Português do Brasil', - 'ro': 'Română', - 'zh': '繁體中文', - 'el': 'Ελληνικά', - 'pirate': 'English Pirate', // add our module to the map of languages -}; -``` -Just add your module in a similar fashion to the existing translations, save your changes, and close `/customize.dist/messages.js`. - - -You also need to add a customizable version of you translation. To do so, make a copy of the file `/customize.dist/translations/messages.js` with your translation name (`messages.pirate.js` in our case), and change its content to load the correct language file: - -```javascript -/* - * You can override the translation text using this file. - * The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js) - in a 'customize' directory (/customize/translations/messages.{LANG}.js). - * If you want to check all the existing translation keys, you can open the internal language file - but you should not change it directly (/common/translations/messages.{LANG}.js) -*/ -define(['/common/translations/messages.pirate.js'], function (Messages) { // Change the file name here - // Replace the existing keys (in your copied file) here: - // Messages.button_newpad = "New Rich Text Document"; - return Messages; -}); -``` - -That's all! - -## Actually translating content - -Now we can go back to our file, `/www/common/translations/messages.pirate.js` and start to add our Pirate-language customizations. - -Open the translation file you created in `/customize.dist/translations/`. -You should see something like: - -```javascript -define(function () { - var out = {}; - - out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing"; -``` - -Now you just need to work through this file, updating the strings like so: - -```javascript -define(function () { - var out = {}; - - out.main_title = "Cryptpad: Knowledge lost at sea while ye scribble with yer mateys"; -``` - -It's important that you modify just the string, and not the variable name which is used to access its content. -For instance, changing `main_title` to `mainTitle` would make the translated string inaccessible to the rest of the codebase. - -If a key is not found in your translation, the default English version of that key will be used. -This is to make sure that buttons and other interface elements are not empty, but it's obviously not ideal. - -## Verifying Your Translations - -It's advisable to save your translation file frequently, and reload Cryptpad in your browser to check that there are no errors in your translation file. -If there are any errors in your code, the file will fail to parse, and the page will no load correctly. - -Checking frequently will make it easier to know which change caused the error. - -Additionally, we advise using the apps and visiting the various pages, to make sure that your translations make sense in context. - -When you're happy with your translation file, you can visit http://localhost:3000/assert/translations/ to view Cryptpad's tests. -These tests will check to make sure that your translation has an entry for every entry in the default English translation. - -## Getting Help - -If you have any issues, reach out via any of the methods listed in the readme under **Contacting Us**. -We're happy to help. - -## Deleting a translation -When a key is nolonger used (such as presentSuccess) you can delete it using this bash one-liner. - -```shell -( export KEY=presentSuccess && grep -nr "$KEY" ./www/common/translations/ | sed 's/:.*$//' | while read x; do sed -i -e "/out\.$KEY =/d" $x; done ) -``` From 394a40619ab1623b93523015707d940343098487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:41:54 +0100 Subject: [PATCH 092/283] move some interesting details to the docs https://github.com/cryptpad/cryptpad/blob/main/customize.dist/readme.md --- customize.dist/readme.md | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 customize.dist/readme.md diff --git a/customize.dist/readme.md b/customize.dist/readme.md deleted file mode 100644 index ca5ea12a1..000000000 --- a/customize.dist/readme.md +++ /dev/null @@ -1,31 +0,0 @@ - - -# Customizing CryptPad - -In order allow a variety of features to be changed and to allow site-specific changes -to CryptPad apps while still keeping the git repository pristine, this directory exists -to allow a set of hooks to be run. - -The server is configured to load files from the `/customize/` path preferentially from -`cryptpad/customize/`, and to fall back to `cryptpad/customize.dist/` if they are not found - -If you wish to customize cryptpad, please **copy** -`/customize.dist/` to `/customize` and then edit it there, this way you will still be able -to pull from (and make pull requests to (!) the git repository. - -## Files you may be interested in - -* index.html is the main page -* main.js contains javascript for the home page -* application_config.js allows you to modify settings used by the various applications -* messages.js contains functions for applying translations to various pages - * look inside `/translations/` for the rest of the files which contain translated strings -* `/share/` implements an iframe RPC which allows multiple domains to access the same localStorage -* `/src/` contains source files for html and css (in the form of html templates and .less stylesheets) - -All other content which is placed in this directory will be referencable at the `/customize/` -URL location. From fec9678db30ce4bb0834d8d4ca992ab88d83bad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:51:32 +0100 Subject: [PATCH 093/283] remove useless file, content is on the docs https://docs.cryptpad.org/en/how_to_contribute.html#translate-cryptpad --- customize.dist/translations/README.md | 37 --------------------------- 1 file changed, 37 deletions(-) delete mode 100644 customize.dist/translations/README.md diff --git a/customize.dist/translations/README.md b/customize.dist/translations/README.md deleted file mode 100644 index e42df15ac..000000000 --- a/customize.dist/translations/README.md +++ /dev/null @@ -1,37 +0,0 @@ - - -# Translations - -Translations can now be made using [Weblate](https://weblate.cryptpad.org). We may still accept PRs for the internal translation files, but we won't provide support for this. See the state of the translated languages: - -![](https://weblate.cryptpad.org/widgets/cryptpad/-/app/multi-auto.svg) - -## Request a new language - -* New languages require some minor changes in the code which we have to apply manually. If you want to translate CryptPad into a new language, please send us an email at weblate@cryptpad.fr -* Please note that members of the current development team are only fluent in English and French, so additional languages will require ongoing contributions in order to stay up to date. - * If a language becomes too outdated, we will consider dropping it from the available language until it is fixed. - * Please refrain from asking for a new language if you are not able to provide a sufficiently translated version and maintain it or to find other users that can do so. - -## Become a reviewer - -* We need reviewers for all the languages except English and French. Their job will be to approve/reject/discuss the translations made by other contributors to this language, using the Weblate UI. -* If you want to become a reviewer for a language, please write us an email at weblate@cryptpad.fr -* Please tell us if you want to stop being a reviewer (even momentarily) so that we can find a replacement as soon as posible - -## Translate an existing language - -* All translations can be done using the Weblate UI. For better help about how to use the tool, please check the [Weblate documentation](https://docs.weblate.org/en/latest/). -* Our Weblate instance is configured to always require approval for changes. - -### Update an existing translation - -* Existing translations that have already been approved can't be changed directly. Users can only make suggestions, and the reviewers will have to approve the changes if they agree. - -### Translate a new key - -* Untranslated strings can be changed by any user and the translation can be edited by others as long as it has not been approved by a reviewer. From e9b674d220e5469893de2e85fc8cf558ee99a195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:38:24 +0100 Subject: [PATCH 094/283] remove www/lib/ical since we have licensing info elsewhere --- www/lib/ical/LICENSE | 373 ----------------------------------------- www/lib/ical/README.md | 7 - 2 files changed, 380 deletions(-) delete mode 100644 www/lib/ical/LICENSE delete mode 100644 www/lib/ical/README.md diff --git a/www/lib/ical/LICENSE b/www/lib/ical/LICENSE deleted file mode 100644 index a612ad981..000000000 --- a/www/lib/ical/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/www/lib/ical/README.md b/www/lib/ical/README.md deleted file mode 100644 index 330444b81..000000000 --- a/www/lib/ical/README.md +++ /dev/null @@ -1,7 +0,0 @@ - - -`cryptpad/www/lib/ical.min.js` was imported from https://github.com/mozilla-comm/ical.js and is available under the terms of the Mozilla Public License Version 2.0, included in this folder. From 120e682a8ac41d5acd751ba4b695d3dc117f3cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:44:04 +0100 Subject: [PATCH 095/283] Revert "move adding translations instructions to developer guide https://github.com/cryptpad/documentation/pull/33/commits/ea75dac5994e2b091afc7ca479c0dcf8ef5072da" This reverts commit 7280cc54a655b0177dd9088c1b76e7e5bff77bc6. --- www/common/translations/README.md | 135 ++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 www/common/translations/README.md diff --git a/www/common/translations/README.md b/www/common/translations/README.md new file mode 100644 index 000000000..3b61e46be --- /dev/null +++ b/www/common/translations/README.md @@ -0,0 +1,135 @@ + + +# Adding Translations + +To illustrate the process of translating, this guide will make an english-pirate translation of Cryptpad. +We'll assume that you have a work locally-installed, properly functioning installation of Cryptpad. +If you don't have Cryptpad installed locally, start by following the steps in the main readme. + +## Getting started + +Once everything is working, copy the default (English) source file (`/www/common/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/www/common/translations/messages.fr.js`. +There is no ISO 639-1 language code for _English-pirate_, so we'll just call it `messages.pirate.js`. + +```Bash +cd www/common/translations/ +cp messages.js messages.pirate.js +``` + +## Including your translation + +To include your translation in the list, you'll need to add it to `/customize.dist/messages.js`. +There are comments indicating what to modify in three places: + +```javascript +(function () { +// add your module to this map so it gets used +// please use the translated name of your language ("Français" and not "French") +var map = { + 'fr': 'Français', + 'es': 'Español', + 'pl': 'Polski', + 'de': 'Deutsch', + 'pt-br': 'Português do Brasil', + 'ro': 'Română', + 'zh': '繁體中文', + 'el': 'Ελληνικά', +}; +``` + +We need to modify that map to include our translation: + +```javascript +(function () { +// add your module to this map so it gets used +// please use the translated name of your language ("Français" and not "French") +var map = { + 'fr': 'Français', + 'es': 'Español', + 'pl': 'Polski', + 'de': 'Deutsch', + 'pt-br': 'Português do Brasil', + 'ro': 'Română', + 'zh': '繁體中文', + 'el': 'Ελληνικά', + 'pirate': 'English Pirate', // add our module to the map of languages +}; +``` +Just add your module in a similar fashion to the existing translations, save your changes, and close `/customize.dist/messages.js`. + + +You also need to add a customizable version of you translation. To do so, make a copy of the file `/customize.dist/translations/messages.js` with your translation name (`messages.pirate.js` in our case), and change its content to load the correct language file: + +```javascript +/* + * You can override the translation text using this file. + * The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js) + in a 'customize' directory (/customize/translations/messages.{LANG}.js). + * If you want to check all the existing translation keys, you can open the internal language file + but you should not change it directly (/common/translations/messages.{LANG}.js) +*/ +define(['/common/translations/messages.pirate.js'], function (Messages) { // Change the file name here + // Replace the existing keys (in your copied file) here: + // Messages.button_newpad = "New Rich Text Document"; + return Messages; +}); +``` + +That's all! + +## Actually translating content + +Now we can go back to our file, `/www/common/translations/messages.pirate.js` and start to add our Pirate-language customizations. + +Open the translation file you created in `/customize.dist/translations/`. +You should see something like: + +```javascript +define(function () { + var out = {}; + + out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing"; +``` + +Now you just need to work through this file, updating the strings like so: + +```javascript +define(function () { + var out = {}; + + out.main_title = "Cryptpad: Knowledge lost at sea while ye scribble with yer mateys"; +``` + +It's important that you modify just the string, and not the variable name which is used to access its content. +For instance, changing `main_title` to `mainTitle` would make the translated string inaccessible to the rest of the codebase. + +If a key is not found in your translation, the default English version of that key will be used. +This is to make sure that buttons and other interface elements are not empty, but it's obviously not ideal. + +## Verifying Your Translations + +It's advisable to save your translation file frequently, and reload Cryptpad in your browser to check that there are no errors in your translation file. +If there are any errors in your code, the file will fail to parse, and the page will no load correctly. + +Checking frequently will make it easier to know which change caused the error. + +Additionally, we advise using the apps and visiting the various pages, to make sure that your translations make sense in context. + +When you're happy with your translation file, you can visit http://localhost:3000/assert/translations/ to view Cryptpad's tests. +These tests will check to make sure that your translation has an entry for every entry in the default English translation. + +## Getting Help + +If you have any issues, reach out via any of the methods listed in the readme under **Contacting Us**. +We're happy to help. + +## Deleting a translation +When a key is nolonger used (such as presentSuccess) you can delete it using this bash one-liner. + +```shell +( export KEY=presentSuccess && grep -nr "$KEY" ./www/common/translations/ | sed 's/:.*$//' | while read x; do sed -i -e "/out\.$KEY =/d" $x; done ) +``` From 8fcc05adb5dc82fac1f418f02536ccd63c4d00ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:44:32 +0100 Subject: [PATCH 096/283] Revert "move some interesting details to the docs https://github.com/cryptpad/cryptpad/blob/main/customize.dist/readme.md" This reverts commit 394a40619ab1623b93523015707d940343098487. --- customize.dist/readme.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 customize.dist/readme.md diff --git a/customize.dist/readme.md b/customize.dist/readme.md new file mode 100644 index 000000000..ca5ea12a1 --- /dev/null +++ b/customize.dist/readme.md @@ -0,0 +1,31 @@ + + +# Customizing CryptPad + +In order allow a variety of features to be changed and to allow site-specific changes +to CryptPad apps while still keeping the git repository pristine, this directory exists +to allow a set of hooks to be run. + +The server is configured to load files from the `/customize/` path preferentially from +`cryptpad/customize/`, and to fall back to `cryptpad/customize.dist/` if they are not found + +If you wish to customize cryptpad, please **copy** +`/customize.dist/` to `/customize` and then edit it there, this way you will still be able +to pull from (and make pull requests to (!) the git repository. + +## Files you may be interested in + +* index.html is the main page +* main.js contains javascript for the home page +* application_config.js allows you to modify settings used by the various applications +* messages.js contains functions for applying translations to various pages + * look inside `/translations/` for the rest of the files which contain translated strings +* `/share/` implements an iframe RPC which allows multiple domains to access the same localStorage +* `/src/` contains source files for html and css (in the form of html templates and .less stylesheets) + +All other content which is placed in this directory will be referencable at the `/customize/` +URL location. From 78f44b578d35d06d9aec39012a0e3dd11017dc5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:44:45 +0100 Subject: [PATCH 097/283] Revert "remove useless file, content is on the docs https://docs.cryptpad.org/en/how_to_contribute.html#translate-cryptpad" This reverts commit fec9678db30ce4bb0834d8d4ca992ab88d83bad1. --- customize.dist/translations/README.md | 37 +++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 customize.dist/translations/README.md diff --git a/customize.dist/translations/README.md b/customize.dist/translations/README.md new file mode 100644 index 000000000..e42df15ac --- /dev/null +++ b/customize.dist/translations/README.md @@ -0,0 +1,37 @@ + + +# Translations + +Translations can now be made using [Weblate](https://weblate.cryptpad.org). We may still accept PRs for the internal translation files, but we won't provide support for this. See the state of the translated languages: + +![](https://weblate.cryptpad.org/widgets/cryptpad/-/app/multi-auto.svg) + +## Request a new language + +* New languages require some minor changes in the code which we have to apply manually. If you want to translate CryptPad into a new language, please send us an email at weblate@cryptpad.fr +* Please note that members of the current development team are only fluent in English and French, so additional languages will require ongoing contributions in order to stay up to date. + * If a language becomes too outdated, we will consider dropping it from the available language until it is fixed. + * Please refrain from asking for a new language if you are not able to provide a sufficiently translated version and maintain it or to find other users that can do so. + +## Become a reviewer + +* We need reviewers for all the languages except English and French. Their job will be to approve/reject/discuss the translations made by other contributors to this language, using the Weblate UI. +* If you want to become a reviewer for a language, please write us an email at weblate@cryptpad.fr +* Please tell us if you want to stop being a reviewer (even momentarily) so that we can find a replacement as soon as posible + +## Translate an existing language + +* All translations can be done using the Weblate UI. For better help about how to use the tool, please check the [Weblate documentation](https://docs.weblate.org/en/latest/). +* Our Weblate instance is configured to always require approval for changes. + +### Update an existing translation + +* Existing translations that have already been approved can't be changed directly. Users can only make suggestions, and the reviewers will have to approve the changes if they agree. + +### Translate a new key + +* Untranslated strings can be changed by any user and the translation can be edited by others as long as it has not been approved by a reviewer. From 2392daaef1cdfc07c57db4a2b319379d3811036b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:47:42 +0100 Subject: [PATCH 098/283] remove content and point to the appropraite documentation page --- www/common/translations/README.md | 128 +----------------------------- 1 file changed, 1 insertion(+), 127 deletions(-) diff --git a/www/common/translations/README.md b/www/common/translations/README.md index 3b61e46be..920373858 100644 --- a/www/common/translations/README.md +++ b/www/common/translations/README.md @@ -6,130 +6,4 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Adding Translations -To illustrate the process of translating, this guide will make an english-pirate translation of Cryptpad. -We'll assume that you have a work locally-installed, properly functioning installation of Cryptpad. -If you don't have Cryptpad installed locally, start by following the steps in the main readme. - -## Getting started - -Once everything is working, copy the default (English) source file (`/www/common/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/www/common/translations/messages.fr.js`. -There is no ISO 639-1 language code for _English-pirate_, so we'll just call it `messages.pirate.js`. - -```Bash -cd www/common/translations/ -cp messages.js messages.pirate.js -``` - -## Including your translation - -To include your translation in the list, you'll need to add it to `/customize.dist/messages.js`. -There are comments indicating what to modify in three places: - -```javascript -(function () { -// add your module to this map so it gets used -// please use the translated name of your language ("Français" and not "French") -var map = { - 'fr': 'Français', - 'es': 'Español', - 'pl': 'Polski', - 'de': 'Deutsch', - 'pt-br': 'Português do Brasil', - 'ro': 'Română', - 'zh': '繁體中文', - 'el': 'Ελληνικά', -}; -``` - -We need to modify that map to include our translation: - -```javascript -(function () { -// add your module to this map so it gets used -// please use the translated name of your language ("Français" and not "French") -var map = { - 'fr': 'Français', - 'es': 'Español', - 'pl': 'Polski', - 'de': 'Deutsch', - 'pt-br': 'Português do Brasil', - 'ro': 'Română', - 'zh': '繁體中文', - 'el': 'Ελληνικά', - 'pirate': 'English Pirate', // add our module to the map of languages -}; -``` -Just add your module in a similar fashion to the existing translations, save your changes, and close `/customize.dist/messages.js`. - - -You also need to add a customizable version of you translation. To do so, make a copy of the file `/customize.dist/translations/messages.js` with your translation name (`messages.pirate.js` in our case), and change its content to load the correct language file: - -```javascript -/* - * You can override the translation text using this file. - * The recommended method is to make a copy of this file (/customize.dist/translations/messages.{LANG}.js) - in a 'customize' directory (/customize/translations/messages.{LANG}.js). - * If you want to check all the existing translation keys, you can open the internal language file - but you should not change it directly (/common/translations/messages.{LANG}.js) -*/ -define(['/common/translations/messages.pirate.js'], function (Messages) { // Change the file name here - // Replace the existing keys (in your copied file) here: - // Messages.button_newpad = "New Rich Text Document"; - return Messages; -}); -``` - -That's all! - -## Actually translating content - -Now we can go back to our file, `/www/common/translations/messages.pirate.js` and start to add our Pirate-language customizations. - -Open the translation file you created in `/customize.dist/translations/`. -You should see something like: - -```javascript -define(function () { - var out = {}; - - out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing"; -``` - -Now you just need to work through this file, updating the strings like so: - -```javascript -define(function () { - var out = {}; - - out.main_title = "Cryptpad: Knowledge lost at sea while ye scribble with yer mateys"; -``` - -It's important that you modify just the string, and not the variable name which is used to access its content. -For instance, changing `main_title` to `mainTitle` would make the translated string inaccessible to the rest of the codebase. - -If a key is not found in your translation, the default English version of that key will be used. -This is to make sure that buttons and other interface elements are not empty, but it's obviously not ideal. - -## Verifying Your Translations - -It's advisable to save your translation file frequently, and reload Cryptpad in your browser to check that there are no errors in your translation file. -If there are any errors in your code, the file will fail to parse, and the page will no load correctly. - -Checking frequently will make it easier to know which change caused the error. - -Additionally, we advise using the apps and visiting the various pages, to make sure that your translations make sense in context. - -When you're happy with your translation file, you can visit http://localhost:3000/assert/translations/ to view Cryptpad's tests. -These tests will check to make sure that your translation has an entry for every entry in the default English translation. - -## Getting Help - -If you have any issues, reach out via any of the methods listed in the readme under **Contacting Us**. -We're happy to help. - -## Deleting a translation -When a key is nolonger used (such as presentSuccess) you can delete it using this bash one-liner. - -```shell -( export KEY=presentSuccess && grep -nr "$KEY" ./www/common/translations/ | sed 's/:.*$//' | while read x; do sed -i -e "/out\.$KEY =/d" $x; done ) -``` +This tutorial is part of our documentation, you can find it in our developer guide: https://docs.cryptpad.org/en/dev_guide/translations.html \ No newline at end of file From dd6bd08eb2f0b3ff329d1b4343eae21290065d05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:49:36 +0100 Subject: [PATCH 099/283] remove content and point to the appropraite documentation page --- customize.dist/readme.md | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/customize.dist/readme.md b/customize.dist/readme.md index ca5ea12a1..cd4597321 100644 --- a/customize.dist/readme.md +++ b/customize.dist/readme.md @@ -6,26 +6,4 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Customizing CryptPad -In order allow a variety of features to be changed and to allow site-specific changes -to CryptPad apps while still keeping the git repository pristine, this directory exists -to allow a set of hooks to be run. - -The server is configured to load files from the `/customize/` path preferentially from -`cryptpad/customize/`, and to fall back to `cryptpad/customize.dist/` if they are not found - -If you wish to customize cryptpad, please **copy** -`/customize.dist/` to `/customize` and then edit it there, this way you will still be able -to pull from (and make pull requests to (!) the git repository. - -## Files you may be interested in - -* index.html is the main page -* main.js contains javascript for the home page -* application_config.js allows you to modify settings used by the various applications -* messages.js contains functions for applying translations to various pages - * look inside `/translations/` for the rest of the files which contain translated strings -* `/share/` implements an iframe RPC which allows multiple domains to access the same localStorage -* `/src/` contains source files for html and css (in the form of html templates and .less stylesheets) - -All other content which is placed in this directory will be referencable at the `/customize/` -URL location. +This tutorial is part of our documentation, you can find it in our administrator guide: https://docs.cryptpad.org/en/admin_guide/customization.html From 8aceb6e86bcda7c825ea17d93679b7623768ee36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Fri, 8 Dec 2023 11:51:18 +0100 Subject: [PATCH 100/283] remove content and point to the appropraite documentation page --- customize.dist/translations/README.md | 30 +-------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/customize.dist/translations/README.md b/customize.dist/translations/README.md index e42df15ac..f2dc5ee8e 100644 --- a/customize.dist/translations/README.md +++ b/customize.dist/translations/README.md @@ -6,32 +6,4 @@ SPDX-License-Identifier: AGPL-3.0-or-later # Translations -Translations can now be made using [Weblate](https://weblate.cryptpad.org). We may still accept PRs for the internal translation files, but we won't provide support for this. See the state of the translated languages: - -![](https://weblate.cryptpad.org/widgets/cryptpad/-/app/multi-auto.svg) - -## Request a new language - -* New languages require some minor changes in the code which we have to apply manually. If you want to translate CryptPad into a new language, please send us an email at weblate@cryptpad.fr -* Please note that members of the current development team are only fluent in English and French, so additional languages will require ongoing contributions in order to stay up to date. - * If a language becomes too outdated, we will consider dropping it from the available language until it is fixed. - * Please refrain from asking for a new language if you are not able to provide a sufficiently translated version and maintain it or to find other users that can do so. - -## Become a reviewer - -* We need reviewers for all the languages except English and French. Their job will be to approve/reject/discuss the translations made by other contributors to this language, using the Weblate UI. -* If you want to become a reviewer for a language, please write us an email at weblate@cryptpad.fr -* Please tell us if you want to stop being a reviewer (even momentarily) so that we can find a replacement as soon as posible - -## Translate an existing language - -* All translations can be done using the Weblate UI. For better help about how to use the tool, please check the [Weblate documentation](https://docs.weblate.org/en/latest/). -* Our Weblate instance is configured to always require approval for changes. - -### Update an existing translation - -* Existing translations that have already been approved can't be changed directly. Users can only make suggestions, and the reviewers will have to approve the changes if they agree. - -### Translate a new key - -* Untranslated strings can be changed by any user and the translation can be edited by others as long as it has not been approved by a reviewer. +This tutorial is part of our documentation, you can find it in our how to contribute guide: https://docs.cryptpad.org/en/how_to_contribute.html#translate-cryptpad \ No newline at end of file From 4385a9dd5a41e658a3c9334981766c9d96b1b77a Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Fri, 8 Dec 2023 15:01:34 +0100 Subject: [PATCH 101/283] WIP --- package-lock.json | 9 ++++++--- package.json | 2 +- www/diagram/inner.js | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2807a8521..a1eed724c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+3", + "drawio": "file:../drawio-npm", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -68,6 +68,9 @@ "url": "https://opencollective.com/cryptpad" } }, + "../drawio-npm": { + "version": "21.8.2+3" + }, "node_modules/@mcrowe/minibloom": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mcrowe/minibloom/-/minibloom-0.2.0.tgz", @@ -1315,8 +1318,8 @@ } }, "node_modules/drawio": { - "version": "21.8.2+2", - "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#20bb1d9ac9ee504002fa39c44c6585b6ac7f2282" + "resolved": "../drawio-npm", + "link": true }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", diff --git a/package.json b/package.json index b076ce14d..19f583950 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+3", + "drawio": "file:../drawio-npm", "pako": "^2.1.0", "x2js": "^3.4.4" }, diff --git a/www/diagram/inner.js b/www/diagram/inner.js index 387abaa59..ce2842587 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -135,6 +135,8 @@ define([ framework.insertImage({}, (imageData) => { if (imageData.blob) { resolve(imageData.blob); + } else if (imageData.url) { + resolve(imageData.url); } else { resolve(DiagramUtil.getCryptPadUrl(imageData.src, imageData.key, imageData.fileType)); } From 3d17cbfac42659d44e257d4a290f482375e5562f Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Fri, 8 Dec 2023 22:23:39 +0100 Subject: [PATCH 102/283] changed html() to text() in button function --- www/kanban/inner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 8b41e9fa6..2a3bd4ae9 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -1051,10 +1051,10 @@ define([ if (existing.indexOf(tag.innerHTML) > 10 && kanban.options.tags.indexOf(tag.innerHTML) === -1) { if ($(tag).is(":visible")) { $(tag).hide(); - $(toggleTagsButton).html(Messages.kanban_showTags); + $(toggleTagsButton).text(Messages.kanban_showTags); } else { $(tag).show(); - $(toggleTagsButton).html(Messages.kanban_hideTags); + $(toggleTagsButton).text(Messages.kanban_hideTags); } } } From ba0a39cc1c20d6de43e2800f61d7f83cc09131c5 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 11 Dec 2023 14:35:32 +0100 Subject: [PATCH 103/283] Fix UI issues on SSO pages --- customize.dist/pages/login.js | 7 +-- customize.dist/pages/ssoauth.js | 31 ++++++------ customize.dist/src/less2/include/login.less | 50 +++++++++++++++++++ .../src/less2/pages/page-login.less | 43 +++------------- .../src/less2/pages/page-register.less | 23 ++------- .../src/less2/pages/page-ssoauth.less | 29 +++++++++-- www/login/main.js | 4 ++ www/register/main.js | 4 ++ 8 files changed, 111 insertions(+), 80 deletions(-) create mode 100644 customize.dist/src/less2/include/login.less diff --git a/customize.dist/pages/login.js b/customize.dist/pages/login.js index 9234a447f..2ae732805 100644 --- a/customize.dist/pages/login.js +++ b/customize.dist/pages/login.js @@ -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'), diff --git a/customize.dist/pages/ssoauth.js b/customize.dist/pages/ssoauth.js index 691d18470..2b6297684 100644 --- a/customize.dist/pages/ssoauth.js +++ b/customize.dist/pages/ssoauth.js @@ -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'), ]) diff --git a/customize.dist/src/less2/include/login.less b/customize.dist/src/less2/include/login.less new file mode 100644 index 000000000..a47c1aabb --- /dev/null +++ b/customize.dist/src/less2/include/login.less @@ -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; + } + } +} + diff --git a/customize.dist/src/less2/pages/page-login.less b/customize.dist/src/less2/pages/page-login.less index 655a418e5..1bf4042cd 100644 --- a/customize.dist/src/less2/pages/page-login.less +++ b/customize.dist/src/less2/pages/page-login.less @@ -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 { diff --git a/customize.dist/src/less2/pages/page-register.less b/customize.dist/src/less2/pages/page-register.less index 662a03381..481146253 100644 --- a/customize.dist/src/less2/pages/page-register.less +++ b/customize.dist/src/less2/pages/page-register.less @@ -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 { diff --git a/customize.dist/src/less2/pages/page-ssoauth.less b/customize.dist/src/less2/pages/page-ssoauth.less index a2c0e0141..64d9511db 100644 --- a/customize.dist/src/less2/pages/page-ssoauth.less +++ b/customize.dist/src/less2/pages/page-ssoauth.less @@ -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; + } } - } diff --git a/www/login/main.js b/www/login/main.js index 3986edfac..c2f2aeef7 100644 --- a/www/login/main.js +++ b/www/login/main.js @@ -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 */ diff --git a/www/register/main.js b/www/register/main.js index 174f0e8d7..302e2ebb7 100644 --- a/www/register/main.js +++ b/www/register/main.js @@ -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 () { From ac090767ca1a7db48ade899b9d2befbb3ad0b43d Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 11 Dec 2023 16:40:05 +0100 Subject: [PATCH 104/283] Add admin panel option to enforce MFA --- lib/commands/admin-rpc.js | 1 + lib/decrees.js | 3 +++ www/admin/inner.js | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 07a121909..3100194b4 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -495,6 +495,7 @@ var instanceStatus = function (Env, Server, cb) { instanceJurisdiction: Env.instanceJurisdiction, instanceName: Env.instanceName, instanceNotice: Env.instanceNotice, + enforceMFA: Env.enforceMFA, }); }; diff --git a/lib/decrees.js b/lib/decrees.js index 2e2ffd43a..1f81db056 100644 --- a/lib/decrees.js +++ b/lib/decrees.js @@ -107,6 +107,9 @@ var makeBooleanSetter = function (attr) { // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['DISABLE_EMBEDDING', [true]]], console.log) commands.ENABLE_EMBEDDING = makeBooleanSetter('enableEmbedding'); +// CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['ENFORCE_MFA', [true]]], console.log) +commands.ENFORCE_MFA = makeBooleanSetter('enforceMFA'); + // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['RESTRICT_REGISTRATION', [true]]], console.log) commands.RESTRICT_REGISTRATION = makeBooleanSetter('restrictRegistration'); diff --git a/www/admin/inner.js b/www/admin/inner.js index 8155a1164..798c1ddcd 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -63,6 +63,7 @@ define([ 'cp-admin-update-limit', 'cp-admin-registration', 'cp-admin-enableembeds', + 'cp-admin-forcemfa', 'cp-admin-email', 'cp-admin-instance-info-notice', @@ -1527,6 +1528,31 @@ Example }, }); + // Msg.admin_forcemfaHint, .admin_forcemfaTitle + Messages.admin_forcemfaTitle = "Enforce MFA on this instance"; // XXX + Messages.admin_forcemfaHint = "All CryptPad users will be asked to set up a multi-factor authenticator (TOTP) to log in to their account."; // XXX + create['forcemfa'] = makeAdminCheckbox({ + key: 'forcemfa', + getState: function () { + return APP.instanceStatus.enforceMFA; + }, + query: function (val, setState) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'ADMIN_DECREE', + data: ['ENFORCE_MFA', [val]] + }, function (e, response) { + if (e || response.error) { + UI.warn(Messages.error); + console.error(e, response); + } + APP.updateStatus(function () { + setState(APP.instanceStatus.enforceMFA); + flushCacheNotice(); + }); + }); + }, + }); + create['email'] = function () { var key = 'email'; var $div = makeBlock(key, true); // Msg.admin_emailHint, Msg.admin_emailTitle From 9d7e93691489b6b272a5bbd87233d3025897a257 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 11 Dec 2023 17:28:29 +0100 Subject: [PATCH 105/283] improvements and refactoring --- www/form/inner.js | 233 ++++++++++++++++++++++++---------------------- 1 file changed, 120 insertions(+), 113 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 1261699ef..52b688838 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -434,7 +434,11 @@ define([ // Calendar inline for "day" type var calendarInput = h('input'); calendarView = h('div', calendarInput); - var calendarDefault = new Date(); + var calendarDefault = v.type === "day" ? extractValues(v.values).map(function (time) { + if (!time) { return; } + var d = new Date(time); + if (!isNaN(d)) { return d; } + }).filter(Boolean) : undefined; Flatpickr(calendarInput, { mode: 'multiple', inline: true, @@ -527,16 +531,31 @@ define([ el = getOption(+time, false, false, Util.uid()); $add.before(el); $(el).find('input').focus(); + return; } $(add).click(); return; - } - - if (!isNaN(parseInt($container.find('input')[0].value))&& parseInt($container.find('input')[0].value).toString().length > 4) { - var dateInput = new Date(parseInt($container.find('input')[0].value)); - $container.find('input')[0].value = dateInput.toDateString(); + } else { + var selectedDates = $(calendarView).find('input')[0]._flatpickr.selectedDates; + if ($container.find('input')[0] && $container.find('input')[0]._flatpickr) { + var dateInput = new Date(+$container.find('input').value); + $container.find('input').value = dateInput.toLocaleDateString(); + } else if (selectedDates.length > 0) { + for (var i=0; i < selectedDates.length; i++ ) { + if (!$container.find('input')[i]) { + var element = getOption(selectedDates[i].toLocaleDateString(), true, false, Util.uid()); + $add.before(element); + $(element).find('input').focus(); + } else { + $container.find('input')[i].value = selectedDates[i].toLocaleDateString(); + } + } + } else if ($container.find('input')[0]) { + $container.find('input')[0].value = ''; + } } + $container.find('input').each(function (i, input) { if (input._flatpickr) { input._flatpickr.destroy(); @@ -2662,12 +2681,11 @@ define([ if (answer === false) { var cols = extractValues(opts.values).map(function (key) { if (opts.type === 'time') { - return q + ' | ' + new Date(parseInt(key)).toISOString(); - } else { - return q + ' | ' + key; + return q + ' | ' + new Date(+key).toISOString(); } + return q + ' | ' + key; + }); - cols.unshift(q); return cols; } if (!answer || !answer.values) { @@ -2675,25 +2693,18 @@ define([ empty.unshift(''); return empty; } - var str = ''; var timeValues = {}; - Object.keys(answer.values).sort().forEach(function (k, i) { - if (i !== 0) { str += ';'; } + Object.keys(answer.values).sort().forEach(function (k) { if (opts.type === 'time') { - timeValues[new Date(parseInt(k)).toISOString()] = answer.values[k]; - str += new Date(parseInt(k)).toISOString().replace(';', '').replace(':', '') + ':' + timeValues[new Date(parseInt(k)).toISOString()]; - } else { - str += k.replace(';', '').replace(':', '') + ':' + answer.values[k]; - } + timeValues[new Date(+k).toISOString()] = answer.values[k]; + } }); var res = extractValues(opts.values).map(function (key) { if (opts.type === 'time') { - return timeValues[new Date(parseInt(key)).toISOString()] || ''; - } else { - return answer.values[key] || ''; - } + return timeValues[new Date(+key).toISOString()] || ''; + } + return answer.values[key] || ''; }); - res.unshift(str); return res; }, icon: h('i.cptools.cptools-form-poll') @@ -3661,7 +3672,7 @@ define([ e.preventDefault(); if (!$el.is(':visible')) { var pages = $el.closest('.cp-form-page').index(); - if (APP.refreshPage) { APP.refreshPage(pages + 1); } + if (APP.refreshPage) { APP.refreshPage(pages, 'required'); } } $el[0].scrollIntoView(); }); @@ -4094,41 +4105,21 @@ define([ ]); $(copy).click(function() { if (!APP.isEditor) { return; } - var full = !uid; var arr = content.order; var idx = content.order.indexOf(uid); var _uid; - if (!full) { - var obj = getSectionFromQ(content, uid); - arr = obj.arr; - idx = obj.idx; - _uid = Util.uid(); - } + var obj = getSectionFromQ(content, uid); + arr = obj.arr; + idx = obj.idx; + _uid = Util.uid(); - var model = TYPES[type] || STATIC_TYPES[type]; - if (!model) { return; } - var question; - if (content.form[uid].q) { - question = content.form[uid].q; - } else { - question = Messages.form_default; - } - var options; - if (content.form[uid].opts) { - options = content.form[uid].opts; - } else { - options = Util.clone(model.defaultOpts); - } content.form[_uid] = { - q: question, - opts: options, + q: content.form[uid].q, + opts: content.form[uid].opts, type: type, }; - if (full) { - arr.push(_uid); - } else { - arr.splice(idx, 0, _uid); - } + + arr.splice(idx, 0, _uid); framework.localChange(); updateForm(framework, content, true); }); @@ -4273,6 +4264,8 @@ define([ var _content = elements; if (!editable) { _content = []; + var pgcontent = []; + var pg = []; var div = h('div.cp-form-page'); var pages = 1; var wasPage = false; @@ -4282,60 +4275,93 @@ define([ if (i === (elements.length - 1)) { return; } // Can't end with a page break if (wasPage) { return; } // Prevent double page break _content.push(div); + pgcontent.push(pg); pages++; div = h('div.cp-form-page'); + pg = []; wasPage = true; return; } + if (form[obj.uid] && form[obj.uid].type === 'section') { + return; + } + pg.push(obj); wasPage = false; $(div).append(obj); }); _content.push(div); - + pgcontent.push(pg); if (pages > 1) { - var pageContainer = h('div.cp-form-page-container'); - var $page = $(pageContainer); - _content.push(pageContainer); - var refreshPage = APP.refreshPage = function (current) { - $page.empty(); - var hiddenPages; - - var checkEmptyPages = function() { - var shownContent = []; - hiddenPages = 0; - _content.forEach(function(div) { - var hiddenQs = 0; - for (var child of div.children) { - if ($(child).attr('data-title') === 'hidden') { - hiddenQs++; - } - } - if (hiddenQs === div.children.length && $(div).attr('class') !== 'cp-form-page-container') { - div['empty'] = true; - hiddenPages ++; - } - else { - div['empty'] = false; - if ($(div).attr('class') !== 'cp-form-page-container' && shownContent.indexOf(div) === -1) { - shownContent.push(div); - } + var checkEmptyPages = function() { + getSections(content).forEach(function (uid) { + var block = content.form[uid]; + if (checkCondition(block)) { + block.opts.questions.forEach(function(uid){ + form[uid].visible = true; + }); + } else { + block.opts.questions.forEach(function(uid){ + form[uid].visible = false; + }); + } + }); + + var shownContent = []; + var shownPages = []; + pgcontent.forEach(function(page) { + var hiddenQs = 0; + page.forEach(function(q) { + if (form[$(q).attr('data-id')] && form[$(q).attr('data-id')].visible === false) { + hiddenQs++; } }); - return shownContent; - }; - var shownContent = checkEmptyPages(); - var shownPages = checkEmptyPages().length; + if (hiddenQs === page.length) { + page.empty = true; + } else { + page.empty = false; + shownContent.push(page); + shownPages.push(_content[pgcontent.indexOf(page)]); + } + }); + return [shownContent, shownPages]; + }; + var pageContainer = h('div.cp-form-page-container'); + + var $page = $(pageContainer); + _content.push(pageContainer); + var refreshPage = APP.refreshPage = function (current, direction) { + $page.empty(); if (!current || current < 1) { current = 1; } - checkEmptyPages(); + var checkPages = checkEmptyPages(); + var shownContent = checkPages[0]; + var shownPages = checkPages[1]; + var shownLength = shownContent.length; - var state = h('span', Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])); + if (pgcontent[(current - 1)] && pgcontent[current-1].empty) { + if (direction === 'next') { + current++; + while (pgcontent[current-1].empty) { + current++; + } + } else if (direction === 'prev') { + current--; + while (pgcontent[current-1].empty) { + current--; + } + } else if (direction === 'required') { + current = shownContent.indexOf(_content[current]); + } + } + + var state = h('span', Messages._getKey('form_page', [shownPages.indexOf(_content[current-1])+1, shownLength])); evOnChange.reg(function(){ - checkEmptyPages(); - shownContent = checkEmptyPages(); - shownPages = checkEmptyPages().length; - $(state).html(Messages._getKey('form_page', [shownContent.indexOf(_content[current-1])+1, shownPages])); + var checkPages = checkEmptyPages(); + var shownContent = checkPages[0]; + var shownPages = checkPages[1]; + var shownLength = shownContent.length; + $(state).text(Messages._getKey('form_page', [shownPages.indexOf(_content[current-1])+1, shownLength])); }); var left = h('button.btn.btn-secondary.cp-prev', [ h('i.fa.fa-arrow-left'), @@ -4343,32 +4369,18 @@ define([ var right = h('button.btn.btn-secondary.cp-next', [ h('i.fa.fa-arrow-right'), ]); - if (current === pages) { $(right).css('visibility', 'hidden'); } + + if (shownPages.indexOf(_content[current-1])+1 === shownContent.length) { $(right).css('visibility', 'hidden'); } if (current === 1) { $(left).css('visibility', 'hidden'); } $(left).click(function () { - checkEmptyPages(); - var prevPage = -1; - if (_content[current+prevPage-1]['empty']) { - prevPage--; - while (_content[current+prevPage-1]['empty']) { - prevPage --; - } - } - refreshPage(current + prevPage); + refreshPage(current - 1, 'prev'); }); $(right).click(function () { - checkEmptyPages(); - var nextPage = 1; - if (_content[current]['empty']) { - nextPage++; - while (_content[(current+nextPage)-1]['empty']) { - nextPage ++; - } - } - refreshPage(current + nextPage); + refreshPage(current + 1, 'next'); }); $page.append([left, state, right]); + $container.find('.cp-form-page').hide(); $($container.find('.cp-form-page').get(current-1)).show(); if (current !== pages) { @@ -4524,11 +4536,6 @@ define([ var show = checkCondition(block); block.opts.questions.forEach(function (_uid) { $container.find('.cp-form-block[data-id="'+_uid+'"]').toggle(show); - if (!show) { - $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'hidden'); - } else { - $container.find('.cp-form-block[data-id="'+_uid+'"]').attr('data-title', 'visible'); - } }); }); }); From c11f946379c1cc502aa36db3d655b8450650a053 Mon Sep 17 00:00:00 2001 From: Fabrice Mouhartem Date: Tue, 12 Dec 2023 10:55:45 +0100 Subject: [PATCH 106/283] Code cleanup Remove `XXX` comments related to PRs #1308 and #1312 --- www/calendar/inner.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index fbd56ce07..c92b4d966 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -1012,13 +1012,12 @@ ICS ==> create a new event with the same UID and a RECURRENCE-ID field (with a v makeLeftside(cal, $(leftside)); cal.on('beforeCreateSchedule', function(event) { - event.recurrenceRule = APP.recurrenceRule; // XXX Not sure about the consistency of data structures + event.recurrenceRule = APP.recurrenceRule; newEvent(event, function (err) { if (err) { console.error(err); return void UI.warn(err); } - //cal.createSchedules([schedule]); XXX Remove these occurrences elsewhere }); }); cal.on('beforeUpdateSchedule', function(event) { @@ -1127,7 +1126,6 @@ ICS ==> create a new event with the same UID and a RECURRENCE-ID field (with a v console.error(err); return void UI.warn(err); } - //cal.updateSchedule(old.id, old.calendarId, changes); }); } }; From 03eda4f9cf64ec1e9cef129932ba4bd2f930b7b5 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Tue, 12 Dec 2023 15:17:05 +0100 Subject: [PATCH 107/283] further refactoring --- www/form/inner.js | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 52b688838..6c3944e53 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2694,11 +2694,6 @@ define([ return empty; } var timeValues = {}; - Object.keys(answer.values).sort().forEach(function (k) { - if (opts.type === 'time') { - timeValues[new Date(+k).toISOString()] = answer.values[k]; - } - }); var res = extractValues(opts.values).map(function (key) { if (opts.type === 'time') { return timeValues[new Date(+key).toISOString()] || ''; @@ -4295,30 +4290,21 @@ define([ var checkEmptyPages = function() { getSections(content).forEach(function (uid) { var block = content.form[uid]; - if (checkCondition(block)) { - block.opts.questions.forEach(function(uid){ - form[uid].visible = true; - }); - } else { - block.opts.questions.forEach(function(uid){ - form[uid].visible = false; - }); - } + var condition = Boolean(checkCondition(block)); + block.opts.questions.forEach(function(uid){ + form[uid].visible = condition; + }); }); + var shownContent = []; var shownPages = []; pgcontent.forEach(function(page) { - var hiddenQs = 0; - page.forEach(function(q) { - if (form[$(q).attr('data-id')] && form[$(q).attr('data-id')].visible === false) { - hiddenQs++; - } + var visible = page.some(function(q) { + return form[$(q).attr('data-id')] && form[$(q).attr('data-id')].visible !== false; }); - if (hiddenQs === page.length) { - page.empty = true; - } else { - page.empty = false; + page.empty = !visible; + if (visible) { shownContent.push(page); shownPages.push(_content[pgcontent.indexOf(page)]); } From 4361176b51b887869025a20bc240f667f1abf93d Mon Sep 17 00:00:00 2001 From: David Benque Date: Tue, 12 Dec 2023 15:14:24 +0000 Subject: [PATCH 108/283] Rename translation key --- www/form/inner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 6c3944e53..b1b968cfe 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -75,7 +75,7 @@ define([ Sortable ) { - Messages.form_copyQuestion = 'Duplicate'; //XXX + Messages.duplicate = 'Duplicate'; // XXX var APP = window.APP = { blocks: {} @@ -4096,7 +4096,7 @@ define([ ]); var copy = h('button.btn.btn-default.cp-form-copy-button', [ h('i.fa.fa-copy'), - h('span', Messages.form_copyQuestion) + h('span', Messages.duplicate) ]); $(copy).click(function() { if (!APP.isEditor) { return; } From 641f224c71b405225273db19168fcd15198ddd63 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 12 Dec 2023 17:04:01 +0100 Subject: [PATCH 109/283] Fix lost functions in Env in HTTP workers --- lib/http-worker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/http-worker.js b/lib/http-worker.js index 143f41b85..1ed0157a5 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -70,6 +70,7 @@ EVENTS.ENV_UPDATE = function (data /*, cb */) { try { Env = JSON.parse(data); Env.Log = Log; + Env.plugins = plugins; Env.incrementBytesWritten = function () {}; } catch (err) { Log.error('HTTP_WORKER_ENV_UPDATE', Util.serializeError(err)); From 906cd1cb15495ce72fe17571522c967f0583884f Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 13 Dec 2023 14:59:38 +0100 Subject: [PATCH 110/283] Fix margin issues with kanban tags --- www/kanban/app-kanban.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/www/kanban/app-kanban.less b/www/kanban/app-kanban.less index 70dd7facf..8d50f1e91 100644 --- a/www/kanban/app-kanban.less +++ b/www/kanban/app-kanban.less @@ -437,6 +437,9 @@ .cp-kanban-filterTags { @media (min-width: 505px) { display: inline-flex; + .kanban-tag-btn-toggle { + margin-right: 10px; + } } align-items: center; flex: 1; @@ -477,9 +480,6 @@ .cp-kanban-filterTags-list { margin-right: 10px; margin-left: 10px; - @media (max-width: 405px) { - padding-top: 15px - } display: flex; flex-wrap: wrap; &:not(.cp-empty) { From 0fb82aa688e7e14f0da970ac22b0d47b73b171d6 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 13 Dec 2023 15:02:28 +0100 Subject: [PATCH 111/283] Fix XXX comment --- www/kanban/inner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 2a3bd4ae9..5df509f81 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -56,8 +56,8 @@ define([ jKanban, Export) { - Messages.kanban_showTags = 'See all tags'; //XX - Messages.kanban_hideTags = 'See less tags'; //XX + Messages.kanban_showTags = 'See all tags'; // XXX + Messages.kanban_hideTags = 'See less tags'; // XXX var verbose = function (x) { console.log(x); }; verbose = function () {}; // comment out to enable verbose logging From 36e4837d086a3d9ad68d0b59399fa8162fdf3ce7 Mon Sep 17 00:00:00 2001 From: DianaXWiki Date: Wed, 13 Dec 2023 17:00:18 +0200 Subject: [PATCH 112/283] Fix toolbar keyboard nav linux #1272 --- www/pad/csp.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/www/pad/csp.js b/www/pad/csp.js index 2f27855fc..8504f3362 100644 --- a/www/pad/csp.js +++ b/www/pad/csp.js @@ -32,6 +32,15 @@ define(['jquery'], function ($) { } $el.on('keydown blur focus click dragstart', function (e) { //e.preventDefault(); + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + var focusedButton = document.activeElement; + + // Simulate a click event on the focused button + if (focusedButton) { + focusedButton.click(); + } + } var attr = $(el).attr('oon'+e.type); if (!attr) { return; } if (['blur', 'dragstart'].indexOf(e.type) !== -1) { return false; } @@ -45,7 +54,7 @@ define(['jquery'], function ($) { $iframe.scrollTop(s); }); }); - + // Dropdown menus @@ -104,7 +113,7 @@ define(['jquery'], function ($) { that.onLoad(); } }).contents().find('body').on('click dragstart mouseover mouseout', '.cke_button, a.cke_colormore, a.cke_colorbox, .cke_colorauto, .cke_combo_button, .cke_panel_listItem a, a.cke_menubutton', function (e) { - e.preventDefault(); + //e.preventDefault(); if (e.type === 'dragstart') { return false; } var attr = $(e.currentTarget).attr('oon'+e.type); if (!attr) { return; } From 45ac8d901f32a9259d609d24b04ab11026361641 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 13 Dec 2023 16:27:20 +0100 Subject: [PATCH 113/283] Remove CSP warnings in the console with CkEditor toolbar --- www/pad/csp.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/pad/csp.js b/www/pad/csp.js index 8504f3362..b7c54a264 100644 --- a/www/pad/csp.js +++ b/www/pad/csp.js @@ -31,7 +31,7 @@ define(['jquery'], function ($) { } catch (e) { console.error(e); } } $el.on('keydown blur focus click dragstart', function (e) { - //e.preventDefault(); + if (e.key !== 'Tab') { e.preventDefault(); } if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); var focusedButton = document.activeElement; @@ -113,7 +113,7 @@ define(['jquery'], function ($) { that.onLoad(); } }).contents().find('body').on('click dragstart mouseover mouseout', '.cke_button, a.cke_colormore, a.cke_colorbox, .cke_colorauto, .cke_combo_button, .cke_panel_listItem a, a.cke_menubutton', function (e) { - //e.preventDefault(); + e.preventDefault(); if (e.type === 'dragstart') { return false; } var attr = $(e.currentTarget).attr('oon'+e.type); if (!attr) { return; } From 7c6477979674b5cf872df5812501179a44110ace Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 13 Dec 2023 16:32:00 +0100 Subject: [PATCH 114/283] lint compliance --- customize.dist/src/less2/include/modals-ui-elements.less | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/customize.dist/src/less2/include/modals-ui-elements.less b/customize.dist/src/less2/include/modals-ui-elements.less index 4e9850180..1880100ce 100644 --- a/customize.dist/src/less2/include/modals-ui-elements.less +++ b/customize.dist/src/less2/include/modals-ui-elements.less @@ -64,10 +64,10 @@ } .cp-password-container { flex-wrap: wrap; - gap:0.5rem; + gap: 0.5rem; - justify-content:flex-start; - input { + justify-content: flex-start; + input { flex-shrink: 1; max-width: 400px; } From d29f0f4221d398d56fae576c303103a8df779688 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 13 Dec 2023 18:59:23 +0100 Subject: [PATCH 115/283] removed redundant code --- www/form/inner.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index b1b968cfe..09794d20f 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2684,7 +2684,6 @@ define([ return q + ' | ' + new Date(+key).toISOString(); } return q + ' | ' + key; - }); return cols; } @@ -2693,11 +2692,7 @@ define([ empty.unshift(''); return empty; } - var timeValues = {}; var res = extractValues(opts.values).map(function (key) { - if (opts.type === 'time') { - return timeValues[new Date(+key).toISOString()] || ''; - } return answer.values[key] || ''; }); return res; From 1c77d0699f414496c67405a2f7b2dcb4203c764b Mon Sep 17 00:00:00 2001 From: David Benque Date: Thu, 14 Dec 2023 10:44:23 +0000 Subject: [PATCH 116/283] Remove hard-coded translation strings --- customize.dist/pages/login.js | 1 - customize.dist/pages/register.js | 1 - customize.dist/pages/ssoauth.js | 5 ----- www/admin/inner.js | 2 -- www/calendar/inner.js | 5 ----- www/common/common-ui-elements.js | 1 - www/form/inner.js | 1 - www/kanban/inner.js | 2 -- 8 files changed, 18 deletions(-) diff --git a/customize.dist/pages/login.js b/customize.dist/pages/login.js index 01760a616..269584d04 100644 --- a/customize.dist/pages/login.js +++ b/customize.dist/pages/login.js @@ -14,7 +14,6 @@ define([ var ssoEnabled = (Config.sso && Config.sso.list && Config.sso.list.length) ?'': '.cp-hidden'; var ssoEnforced = (Config.sso && Config.sso.force) ? '.cp-hidden' : ''; - Msg.sso_login_description = "Login from SSO...."; // XXX return [h('div#cp-main', [ Pages.infopageTopbar(), diff --git a/customize.dist/pages/register.js b/customize.dist/pages/register.js index 403d4e737..82cfc9a7c 100644 --- a/customize.dist/pages/register.js +++ b/customize.dist/pages/register.js @@ -16,7 +16,6 @@ define([ var ssoEnabled = (Config.sso && Config.sso.list && Config.sso.list.length) ?'': '.cp-hidden'; var ssoEnforced = (Config.sso && Config.sso.force) ? '.cp-hidden' : ''; - Msg.sso_register_description = "Register from SSO...."; // XXX var termsLink = Pages.customURLs.terms; $(tos).find('a').attr({ diff --git a/customize.dist/pages/ssoauth.js b/customize.dist/pages/ssoauth.js index 2b6297684..a2975ee76 100644 --- a/customize.dist/pages/ssoauth.js +++ b/customize.dist/pages/ssoauth.js @@ -7,11 +7,6 @@ define([ '/customize/pages.js' ], function (Config, $, h, UI, Msg, Pages) { - Msg.ssoauth_header = "SSO authentication"; // XXX - Msg.ssoauth_form_hint_register = "Add a CryptPad password for extra security or leave empty and continue"; - Msg.ssoauth_form_hint_login = "Please enter your CryptPad password"; - Msg.continue = "Continue"; - return function () { document.title = Msg.ssoauth_header; diff --git a/www/admin/inner.js b/www/admin/inner.js index de61e3274..0afa3d156 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -1529,8 +1529,6 @@ Example }); // Msg.admin_forcemfaHint, .admin_forcemfaTitle - Messages.admin_forcemfaTitle = "Enforce MFA on this instance"; // XXX - Messages.admin_forcemfaHint = "All CryptPad users will be asked to set up a multi-factor authenticator (TOTP) to log in to their account."; // XXX create['forcemfa'] = makeAdminCheckbox({ key: 'forcemfa', getState: function () { diff --git a/www/calendar/inner.js b/www/calendar/inner.js index f10ad359d..f19879091 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -72,11 +72,6 @@ define([ CodeMirror ) { - // XXX New translation keys - Messages.calendar_rec_change_first = "You moved the first repeating event to different calendar. You can only apply this change to all repeated events."; // XXX New translation key - Messages.calendar_rec_change = "You moved a repeating event to different calendar. You can only apply this change to this event or all repeated events."; // XXX New translation key - Messages.calendar_desc = "Description"; // XXX maybe rename in `description`? - delete Messages.calendar_location; // XXX Remove Messages.calendar_location from translation keys as it is not used anymore? var SaveAs = window.saveAs; var APP = window.APP = { diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 58a7b8858..e643f6add 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -4176,7 +4176,6 @@ define([ modal = UI.openCustomModal(UI.dialog.customModal(content, {buttons: buttons })); }; - Messages.loading_mfa_required = "Multi-factor Authentication is required on this instance. Please update your account using an anthenticator app and the form below."; // XXX UIElements.onMissingMFA = (common, config, cb) => { let content = h('div'); let msg = h('div.cp-loading-missing-mfa', [ diff --git a/www/form/inner.js b/www/form/inner.js index 971ab646c..5cd9e1449 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -81,7 +81,6 @@ define([ Sortable ) { - Messages.duplicate = 'Duplicate'; // XXX var APP = window.APP = { blocks: {} diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 5df509f81..302b099dd 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -56,8 +56,6 @@ define([ jKanban, Export) { - Messages.kanban_showTags = 'See all tags'; // XXX - Messages.kanban_hideTags = 'See less tags'; // XXX var verbose = function (x) { console.log(x); }; verbose = function () {}; // comment out to enable verbose logging From 32494461b4020a1596ba339979c31b0fc8ad5b33 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 14 Dec 2023 11:47:14 +0100 Subject: [PATCH 117/283] Fix double 'Open' entry in drive tree contextmenu --- www/common/drive-ui.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 001c09a89..6bd2699bf 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -4357,7 +4357,10 @@ define([ if (collapsable) { $collapse = $expandIcon.clone().attr('tabindex', 0); } - var $elementRow = $('', {'class': 'cp-app-drive-element-row', 'tabindex': 0}).append($collapse).append($icon).append($name).on('click keypress', function (e) { + var $elementRow = $('', { + 'class': 'cp-app-drive-element-row cp-app-drive-element-folder', + 'tabindex': 0 + }).append($collapse).append($icon).append($name).on('click keypress', function (e) { if (e.type === 'keypress' && e.which !== 13) { return; } From 7f596b6776e21a0bda12fad46c72535aa8dda3ee Mon Sep 17 00:00:00 2001 From: David Benque Date: Thu, 14 Dec 2023 10:53:10 +0000 Subject: [PATCH 118/283] Fix focus styles in toolbar --- customize.dist/src/less2/include/toolbar.less | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/customize.dist/src/less2/include/toolbar.less b/customize.dist/src/less2/include/toolbar.less index 73fc6fad9..32c6d733d 100644 --- a/customize.dist/src/less2/include/toolbar.less +++ b/customize.dist/src/less2/include/toolbar.less @@ -367,9 +367,8 @@ * { outline-width: 0; &:focus { - outline-width: 1rem; // color shows on chrome/edge, but not firefox - outline-color: grey; // XXX temporary color to change + outline-color: @cryptpad_color_brand; } } From b0ce8fc5ab336666588cdb20abcc196f69db455c Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 14 Dec 2023 11:43:12 +0100 Subject: [PATCH 119/283] Translated using Weblate (English) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1682 of 1682 strings) Translated using Weblate (English) Currently translated at 100.0% (1682 of 1682 strings) Translated using Weblate (English) Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (English) Currently translated at 100.0% (1680 of 1680 strings) Translated using Weblate (English) Currently translated at 100.0% (1679 of 1679 strings) Translated using Weblate (English) Currently translated at 100.0% (1678 of 1678 strings) Translated using Weblate (English) Currently translated at 100.0% (1677 of 1677 strings) Translated using Weblate (English) Currently translated at 100.0% (1676 of 1676 strings) Translated using Weblate (English) Currently translated at 100.0% (1676 of 1676 strings) Translated using Weblate (English) Currently translated at 100.0% (1675 of 1675 strings) Translated using Weblate (English) Currently translated at 100.0% (1674 of 1674 strings) Translated using Weblate (English) Currently translated at 100.0% (1673 of 1673 strings) Translated using Weblate (English) Currently translated at 100.0% (1672 of 1672 strings) Translated using Weblate (English) Currently translated at 100.0% (1671 of 1671 strings) Translated using Weblate (English) Currently translated at 100.0% (1670 of 1670 strings) Translated using Weblate (English) Currently translated at 100.0% (1669 of 1669 strings) Translated using Weblate (English) Currently translated at 100.0% (1668 of 1668 strings) Co-authored-by: Anonymous Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/en/ Translation: CryptPad/App --- www/common/translations/messages.json | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index b31c27a11..cc8e5999b 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1667,5 +1667,20 @@ "dph_tmp_pw": "This template is protected with a new password. Open it from your drive to enter the new password.", "access_passwordUsed": "This password has already been used for this document. It cannot be used again.", "status": "Status page", - "admin_diskUsageWarning": "Use with caution! Depending on the size of the data stored on the instance, generating this report can consume all the memory available on the server and lead to a crash." + "admin_diskUsageWarning": "Use with caution! Depending on the size of the data stored on the instance, generating this report can consume all the memory available on the server and lead to a crash.", + "calendar_rec_change_first": "Moving the first repeating even to a different calendar. All repeated events will also be moved.", + "calendar_rec_change": "Moving a repeating even to a different calendar. You can only apply this change to this event or all repeated events.", + "calendar_desc": "Description", + "calendar_description": "Description:{0}{1}", + "sso_login_description": "Login with", + "sso_register_description": "Register with", + "ssoauth_header": "CryptPad Password", + "ssoauth_form_hint_register": "Add a CryptPad password for extra security or leave empty and continue. If you do not add a password, the keys protecting your data will be available to the instance administrators.", + "ssoauth_form_hint_login": "Please enter your CryptPad password", + "duplicate": "Duplicate", + "kanban_showTags": "See all tags", + "kanban_hideTags": "See less tags", + "admin_forcemfaTitle": "Mandatory Two-Factor Authentication", + "admin_forcemfaHint": "All users on this instance will be asked to set up two-factor authentication to log in to their account.", + "loading_mfa_required": "Two-factor authentication is required on this instance. Please update your account using an authenticator app and the form below." } From ef7c0ac6faf431d1595043ca7bd2e7fca59a4805 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 14 Dec 2023 11:43:13 +0100 Subject: [PATCH 120/283] Translated using Weblate (French) Currently translated at 100.0% (1679 of 1679 strings) Translated using Weblate (French) Currently translated at 100.0% (1676 of 1676 strings) Co-authored-by: Mathilde Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/fr/ Translation: CryptPad/App --- www/common/translations/messages.fr.json | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 1db9a298c..5fcd1e670 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1037,7 +1037,7 @@ "documentID": "Référence du document", "unableToDisplay": "Impossible d'afficher le document. Veuillez recharger la page avec la touche Échap. Si le problème persiste, veuillez contacter le support.", "errorPopupBlocked": "CryptPad doit pouvoir ouvrir de nouveaux onglets pour fonctionner. Veuillez autoriser les fenêtres pop-up dans la barre d'adresse de votre navigateur. Ces fenêtres ne seront jamais utilisées pour vous montrer de la publicité.", - "settings_mediatagSizeHint": "Taille maximale en mégaoctets (Mo) pour le chargement automatique des pièces jointes (images, vidéos, PDF) intégrés dans les documents. Les pièces jointes dont la taille est supérieure à la taille spécifiée peuvent être chargées manuellement. Utilisez \"-1\" pour toujours charger automatiquement les pièces jointes.", + "settings_mediatagSizeHint": "Taille maximale en mégaoctets (Mo) pour le chargement automatique des pièces jointes (images, vidéos, PDF) intégrées dans les documents. Les pièces jointes dont la taille est supérieure à la taille spécifiée peuvent être chargées manuellement. Utilisez \"-1\" pour toujours charger automatiquement les pièces jointes.", "settings_mediatagSizeTitle": "Limite de téléchargement automatique", "mediatag_notReady": "Merci de compléter le téléchargement", "pad_mediatagOpen": "Ouvrir ce fichier", @@ -1203,14 +1203,14 @@ "admin_blockDailyCheckTitle": "Télémétrie du serveur", "admin_removeDonateButtonLabel": "Ne pas promouvoir la campagnes de financement", "admin_removeDonateButtonHint": "Le développement de CryptPad est partiellement financé par des bourses et des dons publics. Faire de la publicité pour notre campagne de financement sur votre instance aide l'équipe de développement à continuer son travail. Vous pouvez désactiver ces notifications.", - "admin_removeDonateButtonTitle": "Participation au financement participatif", + "admin_removeDonateButtonTitle": "Financement participatif", "admin_consentToContactLabel": "Je consens", "admin_listMyInstanceTitle": "Lister mon instance dans les répertoires publics", "admin_listMyInstanceHint": "Si votre instance est destinée à un usage public, vous pouvez la répertorier dans les listes d'instances. La télémétrie du serveur doit être activée pour que cela ait un effet.", "admin_listMyInstanceLabel": "Lister cette instance", "admin_consentToContactHint": "La télémétrie du serveur comprend l'adresse e-mail de l'administrateur·ice afin que l'équipe de développement puisse vous informer de problèmes sérieux avec le logiciel ou votre configuration. Elle ne sera jamais partagée, vendue ou utilisée à des fins de marketing. Consentez à être contacté·e si vous souhaitez être informé·e des problèmes critiques concernant votre serveur.", "admin_consentToContactTitle": "Consentement à la prise de contact", - "admin_checkupButton": "Exécuter les diagnostics", + "admin_checkupButton": "Exécuter les diagnostiques", "admin_updateAvailableTitle": "Nouvelles versions", "admin_updateAvailableHint": "Une nouvelle version de CryptPad est disponible", "admin_checkupHint": "CryptPad est doté d'une page qui diagnostique automatiquement les problèmes de configuration courants et suggère comment les corriger si nécessaire.", @@ -1476,8 +1476,8 @@ "admin_storageUsage": "Données stockées", "admin_channelCount": "Nombre de documents", "admin_fileCount": "Nombre de fichiers", - "admin_pinLogAvailable": "Liste des documents est disponible", - "admin_pinLogArchived": "Liste des documents est archivée", + "admin_pinLogAvailable": "La liste des documents est disponible", + "admin_pinLogArchived": "La liste des documents est archivée", "admin_blockKey": "Clé publique de bloc", "admin_blockAvailable": "Le bloc est disponible", "admin_blockArchived": "Le bloc est archivé", @@ -1667,5 +1667,17 @@ "admin_archiveAccountConfirm": "Veuillez spécifier la raison de l'archivage, ce sera affiché à l'utilisateur·ice.", "access_passwordUsed": "Ce mot de passe a déjà été utilisé pour ce document. Il ne peut pas être réutilisé.", "admin_diskUsageWarning": "Utiliser avec prudence ! Suivant la taille du volume de données stockées sur l'instance, générer ce rapport peut consommer toute la mémoire disponible sur le serveur et causer un crash.", - "status": "Page de statut" + "status": "Page de statut", + "calendar_rec_change_first": "Déplacer le premier événement répété vers un autre calendrier. Tous les autres événements seront aussi déplacés.", + "calendar_desc": "Description", + "sso_register_description": "S'enregistrer avec", + "calendar_description": "Description:{0}{1}", + "ssoauth_header": "Mot de passe CryptPad", + "ssoauth_form_hint_login": "Veuillez entrer votre mot de passe CryptPad", + "ssoauth_form_hint_register": "Ajouter un mot de passe CryptPad pour plus de sécurité ou laisser vide et continuer. Si vous n'ajoutez pas de mot de passe, les clés protégeant vos données seront accessibles aux administrateur·ices de l'instance.", + "calendar_rec_change": "Déplacer un événement répété vers un autre calendrier. Vous pouvez appliquer ce changement seulement pour cet événement ou pour tous les événements répétés.", + "sso_login_description": "Se connecter avec", + "duplicate": "Dupliquer", + "kanban_showTags": "Voir toutes les étiquettes", + "kanban_hideTags": "Voir moins d'étiquettes" } From f01f92b17798991384aa18b3b7470557b1bd3d84 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 14 Dec 2023 11:43:13 +0100 Subject: [PATCH 121/283] Added translation using Weblate (Chinese (Traditional)) Co-authored-by: Mathilde Co-authored-by: Weblate --- www/common/translations/messages.zh_Hant.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 www/common/translations/messages.zh_Hant.json diff --git a/www/common/translations/messages.zh_Hant.json b/www/common/translations/messages.zh_Hant.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/www/common/translations/messages.zh_Hant.json @@ -0,0 +1 @@ +{} From e100f74505438384a26b9a1c8ad3ff041a2ddaab Mon Sep 17 00:00:00 2001 From: David Benque Date: Thu, 14 Dec 2023 11:12:09 +0000 Subject: [PATCH 122/283] Remove un-used translation --- www/common/translations/messages.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index cc8e5999b..107cf2990 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1162,7 +1162,6 @@ "calendar_update": "Update", "calendar_title": "Title", "calendar_loc": "Location", - "calendar_location": "Location: {0}", "calendar_allDay": "All day", "calendar_minutes": "Minutes", "calendar_hours": "Hours", From 124788c4123b216eb6f540f0ca250a1569b07d67 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 15 Dec 2023 15:14:31 +0100 Subject: [PATCH 123/283] Fix keyboard shortcuts in lightbox view --- www/common/common-interface.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 19e94d5a7..8b30901b5 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -573,7 +573,9 @@ define([ if (!$blockContainer || !$blockContainer.length) { var id = ''; if (cfg.id) { id = '#'+cfg.id; } - $blockContainer = $(h('div.cp-modal-container'+id, {})); + $blockContainer = $(h('div.cp-modal-container'+id, { + tabindex: 1 + })); } var deleted = false; var hide = function () { From 9cd86d03a439276ec2b892701d102fb8a0498315 Mon Sep 17 00:00:00 2001 From: David Benque Date: Fri, 15 Dec 2023 15:38:01 +0100 Subject: [PATCH 124/283] REUSE lint compliance --- .reuse/dep5 | 4 ++++ config/sso.example.js | 4 ++++ customize.dist/pages/ssoauth.js | 4 ++++ customize.dist/src/less2/include/drive.less | 6 ++++++ customize.dist/src/less2/include/login.less | 6 ++++++ customize.dist/src/less2/pages/page-ssoauth.less | 6 ++++++ lib/plugin-manager.js | 4 ++++ lib/storage/sso.js | 4 ++++ www/common/common-login.js | 4 ++++ www/common/inner/mfa.js | 4 ++++ www/ssoauth/index.html | 6 ++++++ www/ssoauth/main.js | 4 ++++ 12 files changed, 56 insertions(+) diff --git a/.reuse/dep5 b/.reuse/dep5 index 3cd24fec4..f69423e84 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -39,6 +39,10 @@ Files: www/lib/mermaid/* Copyright: (c) 2014 - 2021 Knut Sveidqvist License: MIT +Files: www/lib/calendar/moment.min.js +Copyright: (c) JS Foundation and other contributors +License: MIT + Files: www/lib/pdfjs/* Copyright: 2017 Mozilla Foundation License: Apache-2.0 diff --git a/config/sso.example.js b/config/sso.example.js index 35d1f2b98..3b6a73723 100644 --- a/config/sso.example.js +++ b/config/sso.example.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + module.exports = { // Enable SSO login on this instance enabled: false, diff --git a/customize.dist/pages/ssoauth.js b/customize.dist/pages/ssoauth.js index a2975ee76..f6472f6eb 100644 --- a/customize.dist/pages/ssoauth.js +++ b/customize.dist/pages/ssoauth.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + define([ '/api/config', 'jquery', diff --git a/customize.dist/src/less2/include/drive.less b/customize.dist/src/less2/include/drive.less index 93ee7a273..c76a71528 100644 --- a/customize.dist/src/less2/include/drive.less +++ b/customize.dist/src/less2/include/drive.less @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + @import (reference) "./browser.less"; @import (reference) './leftside-menu.less'; @import (reference) "./tools.less"; diff --git a/customize.dist/src/less2/include/login.less b/customize.dist/src/less2/include/login.less index a47c1aabb..ae69361c7 100644 --- a/customize.dist/src/less2/include/login.less +++ b/customize.dist/src/less2/include/login.less @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + @import (reference) "../include/infopages.less"; @import (reference) "../include/colortheme-all.less"; @import (reference) "../include/alertify.less"; diff --git a/customize.dist/src/less2/pages/page-ssoauth.less b/customize.dist/src/less2/pages/page-ssoauth.less index 64d9511db..86ce10c15 100644 --- a/customize.dist/src/less2/pages/page-ssoauth.less +++ b/customize.dist/src/less2/pages/page-ssoauth.less @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors + * + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + @import (reference) "../include/infopages.less"; @import (reference) "../include/colortheme-all.less"; @import (reference) "../include/alertify.less"; diff --git a/lib/plugin-manager.js b/lib/plugin-manager.js index 5326fb3f9..e9d783ebc 100644 --- a/lib/plugin-manager.js +++ b/lib/plugin-manager.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + const fs = require('node:fs'); const plugins = {}; diff --git a/lib/storage/sso.js b/lib/storage/sso.js index e2ee8360f..ba9de3b6a 100644 --- a/lib/storage/sso.js +++ b/lib/storage/sso.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + const Basic = require("./basic"); const Path = require("node:path"); const Util = require("../common-util"); diff --git a/www/common/common-login.js b/www/common/common-login.js index fede6b609..d3ac6ebcd 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + define([ 'chainpad-listmap', '/components/chainpad-crypto/crypto.js', diff --git a/www/common/inner/mfa.js b/www/common/inner/mfa.js index 0f4fdbba5..8488f9445 100644 --- a/www/common/inner/mfa.js +++ b/www/common/inner/mfa.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + define([ 'jquery', '/customize/messages.js', diff --git a/www/ssoauth/index.html b/www/ssoauth/index.html index 71677f72b..089ac00b1 100644 --- a/www/ssoauth/index.html +++ b/www/ssoauth/index.html @@ -1,3 +1,9 @@ + + diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index c5b3e1d7e..a32f6bad2 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + define([ '/api/config', 'jquery', From 576e713d708de644e9bfcb383ab0b46f610137d4 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 15 Dec 2023 15:39:12 +0100 Subject: [PATCH 125/283] Add plugins directory --- .gitignore | 3 ++- lib/plugins/README.md | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 lib/plugins/README.md diff --git a/.gitignore b/.gitignore index 502910314..d5767ab7e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ customization .*.swp *.db /customize/ -/lib/plugins customize messages.log .DS_Store @@ -29,3 +28,5 @@ logs/ privileged.conf config/config.js config/sso.js +lib/plugins/* +!lib/plugins/README.md diff --git a/lib/plugins/README.md b/lib/plugins/README.md new file mode 100644 index 000000000..70e448011 --- /dev/null +++ b/lib/plugins/README.md @@ -0,0 +1 @@ +# CryptPad's plugins directory From 01de1b9f47e48ce186cc5efab233d76e83262ba7 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 15 Dec 2023 16:06:25 +0100 Subject: [PATCH 126/283] Update sso example conf --- config/sso.example.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config/sso.example.js b/config/sso.example.js index 35d1f2b98..750ebcf40 100644 --- a/config/sso.example.js +++ b/config/sso.example.js @@ -1,3 +1,4 @@ +const fs = require('node:fs'); module.exports = { // Enable SSO login on this instance enabled: false, @@ -5,6 +6,8 @@ module.exports = { enforced: false, // Allow users to add an additional CryptPad password to their SSO account cpPassword: false, + // You can also force your SSO users to add a CryptPad password + forceCpPassword: false, // List of SSO providers list: [ /* @@ -15,6 +18,14 @@ module.exports = { client_id: "{your_client_id}", client_secret: "{your_client_secret}", jwt_alg: 'RS256' (optional) + }, { + name: 'samltest', + type: 'saml', + url: 'https://samltest.id/idp/profile/SAML2/Redirect/SSO', + issuer: 'your-cryptpad-issuer-id', + cert: String or fs.readFileSync("./your/cert/location", "utf-8"), + privateKey: fs.readFileSync("./your/private/key/location", "utf-8"), + signingCert: fs.readFileSync("./your/signing/cert/location", "utf-8"), } */ ] From 461d276d162c45b68807c5ba1aa5aba6a8e48538 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 15 Dec 2023 17:10:21 +0100 Subject: [PATCH 127/283] Fix SSO+MFA issues --- config/sso.example.js | 2 +- www/common/inner/mfa.js | 12 +- www/settings/inner.js | 298 ---------------------------------------- 3 files changed, 11 insertions(+), 301 deletions(-) diff --git a/config/sso.example.js b/config/sso.example.js index 20037c20b..1393967d7 100644 --- a/config/sso.example.js +++ b/config/sso.example.js @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -const fs = require('node:fs'); +//const fs = require('node:fs'); module.exports = { // Enable SSO login on this instance enabled: false, diff --git a/www/common/inner/mfa.js b/www/common/inner/mfa.js index 8488f9445..3c576779a 100644 --- a/www/common/inner/mfa.js +++ b/www/common/inner/mfa.js @@ -58,13 +58,21 @@ define([ $(pwInput).prop('disabled', 'disabled'); $mfaRevokeBtn.prop('disabled', 'disabled'); var blockKeys; + var ssoSeed; nThen(function (waitFor) { + sframeChan.query("Q_SETTINGS_GET_SSO_SEED", { + }, waitFor(function (err, obj) { + if (!obj || !obj.seed) { return; } // Not an sso account? + ssoSeed = obj.seed; + })); + }).nThen(function (waitFor) { var next = waitFor(); // scrypt locks up the UI before the DOM has a chance // to update (displaying logs, etc.), so do a set timeout setTimeout(function () { - Login.Cred.deriveFromPassphrase(name, password, Login.requiredBytes, function (bytes) { + var salt = ssoSeed || name; + Login.Cred.deriveFromPassphrase(salt, password, Login.requiredBytes, function (bytes) { var result = Login.allocateBytes(bytes); sframeChan.query("Q_SETTINGS_CHECK_PASSWORD", { blockHash: result.blockHash, @@ -246,7 +254,7 @@ define([ var hostname = new URL(origin).hostname; var label = "CryptPad"; - var uri = `otpauth://totp/${label}:${username}@${hostname}?secret=${secret}`; + var uri = `otpauth://totp/${encodeURI(label)}:${encodeURI(username)}@${hostname}?secret=${secret}`; var qr = h('div.cp-settings-qr'); var uriInput = UI.dialog.selectable(uri); diff --git a/www/settings/inner.js b/www/settings/inner.js index e03dbf7a1..bb33bd793 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -939,304 +939,6 @@ define([ // Account access - var drawMfa = function (content, enabled) { - var $content = $(content).empty(); - $content.append(h('div.cp-settings-mfa-hint.cp-settings-mfa-status' + (enabled ? '.mfa-enabled' : '.mfa-disabled'), [ - h('i.fa' + (enabled ? '.fa-check' : '.fa-times')), - h('span', enabled ? Messages.mfa_status_on : Messages.mfa_status_off) - ])); - - if (enabled) { - (function () { - var button = h('button.btn', Messages.mfa_disable); - button.classList.add('disable-button'); - var $mfaRevokeBtn = $(button); - var pwInput; - var pwContainer = h('div.cp-password-container', [ - h('label.cp-settings-mfa-hint', { for: 'cp-mfa-password' }, Messages.mfa_revoke_label), - pwInput = h('input#cp-mfa-password', { - type: 'password', - placeholder: Messages.login_password, - autocomplete: 'current-password', - }), - button - ]); - $content.append(pwContainer); - - // submit password on enter keyup - $(pwInput).on('keyup', e => { - if (e.which === 13) { $mfaRevokeBtn.click(); } - }); - - var spinner = UI.makeSpinner($mfaRevokeBtn); - $mfaRevokeBtn.click(function () { - var name = privateData.accountName; - var password = $(pwInput).val(); - if (!password) { return void UI.warn(Messages.login_noSuchUser); } - - spinner.spin(); - $(pwInput).prop('disabled', 'disabled'); - $mfaRevokeBtn.prop('disabled', 'disabled'); - var blockKeys; - - nThen(function (waitFor) { - var next = waitFor(); - // scrypt locks up the UI before the DOM has a chance - // to update (displaying logs, etc.), so do a set timeout - setTimeout(function () { - Login.Cred.deriveFromPassphrase(name, password, Login.requiredBytes, function (bytes) { - var result = Login.allocateBytes(bytes); - sframeChan.query("Q_SETTINGS_CHECK_PASSWORD", { - blockHash: result.blockHash, - }, function (err, obj) { - if (!obj || !obj.correct) { - spinner.hide(); - UI.warn(Messages.login_noSuchUser); - $mfaRevokeBtn.removeAttr('disabled'); - $(pwInput).removeAttr('disabled'); - waitFor.abort(); - return; - } - spinner.done(); - blockKeys = result.blockKeys; - next(); - }); - }); - }, 100); - }).nThen(function () { - $(pwContainer).remove(); - var OTPEntry; - var disable = h('button.btn.disable-button', Messages.mfa_revoke_button); - $content.append(h('div.cp-password-container', [ - h('label.cp-settings-mfa-hint', { for: 'cp-mfa-password' }, Messages.mfa_revoke_code), - OTPEntry = h('input', { - placeholder: Messages.settings_otp_code - }), - disable - ])); - var $OTPEntry = $(OTPEntry); - var $d = $(disable).click(function () { - $d.prop('disabled', 'disabled'); - var code = $OTPEntry.val(); - sframeChan.query("Q_SETTINGS_TOTP_REVOKE", { - key: blockKeys.sign, - data: { - command: 'TOTP_REVOKE', - code: code, - } - }, function (err, obj) { - $OTPEntry.val(""); - if (err || !obj || !obj.success) { - $d.removeAttr('disabled'); - return void UI.warn(Messages.settings_otp_invalid); - } - drawMfa(content, false); - }, {raw: true}); - - }); - OTPEntry.focus(); - // submit OTP on enter keyup - $OTPEntry.on('keyup', e => { - if (e.which === 13) { $d.click(); } - }); - }); - }); - - })(); - return; - } - - var button = h('button.btn.btn-primary', Messages.mfa_setup_button); - var $mfaSetupBtn = $(button); - var pwInput; - $content.append(h('div.cp-password-container', [ - h('label.cp-settings-mfa-hint', { for: 'cp-mfa-password' }, Messages.mfa_setup_label), - pwInput = h('input#cp-mfa-password', { - type: 'password', - placeholder: Messages.login_password, - }), - button - ])); - var spinner = UI.makeSpinner($mfaSetupBtn); - - // submit password on enter keyup - $(pwInput).on('keyup', e => { - if (e.which === 13) { $(button).click(); } - }); - - $(button).click(function () { - var name = privateData.accountName; - var password = $(pwInput).val(); - if (!password) { return void UI.warn(Messages.login_noSuchUser); } - - spinner.spin(); - $(pwInput).prop('disabled', 'disabled'); - $mfaSetupBtn.prop('disabled', 'disabled'); - - var Base32, QRCode, Nacl; - var blockKeys; - var recoverySecret; - var ssoSeed; - nThen(function (waitFor) { - require([ - '/auth/base32.js', - '/lib/qrcode.min.js', - '/components/tweetnacl/nacl-fast.min.js', - ], waitFor(function (_Base32) { - Base32 = _Base32; - QRCode = window.QRCode; - Nacl = window.nacl; - })); - }).nThen(function (waitFor) { - sframeChan.query("Q_SETTINGS_GET_SSO_SEED", { - }, waitFor(function (err, obj) { - if (!obj || !obj.seed) { return; } // Not an sso account? - ssoSeed = obj.seed; - })); - }).nThen(function (waitFor) { - var next = waitFor(); - // scrypt locks up the UI before the DOM has a chance - // to update (displaying logs, etc.), so do a set timeout - setTimeout(function () { - var salt = ssoSeed || name; - Login.Cred.deriveFromPassphrase(salt, password, Login.requiredBytes, function (bytes) { - var result = Login.allocateBytes(bytes); - sframeChan.query("Q_SETTINGS_CHECK_PASSWORD", { - blockHash: result.blockHash, - }, function (err, obj) { - if (!obj || !obj.correct) { - spinner.hide(); - UI.warn(Messages.login_noSuchUser); - $mfaSetupBtn.removeAttr('disabled'); - $(pwInput).removeAttr('disabled'); - waitFor.abort(); - return; - } - spinner.done(); - blockKeys = result.blockKeys; - next(); - }); - }); - }, 100); - }).nThen(function (waitFor) { - $content.empty(); - var next = waitFor(); - recoverySecret = Nacl.util.encodeBase64(Nacl.randomBytes(24)); - var button = h('button.btn.btn-primary', [ - h('i.fa.fa-check'), - h('span', Messages.done) - ]); - $content.append(h('div.alert.alert-danger', [ - h('h2', Messages.mfa_recovery_title), - h('p', Messages.mfa_recovery_hint), - h('p', Messages.mfa_recovery_warning), - h('div.cp-password-container', [ - UI.dialog.selectable(recoverySecret), - button - ]) - ])); - - var nextButton = h('button.btn.btn-primary', { - 'disabled': 'disabled' - }, Messages.continue); - $(nextButton).click(function () { - next(); - }).appendTo($content); - - $(button).click(function () { - $content.find('.alert-danger').removeClass('alert-danger').addClass('alert-success'); - $(button).prop('disabled', 'disabled'); - $(nextButton).removeAttr('disabled'); - }); - }).nThen(function () { - var randomSecret = function () { - var U8 = Nacl.randomBytes(20); - return Base32.encode(U8); - }; - $content.empty(); - - var updateQR = Util.mkAsync(function (uri, target) { - new QRCode(target, uri); - }); - var updateURI = function (secret) { - var username = privateData.accountName; - var hostname = new URL(privateData.origin).hostname; - var label = "CryptPad"; - - var uri = `otpauth://totp/${label}:${username}@${hostname}?secret=${secret}`; - - var qr = h('div.cp-settings-qr'); - var uriInput = UI.dialog.selectable(uri); - - updateQR(uri, qr); - - var OTPEntry = h('input', { - placeholder: Messages.settings_otp_code - }); - var $OTPEntry = $(OTPEntry); - - var description = h('p.cp-settings-mfa-hint', Messages.settings_otp_tuto); - var confirmOTP = h('button.btn.btn-primary', [ - h('i.fa.fa-check'), - h('span', Messages.mfa_enable) - ]); - var lock = false; - - confirmOTP.addEventListener('click', function () { - var code = $OTPEntry.val(); - if (code.length !== 6 || /\D/.test(code)) { - return void UI.warn(Messages.settings_otp_invalid); - } - confirmOTP.disabled = true; - lock = true; - - var data = { - secret: secret, - contact: "secret:" + recoverySecret, // TODO other recovery options - code: code, - }; - - sframeChan.query("Q_SETTINGS_TOTP_SETUP", { - key: blockKeys.sign, - data: data - }, function (err, obj) { - lock = false; - $OTPEntry.val(""); - if (err || !obj || !obj.success) { - confirmOTP.disabled = false; - console.error(err); - return void UI.warn(Messages.error); - } - drawMfa(content, true); - }, { raw: true }); - }); - - $content.append([ - description, - uriInput, - h('div.cp-settings-qr-container', [ - qr, - h('div.cp-settings-qr-code', [ - OTPEntry, - h('br'), - confirmOTP - ]) - ]) - ]); - OTPEntry.focus(); - // submit OTP on enter keyup - $OTPEntry.on('keyup', e => { - if (e.which === 13) { $(confirmOTP).click(); } - }); - }; - - - var secret = randomSecret(); - updateURI(secret); - }); - - }); - }; makeBlock('mfa', function (cb) { // Msg.settings_mfaTitle, Msg.settings_mfaHint if (!common.isLoggedIn()) { return void cb(false); } From 94a1642d7bca0af46963fa4bc0fd80ba76a660f0 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 15 Dec 2023 17:23:28 +0100 Subject: [PATCH 128/283] Fix margin errors in dropdown with some browsers/OS --- customize.dist/src/less2/include/dropdown.less | 1 + 1 file changed, 1 insertion(+) diff --git a/customize.dist/src/less2/include/dropdown.less b/customize.dist/src/less2/include/dropdown.less index d5ed0955a..38f6033d0 100644 --- a/customize.dist/src/less2/include/dropdown.less +++ b/customize.dist/src/less2/include/dropdown.less @@ -62,6 +62,7 @@ } .cp-dropdown-content { + list-style-type: none; display: none; position: absolute; background-color: @cp_dropdown-bg; From 568bff357ef5dd51daba1f6051ad9cab5fd6b82f Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 18 Dec 2023 10:08:52 +0100 Subject: [PATCH 129/283] Fix server error --- lib/plugin-manager.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/plugin-manager.js b/lib/plugin-manager.js index e9d783ebc..8f51120b6 100644 --- a/lib/plugin-manager.js +++ b/lib/plugin-manager.js @@ -8,6 +8,7 @@ const plugins = {}; try { let pluginsDir = fs.readdirSync(__dirname + '/plugins'); pluginsDir.forEach((name) => { + if (name=== "README.md") { return; } try { let plugin = require(`./plugins/${name}/index`); plugins[plugin.name] = plugin.modules; From 315adc59d7ef7a8cb632d0b57406747d993fe6bf Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 18 Dec 2023 14:06:28 +0100 Subject: [PATCH 130/283] Update version number --- customize.dist/pages.js | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/customize.dist/pages.js b/customize.dist/pages.js index da85e72db..fcb63bb11 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -98,7 +98,7 @@ define([ return h('a', attrs, [icon, text]); }; - Pages.versionString = "5.5.0"; + Pages.versionString = "5.6.0"; var customURLs = Pages.customURLs = {}; (function () { diff --git a/package-lock.json b/package-lock.json index 8b0b3081c..34e3156bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cryptpad", - "version": "5.5.0", + "version": "5.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cryptpad", - "version": "5.5.0", + "version": "5.6.0", "license": "AGPL-3.0+", "dependencies": { "@mcrowe/minibloom": "^0.2.0", diff --git a/package.json b/package.json index 3eea3fdbf..0c1cb79e1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cryptpad", "description": "realtime collaborative visual editor with zero knowlege server", - "version": "5.5.0", + "version": "5.6.0", "license": "AGPL-3.0+", "repository": { "type": "git", From 30d956b52fc02f9e55c3ceebf281372d26d59d49 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 18 Dec 2023 15:47:10 +0100 Subject: [PATCH 131/283] Fix ws proxy issue with :: as httpAddress --- config/config.example.js | 8 ++++---- lib/http-worker.js | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/config/config.example.js b/config/config.example.js index 3e0be47c0..4e4ddd46e 100644 --- a/config/config.example.js +++ b/config/config.example.js @@ -74,12 +74,12 @@ module.exports = { // httpSafeOrigin: "https://some-other-domain.xyz", /* httpAddress specifies the address on which the nodejs server - * should be accessible. By default it will listen on 127.0.0.1 - * (IPv4 localhost on most systems). If you want it to listen on - * all addresses, including IPv6, set this to '::'. + * should be accessible. By default it will listen on localhost + * (IPv4 & IPv6 if enabled). If you want it to listen on + * a specific address, specify it here. e.g '192.168.0.1' * */ - //httpAddress: '::', + //httpAddress: 'localhost', /* httpPort specifies on which port the nodejs server should listen. * By default it will serve content over port 3000, which is suitable diff --git a/lib/http-worker.js b/lib/http-worker.js index 5788b63a5..185ae748e 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -194,7 +194,8 @@ app.head(/^\/common\/feedback\.html/, function (req, res, next) { const { createProxyMiddleware } = require("http-proxy-middleware"); -var proxyTarget = new URL('', `ws:${Env.httpAddress}`); +var httpAddress = Env.httpAddress === '::' ? 'localhost' : Env.httpAddress; +var proxyTarget = new URL('', `ws:${httpAddress}`); proxyTarget.port = Env.websocketPort; const wsProxy = createProxyMiddleware({ From 4c81c95a949e75b5896077e51fcb6ffe86e201b3 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 18 Dec 2023 15:53:43 +0100 Subject: [PATCH 132/283] Remove missing SSO config log --- lib/load-config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/load-config.js b/lib/load-config.js index 6fc7534ec..2ba9771d0 100644 --- a/lib/load-config.js +++ b/lib/load-config.js @@ -50,7 +50,7 @@ config.sso = {}; try { config.sso = require("../config/sso"); } catch (e) { - console.log("SSO config not found"); + //console.log("SSO config not found"); } module.exports = config; From 37cfc8a35f154e3de9518c7d89b4048440190b62 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 19 Dec 2023 08:37:52 +0100 Subject: [PATCH 133/283] Fix race condition on OnlyOffice https://github.com/cryptpad/cryptpad/issues/1319 --- www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js | 2 +- www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js | 2 +- www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js b/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js index 8d90f4b49..b9f4cf98a 100644 --- a/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js +++ b/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js @@ -424,7 +424,7 @@ opt_isIdle){this._isViewer=isViewer;if(this._locks){this.ownedLockBlocks=[];for( "indexUser":this._indexUser},"editorType":this.editorType,"lastOtherSaveTime":this.lastOtherSaveTime,"block":this.ownedLockBlocks,"sessionId":this._id,"sessionTimeConnect":this._sessionTimeConnect,"sessionTimeIdle":opt_isIdle>=0?opt_isIdle:0,"documentFormatSave":this._documentFormatSave,"view":this._isViewer,"isCloseCoAuthoring":this.isCloseCoAuthoring,"openCmd":opt_openCmd,"lang":this.lang,"mode":this.mode,"permissions":this.permissions,"encrypted":this.encrypted,"IsAnonymousUser":this.IsAnonymousUser, "timezoneOffset":(new Date).getTimezoneOffset(),"coEditingMode":this.coEditingMode,"jwtOpen":this.jwtOpen,"jwtSession":this.jwtSession,"time":Math.round(performance.now()),"supportAuthChangesAck":true})};DocsCoApi.prototype._initSocksJs=function(){var t=this;var socketio;socketio=this.socketio={};var send=function(data){setTimeout(function(){socketio.onmessage({data:JSON.stringify(data)})})};var license={type:"license",license:{type:3,mode:0,rights:1,buildVersion:"7.3.3",buildNumber:8}};var channel; require(["/common/outer/worker-channel.js","/common/common-util.js"],function(Channel,Util){var msgEv=Util.mkEvent();var p=window.parent;if(editor&&editor.isReporterMode){p=window.opener;window.parent=p}else window.APP=p&&p.APP;window.addEventListener("message",function(msg){if(msg.source!==p)return;msgEv.fire(msg)});var postMsg=function(data){p.postMessage(data,"*")};Channel.create(msgEv,postMsg,function(chan){channel=chan;send(license);chan.on("CMD",function(obj){send(obj)})})});socketio.onopen= -function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",data)};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); +function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",structuredClone(data))};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); break;case "message":this._onMessages(dataObject,false);break;case "cursor":this._onCursor(dataObject);break;case "meta":this._onMeta(dataObject);break;case "getLock":this._onGetLock(dataObject);break;case "releaseLock":this._onReleaseLock(dataObject);break;case "connectState":this._onConnectionStateChanged(dataObject);break;case "saveChanges":this._onSaveChanges(dataObject);break;case "authChanges":this._onAuthChanges(dataObject);break;case "saveLock":this._onSaveLock(dataObject);break;case "unSaveLock":this._onUnSaveLock(dataObject); break;case "savePartChanges":this._onSavePartChanges(dataObject);break;case "drop":this._onDrop(dataObject);break;case "disconnectReason":this._onDisconnectReason(dataObject);break;case "waitAuth":break;case "error":this._onDrop(dataObject);break;case "documentOpen":this._documentOpen(dataObject);break;case "warning":this._onWarning(dataObject);break;case "license":this._onLicense(dataObject);break;case "session":this._onSession(dataObject);break;case "refreshToken":this._onRefreshToken(dataObject["messages"]); break;case "expiredToken":this._onExpiredToken(dataObject);break;case "forceSaveStart":this._onForceSaveStart(dataObject["messages"]);break;case "forceSave":this._onForceSave(dataObject["messages"]);break;case "rpc":this._onPRC(dataObject["responseKey"],false,dataObject["data"]);break}};DocsCoApi.prototype._onServerClose=function(explicit){if(ConnectionState.SaveChanges===this._state){this._isReSaveAfterAuth=true;if(null!==this.saveCallbackErrorTimeOutId){clearTimeout(this.saveCallbackErrorTimeOutId); diff --git a/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js b/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js index 333b64b81..6d9158cb6 100644 --- a/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js +++ b/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js @@ -424,7 +424,7 @@ opt_isIdle){this._isViewer=isViewer;if(this._locks){this.ownedLockBlocks=[];for( "indexUser":this._indexUser},"editorType":this.editorType,"lastOtherSaveTime":this.lastOtherSaveTime,"block":this.ownedLockBlocks,"sessionId":this._id,"sessionTimeConnect":this._sessionTimeConnect,"sessionTimeIdle":opt_isIdle>=0?opt_isIdle:0,"documentFormatSave":this._documentFormatSave,"view":this._isViewer,"isCloseCoAuthoring":this.isCloseCoAuthoring,"openCmd":opt_openCmd,"lang":this.lang,"mode":this.mode,"permissions":this.permissions,"encrypted":this.encrypted,"IsAnonymousUser":this.IsAnonymousUser, "timezoneOffset":(new Date).getTimezoneOffset(),"coEditingMode":this.coEditingMode,"jwtOpen":this.jwtOpen,"jwtSession":this.jwtSession,"time":Math.round(performance.now()),"supportAuthChangesAck":true})};DocsCoApi.prototype._initSocksJs=function(){var t=this;var socketio;socketio=this.socketio={};var send=function(data){setTimeout(function(){socketio.onmessage({data:JSON.stringify(data)})})};var license={type:"license",license:{type:3,mode:0,rights:1,buildVersion:"7.3.3",buildNumber:8}};var channel; require(["/common/outer/worker-channel.js","/common/common-util.js"],function(Channel,Util){var msgEv=Util.mkEvent();var p=window.parent;if(editor&&editor.isReporterMode){p=window.opener;window.parent=p}else window.APP=p&&p.APP;window.addEventListener("message",function(msg){if(msg.source!==p)return;msgEv.fire(msg)});var postMsg=function(data){p.postMessage(data,"*")};Channel.create(msgEv,postMsg,function(chan){channel=chan;send(license);chan.on("CMD",function(obj){send(obj)})})});socketio.onopen= -function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",data)};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); +function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",structuredClone(data))};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); break;case "message":this._onMessages(dataObject,false);break;case "cursor":this._onCursor(dataObject);break;case "meta":this._onMeta(dataObject);break;case "getLock":this._onGetLock(dataObject);break;case "releaseLock":this._onReleaseLock(dataObject);break;case "connectState":this._onConnectionStateChanged(dataObject);break;case "saveChanges":this._onSaveChanges(dataObject);break;case "authChanges":this._onAuthChanges(dataObject);break;case "saveLock":this._onSaveLock(dataObject);break;case "unSaveLock":this._onUnSaveLock(dataObject); break;case "savePartChanges":this._onSavePartChanges(dataObject);break;case "drop":this._onDrop(dataObject);break;case "disconnectReason":this._onDisconnectReason(dataObject);break;case "waitAuth":break;case "error":this._onDrop(dataObject);break;case "documentOpen":this._documentOpen(dataObject);break;case "warning":this._onWarning(dataObject);break;case "license":this._onLicense(dataObject);break;case "session":this._onSession(dataObject);break;case "refreshToken":this._onRefreshToken(dataObject["messages"]); break;case "expiredToken":this._onExpiredToken(dataObject);break;case "forceSaveStart":this._onForceSaveStart(dataObject["messages"]);break;case "forceSave":this._onForceSave(dataObject["messages"]);break;case "rpc":this._onPRC(dataObject["responseKey"],false,dataObject["data"]);break}};DocsCoApi.prototype._onServerClose=function(explicit){if(ConnectionState.SaveChanges===this._state){this._isReSaveAfterAuth=true;if(null!==this.saveCallbackErrorTimeOutId){clearTimeout(this.saveCallbackErrorTimeOutId); diff --git a/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js b/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js index bd6421759..de3af8b0a 100644 --- a/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js +++ b/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js @@ -424,7 +424,7 @@ opt_isIdle){this._isViewer=isViewer;if(this._locks){this.ownedLockBlocks=[];for( "indexUser":this._indexUser},"editorType":this.editorType,"lastOtherSaveTime":this.lastOtherSaveTime,"block":this.ownedLockBlocks,"sessionId":this._id,"sessionTimeConnect":this._sessionTimeConnect,"sessionTimeIdle":opt_isIdle>=0?opt_isIdle:0,"documentFormatSave":this._documentFormatSave,"view":this._isViewer,"isCloseCoAuthoring":this.isCloseCoAuthoring,"openCmd":opt_openCmd,"lang":this.lang,"mode":this.mode,"permissions":this.permissions,"encrypted":this.encrypted,"IsAnonymousUser":this.IsAnonymousUser, "timezoneOffset":(new Date).getTimezoneOffset(),"coEditingMode":this.coEditingMode,"jwtOpen":this.jwtOpen,"jwtSession":this.jwtSession,"time":Math.round(performance.now()),"supportAuthChangesAck":true})};DocsCoApi.prototype._initSocksJs=function(){var t=this;var socketio;socketio=this.socketio={};var send=function(data){setTimeout(function(){socketio.onmessage({data:JSON.stringify(data)})})};var license={type:"license",license:{type:3,mode:0,rights:1,buildVersion:"7.3.3",buildNumber:8}};var channel; require(["/common/outer/worker-channel.js","/common/common-util.js"],function(Channel,Util){var msgEv=Util.mkEvent();var p=window.parent;if(editor&&editor.isReporterMode){p=window.opener;window.parent=p}else window.APP=p&&p.APP;window.addEventListener("message",function(msg){if(msg.source!==p)return;msgEv.fire(msg)});var postMsg=function(data){p.postMessage(data,"*")};Channel.create(msgEv,postMsg,function(chan){channel=chan;send(license);chan.on("CMD",function(obj){send(obj)})})});socketio.onopen= -function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",data)};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); +function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",structuredClone(data))};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); break;case "message":this._onMessages(dataObject,false);break;case "cursor":this._onCursor(dataObject);break;case "meta":this._onMeta(dataObject);break;case "getLock":this._onGetLock(dataObject);break;case "releaseLock":this._onReleaseLock(dataObject);break;case "connectState":this._onConnectionStateChanged(dataObject);break;case "saveChanges":this._onSaveChanges(dataObject);break;case "authChanges":this._onAuthChanges(dataObject);break;case "saveLock":this._onSaveLock(dataObject);break;case "unSaveLock":this._onUnSaveLock(dataObject); break;case "savePartChanges":this._onSavePartChanges(dataObject);break;case "drop":this._onDrop(dataObject);break;case "disconnectReason":this._onDisconnectReason(dataObject);break;case "waitAuth":break;case "error":this._onDrop(dataObject);break;case "documentOpen":this._documentOpen(dataObject);break;case "warning":this._onWarning(dataObject);break;case "license":this._onLicense(dataObject);break;case "session":this._onSession(dataObject);break;case "refreshToken":this._onRefreshToken(dataObject["messages"]); break;case "expiredToken":this._onExpiredToken(dataObject);break;case "forceSaveStart":this._onForceSaveStart(dataObject["messages"]);break;case "forceSave":this._onForceSave(dataObject["messages"]);break;case "rpc":this._onPRC(dataObject["responseKey"],false,dataObject["data"]);break}};DocsCoApi.prototype._onServerClose=function(explicit){if(ConnectionState.SaveChanges===this._state){this._isReSaveAfterAuth=true;if(null!==this.saveCallbackErrorTimeOutId){clearTimeout(this.saveCallbackErrorTimeOutId); From 32c22a8b61526bbb2eccb204be8e4b2c04639c7f Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Tue, 19 Dec 2023 08:37:52 +0100 Subject: [PATCH 134/283] Fix race condition on OnlyOffice https://github.com/cryptpad/cryptpad/issues/1319 --- www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js | 2 +- www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js | 2 +- www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js b/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js index 8d90f4b49..b9f4cf98a 100644 --- a/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js +++ b/www/common/onlyoffice/v7/sdkjs/cell/sdk-all-min.js @@ -424,7 +424,7 @@ opt_isIdle){this._isViewer=isViewer;if(this._locks){this.ownedLockBlocks=[];for( "indexUser":this._indexUser},"editorType":this.editorType,"lastOtherSaveTime":this.lastOtherSaveTime,"block":this.ownedLockBlocks,"sessionId":this._id,"sessionTimeConnect":this._sessionTimeConnect,"sessionTimeIdle":opt_isIdle>=0?opt_isIdle:0,"documentFormatSave":this._documentFormatSave,"view":this._isViewer,"isCloseCoAuthoring":this.isCloseCoAuthoring,"openCmd":opt_openCmd,"lang":this.lang,"mode":this.mode,"permissions":this.permissions,"encrypted":this.encrypted,"IsAnonymousUser":this.IsAnonymousUser, "timezoneOffset":(new Date).getTimezoneOffset(),"coEditingMode":this.coEditingMode,"jwtOpen":this.jwtOpen,"jwtSession":this.jwtSession,"time":Math.round(performance.now()),"supportAuthChangesAck":true})};DocsCoApi.prototype._initSocksJs=function(){var t=this;var socketio;socketio=this.socketio={};var send=function(data){setTimeout(function(){socketio.onmessage({data:JSON.stringify(data)})})};var license={type:"license",license:{type:3,mode:0,rights:1,buildVersion:"7.3.3",buildNumber:8}};var channel; require(["/common/outer/worker-channel.js","/common/common-util.js"],function(Channel,Util){var msgEv=Util.mkEvent();var p=window.parent;if(editor&&editor.isReporterMode){p=window.opener;window.parent=p}else window.APP=p&&p.APP;window.addEventListener("message",function(msg){if(msg.source!==p)return;msgEv.fire(msg)});var postMsg=function(data){p.postMessage(data,"*")};Channel.create(msgEv,postMsg,function(chan){channel=chan;send(license);chan.on("CMD",function(obj){send(obj)})})});socketio.onopen= -function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",data)};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); +function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",structuredClone(data))};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); break;case "message":this._onMessages(dataObject,false);break;case "cursor":this._onCursor(dataObject);break;case "meta":this._onMeta(dataObject);break;case "getLock":this._onGetLock(dataObject);break;case "releaseLock":this._onReleaseLock(dataObject);break;case "connectState":this._onConnectionStateChanged(dataObject);break;case "saveChanges":this._onSaveChanges(dataObject);break;case "authChanges":this._onAuthChanges(dataObject);break;case "saveLock":this._onSaveLock(dataObject);break;case "unSaveLock":this._onUnSaveLock(dataObject); break;case "savePartChanges":this._onSavePartChanges(dataObject);break;case "drop":this._onDrop(dataObject);break;case "disconnectReason":this._onDisconnectReason(dataObject);break;case "waitAuth":break;case "error":this._onDrop(dataObject);break;case "documentOpen":this._documentOpen(dataObject);break;case "warning":this._onWarning(dataObject);break;case "license":this._onLicense(dataObject);break;case "session":this._onSession(dataObject);break;case "refreshToken":this._onRefreshToken(dataObject["messages"]); break;case "expiredToken":this._onExpiredToken(dataObject);break;case "forceSaveStart":this._onForceSaveStart(dataObject["messages"]);break;case "forceSave":this._onForceSave(dataObject["messages"]);break;case "rpc":this._onPRC(dataObject["responseKey"],false,dataObject["data"]);break}};DocsCoApi.prototype._onServerClose=function(explicit){if(ConnectionState.SaveChanges===this._state){this._isReSaveAfterAuth=true;if(null!==this.saveCallbackErrorTimeOutId){clearTimeout(this.saveCallbackErrorTimeOutId); diff --git a/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js b/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js index 333b64b81..6d9158cb6 100644 --- a/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js +++ b/www/common/onlyoffice/v7/sdkjs/slide/sdk-all-min.js @@ -424,7 +424,7 @@ opt_isIdle){this._isViewer=isViewer;if(this._locks){this.ownedLockBlocks=[];for( "indexUser":this._indexUser},"editorType":this.editorType,"lastOtherSaveTime":this.lastOtherSaveTime,"block":this.ownedLockBlocks,"sessionId":this._id,"sessionTimeConnect":this._sessionTimeConnect,"sessionTimeIdle":opt_isIdle>=0?opt_isIdle:0,"documentFormatSave":this._documentFormatSave,"view":this._isViewer,"isCloseCoAuthoring":this.isCloseCoAuthoring,"openCmd":opt_openCmd,"lang":this.lang,"mode":this.mode,"permissions":this.permissions,"encrypted":this.encrypted,"IsAnonymousUser":this.IsAnonymousUser, "timezoneOffset":(new Date).getTimezoneOffset(),"coEditingMode":this.coEditingMode,"jwtOpen":this.jwtOpen,"jwtSession":this.jwtSession,"time":Math.round(performance.now()),"supportAuthChangesAck":true})};DocsCoApi.prototype._initSocksJs=function(){var t=this;var socketio;socketio=this.socketio={};var send=function(data){setTimeout(function(){socketio.onmessage({data:JSON.stringify(data)})})};var license={type:"license",license:{type:3,mode:0,rights:1,buildVersion:"7.3.3",buildNumber:8}};var channel; require(["/common/outer/worker-channel.js","/common/common-util.js"],function(Channel,Util){var msgEv=Util.mkEvent();var p=window.parent;if(editor&&editor.isReporterMode){p=window.opener;window.parent=p}else window.APP=p&&p.APP;window.addEventListener("message",function(msg){if(msg.source!==p)return;msgEv.fire(msg)});var postMsg=function(data){p.postMessage(data,"*")};Channel.create(msgEv,postMsg,function(chan){channel=chan;send(license);chan.on("CMD",function(obj){send(obj)})})});socketio.onopen= -function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",data)};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); +function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",structuredClone(data))};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); break;case "message":this._onMessages(dataObject,false);break;case "cursor":this._onCursor(dataObject);break;case "meta":this._onMeta(dataObject);break;case "getLock":this._onGetLock(dataObject);break;case "releaseLock":this._onReleaseLock(dataObject);break;case "connectState":this._onConnectionStateChanged(dataObject);break;case "saveChanges":this._onSaveChanges(dataObject);break;case "authChanges":this._onAuthChanges(dataObject);break;case "saveLock":this._onSaveLock(dataObject);break;case "unSaveLock":this._onUnSaveLock(dataObject); break;case "savePartChanges":this._onSavePartChanges(dataObject);break;case "drop":this._onDrop(dataObject);break;case "disconnectReason":this._onDisconnectReason(dataObject);break;case "waitAuth":break;case "error":this._onDrop(dataObject);break;case "documentOpen":this._documentOpen(dataObject);break;case "warning":this._onWarning(dataObject);break;case "license":this._onLicense(dataObject);break;case "session":this._onSession(dataObject);break;case "refreshToken":this._onRefreshToken(dataObject["messages"]); break;case "expiredToken":this._onExpiredToken(dataObject);break;case "forceSaveStart":this._onForceSaveStart(dataObject["messages"]);break;case "forceSave":this._onForceSave(dataObject["messages"]);break;case "rpc":this._onPRC(dataObject["responseKey"],false,dataObject["data"]);break}};DocsCoApi.prototype._onServerClose=function(explicit){if(ConnectionState.SaveChanges===this._state){this._isReSaveAfterAuth=true;if(null!==this.saveCallbackErrorTimeOutId){clearTimeout(this.saveCallbackErrorTimeOutId); diff --git a/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js b/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js index bd6421759..de3af8b0a 100644 --- a/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js +++ b/www/common/onlyoffice/v7/sdkjs/word/sdk-all-min.js @@ -424,7 +424,7 @@ opt_isIdle){this._isViewer=isViewer;if(this._locks){this.ownedLockBlocks=[];for( "indexUser":this._indexUser},"editorType":this.editorType,"lastOtherSaveTime":this.lastOtherSaveTime,"block":this.ownedLockBlocks,"sessionId":this._id,"sessionTimeConnect":this._sessionTimeConnect,"sessionTimeIdle":opt_isIdle>=0?opt_isIdle:0,"documentFormatSave":this._documentFormatSave,"view":this._isViewer,"isCloseCoAuthoring":this.isCloseCoAuthoring,"openCmd":opt_openCmd,"lang":this.lang,"mode":this.mode,"permissions":this.permissions,"encrypted":this.encrypted,"IsAnonymousUser":this.IsAnonymousUser, "timezoneOffset":(new Date).getTimezoneOffset(),"coEditingMode":this.coEditingMode,"jwtOpen":this.jwtOpen,"jwtSession":this.jwtSession,"time":Math.round(performance.now()),"supportAuthChangesAck":true})};DocsCoApi.prototype._initSocksJs=function(){var t=this;var socketio;socketio=this.socketio={};var send=function(data){setTimeout(function(){socketio.onmessage({data:JSON.stringify(data)})})};var license={type:"license",license:{type:3,mode:0,rights:1,buildVersion:"7.3.3",buildNumber:8}};var channel; require(["/common/outer/worker-channel.js","/common/common-util.js"],function(Channel,Util){var msgEv=Util.mkEvent();var p=window.parent;if(editor&&editor.isReporterMode){p=window.opener;window.parent=p}else window.APP=p&&p.APP;window.addEventListener("message",function(msg){if(msg.source!==p)return;msgEv.fire(msg)});var postMsg=function(data){p.postMessage(data,"*")};Channel.create(msgEv,postMsg,function(chan){channel=chan;send(license);chan.on("CMD",function(obj){send(obj)})})});socketio.onopen= -function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",data)};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); +function(){t._onServerOpen()};socketio.onopen();socketio.close=function(){console.error("Close realtime")};socketio.emit=function(type,data){if(channel)channel.event("CMD",structuredClone(data))};socketio.onmessage=function(e){t._onServerMessage(JSON.parse(e.data))};return socketio};DocsCoApi.prototype._onServerOpen=function(){this._state=ConnectionState.WaitAuth;this.onFirstConnect()};DocsCoApi.prototype._onServerMessage=function(data){var dataObject=data;switch(dataObject["type"]){case "auth":this._onAuth(dataObject); break;case "message":this._onMessages(dataObject,false);break;case "cursor":this._onCursor(dataObject);break;case "meta":this._onMeta(dataObject);break;case "getLock":this._onGetLock(dataObject);break;case "releaseLock":this._onReleaseLock(dataObject);break;case "connectState":this._onConnectionStateChanged(dataObject);break;case "saveChanges":this._onSaveChanges(dataObject);break;case "authChanges":this._onAuthChanges(dataObject);break;case "saveLock":this._onSaveLock(dataObject);break;case "unSaveLock":this._onUnSaveLock(dataObject); break;case "savePartChanges":this._onSavePartChanges(dataObject);break;case "drop":this._onDrop(dataObject);break;case "disconnectReason":this._onDisconnectReason(dataObject);break;case "waitAuth":break;case "error":this._onDrop(dataObject);break;case "documentOpen":this._documentOpen(dataObject);break;case "warning":this._onWarning(dataObject);break;case "license":this._onLicense(dataObject);break;case "session":this._onSession(dataObject);break;case "refreshToken":this._onRefreshToken(dataObject["messages"]); break;case "expiredToken":this._onExpiredToken(dataObject);break;case "forceSaveStart":this._onForceSaveStart(dataObject["messages"]);break;case "forceSave":this._onForceSave(dataObject["messages"]);break;case "rpc":this._onPRC(dataObject["responseKey"],false,dataObject["data"]);break}};DocsCoApi.prototype._onServerClose=function(explicit){if(ConnectionState.SaveChanges===this._state){this._isReSaveAfterAuth=true;if(null!==this.saveCallbackErrorTimeOutId){clearTimeout(this.saveCallbackErrorTimeOutId); From 06f4b8e59063f5afae2faf9bdd3ce6ff6ce30f0e Mon Sep 17 00:00:00 2001 From: David Benque Date: Tue, 19 Dec 2023 11:38:26 +0000 Subject: [PATCH 135/283] Add licensing information to new files --- SECURITY.md | 6 ++++++ docs/example.httpd.conf | 4 ++++ lib/plugins/README.md | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index 133723221..75100dbf0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,9 @@ + + # Security Policy ## Supported Versions diff --git a/docs/example.httpd.conf b/docs/example.httpd.conf index d8b0d8d00..f98b505f2 100644 --- a/docs/example.httpd.conf +++ b/docs/example.httpd.conf @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +# +# SPDX-License-Identifier: AGPL-3.0-or-later + # This file is included strictly as an example of how Apache httpd can be # configured to work with CryptPad. If you are using CryptPad in production # and require professional support please contact sales@cryptpad.fr diff --git a/lib/plugins/README.md b/lib/plugins/README.md index 70e448011..dd2d15af2 100644 --- a/lib/plugins/README.md +++ b/lib/plugins/README.md @@ -1 +1,7 @@ + + # CryptPad's plugins directory From a108e64175e7d68e6c3695c5bbebba136b4f1918 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:10 +0100 Subject: [PATCH 136/283] Translated using Weblate (Ukrainian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 68.0% (1144 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/uk/ Translation: CryptPad/App --- www/common/translations/messages.uk.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.uk.json b/www/common/translations/messages.uk.json index a0b3f28ec..914fe77e5 100644 --- a/www/common/translations/messages.uk.json +++ b/www/common/translations/messages.uk.json @@ -1031,7 +1031,6 @@ "calendar_hours": "Години", "calendar_minutes": "Хвилини", "calendar_allDay": "Весь день", - "calendar_location": "Місце: {0}", "calendar_loc": "Місце", "calendar_title": "Заголовок", "calendar_update": "Оновити", From 10ba682d1f34b73d7cc31e985f83740f2b64b2b5 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:10 +0100 Subject: [PATCH 137/283] Translated using Weblate (Czech) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 84.2% (1417 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/cs/ Translation: CryptPad/App --- www/common/translations/messages.cs.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.cs.json b/www/common/translations/messages.cs.json index f57b72c40..8769febb3 100644 --- a/www/common/translations/messages.cs.json +++ b/www/common/translations/messages.cs.json @@ -635,7 +635,6 @@ "calendar_hours": "Hodin", "calendar_minutes": "Minut", "calendar_allDay": "Celý den", - "calendar_location": "Místo: {0}", "calendar_loc": "Místo", "calendar_title": "Nadpis", "calendar_update": "Uložit", From a884c163e8b9b2f56a451d14148e242be6dea747 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:11 +0100 Subject: [PATCH 138/283] Translated using Weblate (Spanish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 91.9% (1547 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/es/ Translation: CryptPad/App --- www/common/translations/messages.es.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.es.json b/www/common/translations/messages.es.json index 896967246..2c3df1e42 100644 --- a/www/common/translations/messages.es.json +++ b/www/common/translations/messages.es.json @@ -950,7 +950,6 @@ "calendar_hours": "Horas", "calendar_minutes": "Minutos", "calendar_allDay": "Todo el día", - "calendar_location": "Localización: {0}", "calendar_loc": "Localización", "calendar_title": "Título", "calendar_dateTimeRange": "{0} {1} - {2}", From 6505b2f7252a2c5457ca3570c6a3c484caddf65a Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:11 +0100 Subject: [PATCH 139/283] Translated using Weblate (Chinese (Simplified)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 89.4% (1505 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/zh_Hans/ Translation: CryptPad/App --- www/common/translations/messages.zh.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.zh.json b/www/common/translations/messages.zh.json index 5f36f370a..604e64ab9 100644 --- a/www/common/translations/messages.zh.json +++ b/www/common/translations/messages.zh.json @@ -1236,7 +1236,6 @@ "calendar_hours": "小时", "calendar_minutes": "分钟", "calendar_allDay": "全天", - "calendar_location": "位置:{0}", "calendar_loc": "地点", "calendar_title": "标题", "calendar_update": "更新", From 2f7c45477df2a50b0b1538b55d99fc10bcb06798 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:12 +0100 Subject: [PATCH 140/283] Translated using Weblate (Catalan) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 64.5% (1085 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ca/ Translation: CryptPad/App --- www/common/translations/messages.ca.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ca.json b/www/common/translations/messages.ca.json index 8485bdf19..1854164ef 100644 --- a/www/common/translations/messages.ca.json +++ b/www/common/translations/messages.ca.json @@ -1421,7 +1421,6 @@ "calendar_deleteTeamConfirm": "Esteu segur que voleu suprimir aquest calendari de l'equip?", "calendar_deleteOwned": "Continuarà sent visible per a altres usuaris amb els quals s'ha compartit.", "calendar_newEvent": "Esdeveniment nou", - "calendar_location": "Ubicació: {0}", "calendar_more": "{0} més", "reminder_missed": "{0} va tenir lloc el {1}", "reminder_now": "{0} ha començat", From 0ba6d208887674ad9ba6170c74be86cab1736947 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:12 +0100 Subject: [PATCH 141/283] Translated using Weblate (Finnish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 73.0% (1228 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/fi/ Translation: CryptPad/App --- www/common/translations/messages.fi.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.fi.json b/www/common/translations/messages.fi.json index 04002ceae..a4881c436 100644 --- a/www/common/translations/messages.fi.json +++ b/www/common/translations/messages.fi.json @@ -1173,7 +1173,6 @@ "calendar_update": "Päivitä", "calendar_title": "Otsikko", "calendar_loc": "Sijainti", - "calendar_location": "Sijainti: {0}", "calendar_allDay": "Koko päivä", "calendar_minutes": "Minuutit", "calendar_hours": "Tunnit", From a7ac895bf8f53049b9521f173d1b5bdb38ffe4f9 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:13 +0100 Subject: [PATCH 142/283] Translated using Weblate (Indonesian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.0% (1666 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/id/ Translation: CryptPad/App --- www/common/translations/messages.id.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.id.json b/www/common/translations/messages.id.json index 3a927a872..334172693 100644 --- a/www/common/translations/messages.id.json +++ b/www/common/translations/messages.id.json @@ -915,7 +915,6 @@ "calendar_default": "Kalender saya", "calendar_new": "Kalender baru", "calendar_newEvent": "Acara baru", - "calendar_location": "Lokasi: {0}", "calendar_allDay": "Seharian", "reminder_inProgressAllDay": "Hari ini: {0}", "admin_supportPrivButton": "Tampilkan kunci", From 33dcdfb09913f7b57b1ece216d97a0b8da67b124 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:13 +0100 Subject: [PATCH 143/283] Translated using Weblate (Italian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 68.9% (1160 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/it/ Translation: CryptPad/App --- www/common/translations/messages.it.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.it.json b/www/common/translations/messages.it.json index 099b208fc..cf769477a 100644 --- a/www/common/translations/messages.it.json +++ b/www/common/translations/messages.it.json @@ -1098,7 +1098,6 @@ "broadcast_end": "Termina", "broadcast_maintenance": "Una manutenzione è programmata tra {0} e {1}. CryptPad potrebbe non essere disponibile in quel lasso di tempo.", "admin_surveyTitle": "Sondaggio", - "calendar_location": "Posizione: {0}", "admin_surveyButton": "Salva sondaggio", "admin_surveyActive": "Apri sondaggio", "calendar_minutes": "Minuti", From ce6037f95af63003e59a7c371175a5e0d25f2518 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:14 +0100 Subject: [PATCH 144/283] Translated using Weblate (Japanese) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 96.2% (1619 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ja/ Translation: CryptPad/App --- www/common/translations/messages.ja.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ja.json b/www/common/translations/messages.ja.json index 1c139d00e..f3239c85b 100644 --- a/www/common/translations/messages.ja.json +++ b/www/common/translations/messages.ja.json @@ -940,7 +940,6 @@ "calendar_hours": "時間", "calendar_minutes": "分", "calendar_allDay": "全日", - "calendar_location": "場所: {0}", "calendar_loc": "場所", "calendar_title": "タイトル", "calendar_update": "更新", From fc6549b8302a076f7cc7360e1be745d95860aaa7 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:14 +0100 Subject: [PATCH 145/283] Translated using Weblate (Dutch) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 37.9% (638 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/nl/ Translation: CryptPad/App --- www/common/translations/messages.nl.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.nl.json b/www/common/translations/messages.nl.json index b8cc5dd72..022193059 100644 --- a/www/common/translations/messages.nl.json +++ b/www/common/translations/messages.nl.json @@ -522,7 +522,6 @@ "calendar_import": "Voeg toe aan mijn agenda's", "calendar_dateTimeRange": "{0} {1} - {2}", "calendar_title": "Titel", - "calendar_location": "Plaats: {0}", "calendar_minutes": "Minuten", "calendar_addNotification": "Voeg herinnering toe", "register_registrationIsClosed": "Registratie is gesloten.", From 2e79ad7fd26b555be37955b50918b5cd1269866a Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:15 +0100 Subject: [PATCH 146/283] Translated using Weblate (Polish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 82.1% (1381 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/pl/ Translation: CryptPad/App --- www/common/translations/messages.pl.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.pl.json b/www/common/translations/messages.pl.json index 06a49e655..f86939792 100644 --- a/www/common/translations/messages.pl.json +++ b/www/common/translations/messages.pl.json @@ -899,7 +899,6 @@ "calendar_hours": "Godziny", "calendar_minutes": "Minuty", "calendar_allDay": "Cały dzień", - "calendar_location": "Lokalizacja: {0}", "calendar_loc": "Lokalizacja", "calendar_title": "Tytuł", "calendar_update": "Zaktualizuj", From b73a83edc74136f8cbe5a37c531a2f40cedc897f Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:15 +0100 Subject: [PATCH 147/283] Translated using Weblate (Portuguese (Brazil)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 98.9% (1664 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/pt_BR/ Translation: CryptPad/App --- www/common/translations/messages.pt-br.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.pt-br.json b/www/common/translations/messages.pt-br.json index 7159d8b03..8026159d8 100644 --- a/www/common/translations/messages.pt-br.json +++ b/www/common/translations/messages.pt-br.json @@ -1235,7 +1235,6 @@ "calendar_hours": "Horas", "calendar_minutes": "Minutos", "calendar_allDay": "O dia todo", - "calendar_location": "Localização: {0}", "calendar_loc": "Local", "calendar_title": "Título", "calendar_update": "Atualizar", From 0b8bb5ebf61f1bd920d37e4d8e6a7af4444a26c2 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:15 +0100 Subject: [PATCH 148/283] Translated using Weblate (Portuguese (Portugal)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 80.6% (1356 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/pt_PT/ Translation: CryptPad/App --- www/common/translations/messages.pt-pt.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.pt-pt.json b/www/common/translations/messages.pt-pt.json index 4be7f68b0..e6c82a531 100644 --- a/www/common/translations/messages.pt-pt.json +++ b/www/common/translations/messages.pt-pt.json @@ -1234,7 +1234,6 @@ "calendar_hours": "Horas", "calendar_minutes": "Minutos", "calendar_allDay": "O dia todo", - "calendar_location": "Localização: {0}", "calendar_loc": "Local", "calendar_title": "Título", "calendar_update": "Atualizar", From 47db10b06cd510d8ec19767c254c98a3d8208ac3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:16 +0100 Subject: [PATCH 149/283] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 93.7% (1577 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ru/ Translation: CryptPad/App --- www/common/translations/messages.ru.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ru.json b/www/common/translations/messages.ru.json index 6ee081441..355ff6335 100644 --- a/www/common/translations/messages.ru.json +++ b/www/common/translations/messages.ru.json @@ -1337,7 +1337,6 @@ "calendar_hours": "Часа(ов)", "calendar_minutes": "Минут(ы)", "calendar_allDay": "Весь день", - "calendar_location": "Место: {0}", "calendar_loc": "Место", "calendar_title": "Заголовок", "calendar_update": "Обновить", From fd237544c8f0ec8eb483e0fc74fdaf2c5554a309 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:16 +0100 Subject: [PATCH 150/283] Translated using Weblate (Swedish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.0% (1666 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/sv/ Translation: CryptPad/App --- www/common/translations/messages.sv.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.sv.json b/www/common/translations/messages.sv.json index e8c903b0c..6f3aafa9b 100644 --- a/www/common/translations/messages.sv.json +++ b/www/common/translations/messages.sv.json @@ -650,7 +650,6 @@ "calendar_month": "Månad", "calendar_title": "Rubrik", "calendar_noNotification": "Ingen", - "calendar_location": "Plats: {0}", "settings_notifCalendarTitle": "Kalenderaviseringar", "mediatag_defaultImageName": "bild", "share_formAuditor": "Granskare", From 9404288a1ea2190dec2bbc1c611200608c9c6886 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:17 +0100 Subject: [PATCH 151/283] Translated using Weblate (Arabic) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 96.3% (1620 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ar/ Translation: CryptPad/App --- www/common/translations/messages.ar.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ar.json b/www/common/translations/messages.ar.json index e9a1d3bc5..f69f365ab 100644 --- a/www/common/translations/messages.ar.json +++ b/www/common/translations/messages.ar.json @@ -1165,7 +1165,6 @@ "calendar_update": "حَدِّثْ", "calendar_title": "عنوان", "calendar_loc": "موقع", - "calendar_location": "الموقع: {0}", "calendar_hours": "ساعات", "calendar_noNotification": "بدون إشعار", "calendar_allDay": "طوال اليوم", From b14cdacc5cb1973b4b28ba333ed15ccb7616080a Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:17 +0100 Subject: [PATCH 152/283] Translated using Weblate (Basque) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 98.8% (1662 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/eu/ Translation: CryptPad/App --- www/common/translations/messages.eu.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.eu.json b/www/common/translations/messages.eu.json index f83f56c13..827b1bde0 100644 --- a/www/common/translations/messages.eu.json +++ b/www/common/translations/messages.eu.json @@ -1048,7 +1048,6 @@ "calendar_hours": "Orduak", "calendar_minutes": "Minutuak", "calendar_allDay": "Egunero", - "calendar_location": "Kokapena: {0}", "calendar_loc": "Kokapena", "calendar_title": "Izena", "calendar_update": "Eguneratu", From 7f31282d867ffdb2760861fe5a56c3c747f9e997 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:18 +0100 Subject: [PATCH 153/283] Translated using Weblate (German) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (German) Currently translated at 99.1% (1667 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Jan Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/de/ Translation: CryptPad/App --- www/common/translations/messages.de.json | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 34a175d68..8528dc3f3 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -479,7 +479,7 @@ "mdToolbar_list": "Aufzählung", "mdToolbar_check": "Aufgabenliste", "mdToolbar_code": "Code", - "home_host": "Dies ist eine unabhängige Installation der CrypPad-Software.", + "home_host": "Dies ist eine unabhängige Instanz von CryptPad.", "main_catch_phrase": "Suite zur Zusammenarbeit
Ende-zu-Ende-verschlüsselt und quelloffen", "about": "Über uns", "privacy": "Datenschutzerklärung", @@ -1167,7 +1167,6 @@ "calendar_hours": "Stunden", "calendar_minutes": "Minuten", "calendar_allDay": "Ganztägig", - "calendar_location": "Ort: {0}", "calendar_loc": "Ort", "calendar_title": "Titel", "calendar_update": "Aktualisieren", @@ -1667,5 +1666,20 @@ "status": "Statusseite", "access_passwordUsed": "Dieses Passwort wurde bereits für dieses Dokument verwendet. Es kann nicht erneut verwendet werden.", "admin_diskUsageWarning": "Mit Vorsicht zu verwenden! Je nach Größe der auf der Instanz gespeicherten Daten kann die Erstellung dieses Berichts den gesamten auf dem Server verfügbaren Speicher verbrauchen und zu einem Absturz führen.", - "dph_sf_destroyed": "Geteilter Ordner {0} wurde vom Eigentümer zerstört" + "dph_sf_destroyed": "Geteilter Ordner {0} wurde vom Eigentümer zerstört", + "calendar_desc": "Beschreibung", + "admin_forcemfaHint": "Alle Benutzer dieser Instanz werden aufgefordert, eine Zwei-Faktor-Authentifizierung für die Anmeldung bei ihrem Account einzurichten.", + "ssoauth_form_hint_register": "Füge ein CryptPad-Passwort für zusätzliche Sicherheit hinzu oder lasse es leer und fahre fort. Wenn du kein Passwort hinzufügst, können die Administratoren der Instanz auf die Schlüssel zum Schutz deiner Daten zugreifen.", + "ssoauth_form_hint_login": "Bitte gib dein CryptPad-Passwort ein", + "loading_mfa_required": "Auf dieser Instanz ist eine Zwei-Faktor-Authentifizierung erforderlich. Bitte aktualisiere deinen Account mit einer Authentifizierungs-App und dem folgenden Formular.", + "calendar_description": "Beschreibung:{0}{1}", + "duplicate": "Duplizieren", + "kanban_hideTags": "Weniger Tags anzeigen", + "kanban_showTags": "Alle Tags anzeigen", + "sso_login_description": "Einloggen mit", + "sso_register_description": "Registrieren mit", + "ssoauth_header": "CryptPad-Passwort", + "calendar_rec_change": "Ein sich wiederholendes Ereignis wird in einen anderen Kalender verschoben. Du kannst diese Änderung nur auf dieses Ereignis oder alle wiederholten Ereignisse anwenden.", + "calendar_rec_change_first": "Das erste sich wiederholende Ereignis wird in einen anderen Kalender verschoben. Alle wiederholten Ereignisse werden ebenfalls verschoben.", + "admin_forcemfaTitle": "Verpflichtende Zwei-Faktor-Authentifizierung" } From 746012678103089dc151ef82d06440349e1d42b5 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 19 Dec 2023 16:14:18 +0100 Subject: [PATCH 154/283] Translated using Weblate (French) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (French) Currently translated at 99.8% (1679 of 1682 strings) Translated using Weblate (French) Currently translated at 100.0% (1679 of 1679 strings) Translated using Weblate (French) Currently translated at 100.0% (1676 of 1676 strings) Co-authored-by: David Benqué Co-authored-by: Mathilde Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/fr/ Translation: CryptPad/App --- www/common/translations/messages.fr.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 5fcd1e670..fa1822cb0 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1155,7 +1155,6 @@ "calendar_hours": "Heures", "calendar_minutes": "Minutes", "calendar_allDay": "Journée entière", - "calendar_location": "Lieu : {0}", "calendar_loc": "Lieu", "calendar_title": "Titre", "calendar_update": "Modifier", @@ -1679,5 +1678,8 @@ "sso_login_description": "Se connecter avec", "duplicate": "Dupliquer", "kanban_showTags": "Voir toutes les étiquettes", - "kanban_hideTags": "Voir moins d'étiquettes" + "kanban_hideTags": "Voir moins d'étiquettes", + "admin_forcemfaTitle": "Authentification à deux facteurs obligatoire", + "admin_forcemfaHint": "Tous les utilisateurs de cette instance seront obligés d'activer l'authentification à deux facteurs pour se connecter à leur compte.", + "loading_mfa_required": "L'authentification à deux facteurs est requise pour cette instance. Veuillez mettre à jour votre compte en utilisant une application d'authentification et le formulaire ci-dessous." } From e65baebadc3d1153b0deccb935ab27da759c64a2 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 19 Dec 2023 17:59:56 +0100 Subject: [PATCH 155/283] Restrict SSO registration --- customize.dist/login.js | 4 +- customize.dist/pages/register.js | 2 + .../src/less2/pages/page-register.less | 3 + lib/commands/admin-rpc.js | 2 + lib/commands/block.js | 8 +- lib/decrees.js | 2 + lib/http-worker.js | 1 + www/admin/inner.js | 96 +++++++++++++++---- www/register/main.js | 5 +- www/ssoauth/main.js | 18 +++- 10 files changed, 111 insertions(+), 30 deletions(-) diff --git a/customize.dist/login.js b/customize.dist/login.js index 9a05d63a0..2781dd0b6 100644 --- a/customize.dist/login.js +++ b/customize.dist/login.js @@ -49,9 +49,11 @@ define([ Exports.ssoAuth = function (provider, cb) { var keys = Nacl.sign.keyPair(); + var inviteToken = window.location.hash.slice(1); localStorage.CP_sso_auth = JSON.stringify({ s: Nacl.util.encodeBase64(keys.secretKey), - p: Nacl.util.encodeBase64(keys.publicKey) + p: Nacl.util.encodeBase64(keys.publicKey), + token: inviteToken }); ServerCommand(keys, { command: 'SSO_AUTH', diff --git a/customize.dist/pages/register.js b/customize.dist/pages/register.js index cf3fb256a..fde495c49 100644 --- a/customize.dist/pages/register.js +++ b/customize.dist/pages/register.js @@ -56,6 +56,7 @@ define([ h('h2', Msg.register_notes_title), Pages.setHTML(h('div.cp-register-notes'), Msg.register_notes) ]), + h('div.col-md-3.cp-closed-filler'+ssoEnabled, h('div')), h('div.cp-reg-form.col-md-6', [ h('div#userForm.form-group'+ssoEnforced, [ h('div.cp-register-instance', [ @@ -105,6 +106,7 @@ define([ h('div.cp-register-sso', Msg.sso_register_description) ]), ]), + h('div.col-md-3.cp-closed-filler'+ssoEnabled), ]) ]); }; diff --git a/customize.dist/src/less2/pages/page-register.less b/customize.dist/src/less2/pages/page-register.less index 546af842b..9e5d5caee 100644 --- a/customize.dist/src/less2/pages/page-register.less +++ b/customize.dist/src/less2/pages/page-register.less @@ -22,6 +22,9 @@ .cp-restricted-registration { display: none; } + .cp-closed-filler { + display: none; + } } &.cp-register-closed { div.cp-register-det { diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index e87911149..b4b6af536 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -461,6 +461,8 @@ var setLastEviction = function (Env, Server, cb, data, unsafeKey) { var instanceStatus = function (Env, Server, cb) { cb(void 0, { restrictRegistration: Env.restrictRegistration, + restrictSsoRegistration: Env.restrictSsoRegistration, + enableEmbedding: Env.enableEmbedding, launchTime: Env.launchTime, currentTime: +new Date(), diff --git a/lib/commands/block.js b/lib/commands/block.js index 451e9a422..c6723f724 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -111,7 +111,7 @@ Block.validateAncestorProof = function (Env, proof, _cb) { Block.writeLoginBlock = function (Env, msg, _cb) { var cb = Util.once(Util.mkAsync(_cb)); - const { publicKey, signature, ciphertext, registrationProof, userData, inviteToken } = msg; + const { publicKey, signature, ciphertext, registrationProof, userData, inviteToken, isSSO } = msg; var previousKey; var validatedBlock, path; @@ -123,9 +123,11 @@ Block.writeLoginBlock = function (Env, msg, _cb) { if (err || !state) { return; } // Invalid token, don't abort, check registration proof validatedInvite = true; })); + }).nThen(function (w) { }).nThen(function (w) { if (!Env.restrictRegistration) { return; } - if (!registrationProof && !validatedInvite) { + var ssoAllowed = isSSO && !Env.restrictSsoRegistration + if (!(registrationProof || validatedInvite || ssoAllowed)) { // we allow users with existing blocks to create new ones // call back with error if registration is restricted and no proof of an existing block was provided w.abort(); @@ -134,9 +136,9 @@ Block.writeLoginBlock = function (Env, msg, _cb) { }); return cb("E_RESTRICTED"); } + if (!registrationProof) { return; } Block.validateAncestorProof(Env, registrationProof, w(function (err, provenKey) { if (err || !provenKey) { // double check that a key was validated - if (validatedInvite) { return; } w.abort(); Env.Log.warn('BLOCK_REJECTED_INVALID_ANCESTOR', { error: err, diff --git a/lib/decrees.js b/lib/decrees.js index 1f81db056..952700aea 100644 --- a/lib/decrees.js +++ b/lib/decrees.js @@ -10,6 +10,7 @@ var Core = require("./commands/core"); IMPLEMENTED: RESTRICT_REGISTRATION() +RESTRICT_SSO_REGISTRATION() UPDATE_DEFAULT_STORAGE() // QUOTA MANAGEMENT @@ -112,6 +113,7 @@ commands.ENFORCE_MFA = makeBooleanSetter('enforceMFA'); // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['RESTRICT_REGISTRATION', [true]]], console.log) commands.RESTRICT_REGISTRATION = makeBooleanSetter('restrictRegistration'); +commands.RESTRICT_SSO_REGISTRATION = makeBooleanSetter('restrictSsoRegistration'); // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['DISABLE_INTEGRATED_EVICTION', [true]]], console.log) commands.DISABLE_INTEGRATED_EVICTION = makeBooleanSetter('disableIntegratedEviction'); diff --git a/lib/http-worker.js b/lib/http-worker.js index 185ae748e..cdf7678e4 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -579,6 +579,7 @@ var serveConfig = makeRouteCache(function () { maxUploadSize: Env.maxUploadSize, premiumUploadSize: Env.premiumUploadSize, restrictRegistration: Env.restrictRegistration, + restrictSsoRegistration: Env.restrictSsoRegistration, httpSafeOrigin: Env.httpSafeOrigin, enableEmbedding: Env.enableEmbedding, fileHost: Env.fileHost, diff --git a/www/admin/inner.js b/www/admin/inner.js index 29e04be92..d6af245e8 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -1495,29 +1495,81 @@ Example }; // Msg.admin_registrationHint, .admin_registrationTitle - create['registration'] = makeAdminCheckbox({ - key: 'registration', - getState: function () { - return APP.instanceStatus.restrictRegistration; - }, - query: function (val, setState) { - sFrameChan.query('Q_ADMIN_RPC', { - cmd: 'ADMIN_DECREE', - data: ['RESTRICT_REGISTRATION', [val]] - }, function (e, response) { - if (e || response.error) { - UI.warn(Messages.error); - console.error(e, response); - } - APP.updateStatus(function () { - setState(APP.instanceStatus.restrictRegistration); - flushCacheNotice(); + // Msg.admin_registrationSsoTitle + Messages.admin_registrationSsoTitle = "ALSO CLOSE SSO REGISTRATION"; // XXX + create['registration'] = function () { + var key = 'registration'; + + var refresh = function () {}; + + var $div = makeAdminCheckbox({ + key: 'registration', + getState: function () { + return APP.instanceStatus.restrictRegistration; + }, + query: function (val, setState) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'ADMIN_DECREE', + data: ['RESTRICT_REGISTRATION', [val]] + }, function (e, response) { + if (e || response.error) { + UI.warn(Messages.error); + console.error(e, response); + } + APP.updateStatus(function () { + setState(APP.instanceStatus.restrictRegistration); + refresh(); + flushCacheNotice(); + }); }); - }); - }, - }); + } + })(); + + var $sso = makeAdminCheckbox({ + key: 'registration-sso', + getState: function () { + return APP.instanceStatus.restrictSsoRegistration; + }, + query: function (val, setState) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'ADMIN_DECREE', + data: ['RESTRICT_SSO_REGISTRATION', [val]] + }, function (e, response) { + if (e || response.error) { + UI.warn(Messages.error); + console.error(e, response); + } + APP.updateStatus(function () { + setState(APP.instanceStatus.restrictSsoRegistration); + flushCacheNotice(); + }); + }); + } + })(); + var ssoEnabled = ApiConfig.sso && ApiConfig.sso.list && ApiConfig.sso.list.length; + if (ssoEnabled) { + $sso.find('#cp-admin-registration-sso').hide(); + $sso.find('> span.cp-sidebarlayout-description').hide(); + $div.append($sso); + } + + refresh = () => { + var closed = APP.instanceStatus.restrictRegistration; + if (closed) { + $sso.show(); + } else { + $sso.hide(); + } + }; + refresh(); + + + return $div; + }; Messages.admin_invitationCreate = "Create invitation link"; // XXX + Messages.admin_invitationHint = "Create invitation links to allow users to register even when registration is closed"; + Messages.admin_invitationTitle = "Invitation links"; create['invitation'] = function () { var key = 'invitation'; var $div = makeBlock(key); // Msg.admin_invitationHint, admin_invitationTitle @@ -1610,7 +1662,9 @@ Example return $div; }; - Messages.admin_usersAdd = "Add known user"; + Messages.admin_usersAdd = "Add known user"; // XXX + Messages.admin_userHint = "List of known users. You can add more using the form and select automated options"; + Messages.admin_userTitle = "Known users"; create['users'] = function () { var key = 'users'; var $div = makeBlock(key); // Msg.admin_usersHint, admin_usersTitle diff --git a/www/register/main.js b/www/register/main.js index 3af579459..cf7829a0a 100644 --- a/www/register/main.js +++ b/www/register/main.js @@ -34,6 +34,10 @@ define([ var hash = window.location.hash.slice(1); token = hash; $('body').removeClass('cp-register-closed'); + } else if (Config.sso && Config.restrictRegistration && !Config.restrictSsoRegistration) { + $('body').find('.cp-register-det').css('display', 'flex'); + $('body').find('#data').hide(); + $('body').find('#userForm').hide(); } // text and password input fields @@ -69,7 +73,6 @@ define([ var list = Config.sso.list.map(function (name) { var b = h('button.btn.btn-secondary', name); var $b = $(b).click(function () { - console.log('sso register click:', name); $b.prop('disabled', 'disabled'); Login.ssoAuth(name, function (err, data) { if (data.url) { diff --git a/www/ssoauth/main.js b/www/ssoauth/main.js index a32f6bad2..9535a72c7 100644 --- a/www/ssoauth/main.js +++ b/www/ssoauth/main.js @@ -33,19 +33,22 @@ define([ secretKey: Nacl.util.decodeBase64(b64Keys.s), publicKey: Nacl.util.decodeBase64(b64Keys.p) }; + var inviteToken = b64Keys.token; ServerCommand(keys, { command: 'SSO_AUTH_CB', url: window.location.href }, function (err, data) { delete localStorage.CP_sso_auth; document.cookie = 'ssotoken=; Max-Age=-99999999;'; + if (data) { data.inviteToken = inviteToken; } cb(err, data); }); }; - let ssoLoginRegister = function (seed, pw, jwt, name, isRegister) { + let ssoLoginRegister = function (seed, pw, jwt, name, isRegister, inviteToken) { Login.loginOrRegister({ uname: seed, passwd: pw, + token: inviteToken, isRegister: isRegister, onOTP: UI.getOTPScreen, ssoAuth: { @@ -97,7 +100,7 @@ define([ hideTips: true, }); setTimeout(function () { // Second timeout for the loading screen befofe Scrypt - ssoLoginRegister(seed, pw, jwt, name, data.register); + ssoLoginRegister(seed, pw, jwt, name, data.register, data.inviteToken); }, 100); }, 100); @@ -108,6 +111,10 @@ define([ return void next(''); } + if (data.register && ApiConfig.restrictSsoRegistration && !data.inviteToken) { + return void UI.errorLoadingScreen(Messages.register_registrationIsClosed); + } + // Registration and CP password disabled, continue if (data.register && !ApiConfig.sso.password) { return void next(''); @@ -130,14 +137,17 @@ define([ $button.click(() => { let pw = $pw.val(); + let warning = Messages._getKey('register_passwordTooShort', [ + Cred.MINIMUM_PASSWORD_LENGTH + ]); if (data.register && pw !== $pw2.val()) { return void UI.warn(Messages.register_passwordsDontMatch); } if (data.register && pw && !Cred.isLongEnoughPassword(pw)) { - return void UI.warn(Messages.register_passwordTooShort); + return void UI.warn(warning); } if (data.register && !pw && ApiConfig.sso.password === 2) { - return void UI.warn(Messages.register_passwordTooShort); + return void UI.warn(warning); } $button.prop('disabled', 'disabled'); From c87f052f006d3d1ce56d156422d2a5dd76380e9c Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:55 +0100 Subject: [PATCH 156/283] Translated using Weblate (Ukrainian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 68.0% (1144 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/uk/ Translation: CryptPad/App --- www/common/translations/messages.uk.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.uk.json b/www/common/translations/messages.uk.json index a0b3f28ec..914fe77e5 100644 --- a/www/common/translations/messages.uk.json +++ b/www/common/translations/messages.uk.json @@ -1031,7 +1031,6 @@ "calendar_hours": "Години", "calendar_minutes": "Хвилини", "calendar_allDay": "Весь день", - "calendar_location": "Місце: {0}", "calendar_loc": "Місце", "calendar_title": "Заголовок", "calendar_update": "Оновити", From 14cf88c02b2aa6f6b7a0682a0761fed2665294c6 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:55 +0100 Subject: [PATCH 157/283] Translated using Weblate (Czech) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 84.2% (1417 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/cs/ Translation: CryptPad/App --- www/common/translations/messages.cs.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.cs.json b/www/common/translations/messages.cs.json index f57b72c40..8769febb3 100644 --- a/www/common/translations/messages.cs.json +++ b/www/common/translations/messages.cs.json @@ -635,7 +635,6 @@ "calendar_hours": "Hodin", "calendar_minutes": "Minut", "calendar_allDay": "Celý den", - "calendar_location": "Místo: {0}", "calendar_loc": "Místo", "calendar_title": "Nadpis", "calendar_update": "Uložit", From b6a1514f07a1618499ade8a73760e348b34a64fb Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:55 +0100 Subject: [PATCH 158/283] Translated using Weblate (Spanish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 91.9% (1547 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/es/ Translation: CryptPad/App --- www/common/translations/messages.es.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.es.json b/www/common/translations/messages.es.json index 896967246..2c3df1e42 100644 --- a/www/common/translations/messages.es.json +++ b/www/common/translations/messages.es.json @@ -950,7 +950,6 @@ "calendar_hours": "Horas", "calendar_minutes": "Minutos", "calendar_allDay": "Todo el día", - "calendar_location": "Localización: {0}", "calendar_loc": "Localización", "calendar_title": "Título", "calendar_dateTimeRange": "{0} {1} - {2}", From c2f66383c471d0fb88fd8d4bed1d38137f97ceb8 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:56 +0100 Subject: [PATCH 159/283] Translated using Weblate (Chinese (Simplified)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 89.4% (1505 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/zh_Hans/ Translation: CryptPad/App --- www/common/translations/messages.zh.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.zh.json b/www/common/translations/messages.zh.json index 5f36f370a..604e64ab9 100644 --- a/www/common/translations/messages.zh.json +++ b/www/common/translations/messages.zh.json @@ -1236,7 +1236,6 @@ "calendar_hours": "小时", "calendar_minutes": "分钟", "calendar_allDay": "全天", - "calendar_location": "位置:{0}", "calendar_loc": "地点", "calendar_title": "标题", "calendar_update": "更新", From 72ad8754e6f7be5bda15691a0a7ae8c14986db8f Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:56 +0100 Subject: [PATCH 160/283] Translated using Weblate (Catalan) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 64.5% (1085 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ca/ Translation: CryptPad/App --- www/common/translations/messages.ca.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ca.json b/www/common/translations/messages.ca.json index 8485bdf19..1854164ef 100644 --- a/www/common/translations/messages.ca.json +++ b/www/common/translations/messages.ca.json @@ -1421,7 +1421,6 @@ "calendar_deleteTeamConfirm": "Esteu segur que voleu suprimir aquest calendari de l'equip?", "calendar_deleteOwned": "Continuarà sent visible per a altres usuaris amb els quals s'ha compartit.", "calendar_newEvent": "Esdeveniment nou", - "calendar_location": "Ubicació: {0}", "calendar_more": "{0} més", "reminder_missed": "{0} va tenir lloc el {1}", "reminder_now": "{0} ha començat", From 9fd710bd9015b37d5a71d094b6da6a18fcf897d5 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:57 +0100 Subject: [PATCH 161/283] Translated using Weblate (Finnish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 73.0% (1228 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/fi/ Translation: CryptPad/App --- www/common/translations/messages.fi.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.fi.json b/www/common/translations/messages.fi.json index 04002ceae..a4881c436 100644 --- a/www/common/translations/messages.fi.json +++ b/www/common/translations/messages.fi.json @@ -1173,7 +1173,6 @@ "calendar_update": "Päivitä", "calendar_title": "Otsikko", "calendar_loc": "Sijainti", - "calendar_location": "Sijainti: {0}", "calendar_allDay": "Koko päivä", "calendar_minutes": "Minuutit", "calendar_hours": "Tunnit", From cbd65f108908e3d2edcd5aa90c42dd7c415887dc Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:57 +0100 Subject: [PATCH 162/283] Translated using Weblate (Indonesian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.0% (1666 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/id/ Translation: CryptPad/App --- www/common/translations/messages.id.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.id.json b/www/common/translations/messages.id.json index 3a927a872..334172693 100644 --- a/www/common/translations/messages.id.json +++ b/www/common/translations/messages.id.json @@ -915,7 +915,6 @@ "calendar_default": "Kalender saya", "calendar_new": "Kalender baru", "calendar_newEvent": "Acara baru", - "calendar_location": "Lokasi: {0}", "calendar_allDay": "Seharian", "reminder_inProgressAllDay": "Hari ini: {0}", "admin_supportPrivButton": "Tampilkan kunci", From 803b5e0b8f07a6987d1b3242e9821e8e41ccc7eb Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:58 +0100 Subject: [PATCH 163/283] Translated using Weblate (Italian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 68.9% (1160 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/it/ Translation: CryptPad/App --- www/common/translations/messages.it.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.it.json b/www/common/translations/messages.it.json index 099b208fc..cf769477a 100644 --- a/www/common/translations/messages.it.json +++ b/www/common/translations/messages.it.json @@ -1098,7 +1098,6 @@ "broadcast_end": "Termina", "broadcast_maintenance": "Una manutenzione è programmata tra {0} e {1}. CryptPad potrebbe non essere disponibile in quel lasso di tempo.", "admin_surveyTitle": "Sondaggio", - "calendar_location": "Posizione: {0}", "admin_surveyButton": "Salva sondaggio", "admin_surveyActive": "Apri sondaggio", "calendar_minutes": "Minuti", From 9302b46197be75da5610a39fff48969ebaf3d44a Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:58 +0100 Subject: [PATCH 164/283] Translated using Weblate (Japanese) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 96.2% (1619 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ja/ Translation: CryptPad/App --- www/common/translations/messages.ja.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ja.json b/www/common/translations/messages.ja.json index 1c139d00e..f3239c85b 100644 --- a/www/common/translations/messages.ja.json +++ b/www/common/translations/messages.ja.json @@ -940,7 +940,6 @@ "calendar_hours": "時間", "calendar_minutes": "分", "calendar_allDay": "全日", - "calendar_location": "場所: {0}", "calendar_loc": "場所", "calendar_title": "タイトル", "calendar_update": "更新", From 31f82c3306e2f75ee5815cd4797c339724ff60b4 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:59 +0100 Subject: [PATCH 165/283] Translated using Weblate (Dutch) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 37.9% (638 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/nl/ Translation: CryptPad/App --- www/common/translations/messages.nl.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.nl.json b/www/common/translations/messages.nl.json index b8cc5dd72..022193059 100644 --- a/www/common/translations/messages.nl.json +++ b/www/common/translations/messages.nl.json @@ -522,7 +522,6 @@ "calendar_import": "Voeg toe aan mijn agenda's", "calendar_dateTimeRange": "{0} {1} - {2}", "calendar_title": "Titel", - "calendar_location": "Plaats: {0}", "calendar_minutes": "Minuten", "calendar_addNotification": "Voeg herinnering toe", "register_registrationIsClosed": "Registratie is gesloten.", From 67b362be2f695215b7b1f8e0cf91a9327cdd19d4 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:58:59 +0100 Subject: [PATCH 166/283] Translated using Weblate (Polish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 82.1% (1381 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/pl/ Translation: CryptPad/App --- www/common/translations/messages.pl.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.pl.json b/www/common/translations/messages.pl.json index 06a49e655..f86939792 100644 --- a/www/common/translations/messages.pl.json +++ b/www/common/translations/messages.pl.json @@ -899,7 +899,6 @@ "calendar_hours": "Godziny", "calendar_minutes": "Minuty", "calendar_allDay": "Cały dzień", - "calendar_location": "Lokalizacja: {0}", "calendar_loc": "Lokalizacja", "calendar_title": "Tytuł", "calendar_update": "Zaktualizuj", From 30bc01d28eed2524ccac7cc59046bc42967ae882 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:00 +0100 Subject: [PATCH 167/283] Translated using Weblate (Portuguese (Brazil)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 98.9% (1664 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/pt_BR/ Translation: CryptPad/App --- www/common/translations/messages.pt-br.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.pt-br.json b/www/common/translations/messages.pt-br.json index 7159d8b03..8026159d8 100644 --- a/www/common/translations/messages.pt-br.json +++ b/www/common/translations/messages.pt-br.json @@ -1235,7 +1235,6 @@ "calendar_hours": "Horas", "calendar_minutes": "Minutos", "calendar_allDay": "O dia todo", - "calendar_location": "Localização: {0}", "calendar_loc": "Local", "calendar_title": "Título", "calendar_update": "Atualizar", From ad97cc987c1eb6a97ca5b7d04edff6c529aebad8 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:00 +0100 Subject: [PATCH 168/283] Translated using Weblate (Portuguese (Portugal)) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 80.6% (1356 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/pt_PT/ Translation: CryptPad/App --- www/common/translations/messages.pt-pt.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.pt-pt.json b/www/common/translations/messages.pt-pt.json index 4be7f68b0..e6c82a531 100644 --- a/www/common/translations/messages.pt-pt.json +++ b/www/common/translations/messages.pt-pt.json @@ -1234,7 +1234,6 @@ "calendar_hours": "Horas", "calendar_minutes": "Minutos", "calendar_allDay": "O dia todo", - "calendar_location": "Localização: {0}", "calendar_loc": "Local", "calendar_title": "Título", "calendar_update": "Atualizar", From a1ba90f87738f39267f64256d37cfbeb5267365d Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:01 +0100 Subject: [PATCH 169/283] Translated using Weblate (Russian) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 93.7% (1577 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ru/ Translation: CryptPad/App --- www/common/translations/messages.ru.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ru.json b/www/common/translations/messages.ru.json index 6ee081441..355ff6335 100644 --- a/www/common/translations/messages.ru.json +++ b/www/common/translations/messages.ru.json @@ -1337,7 +1337,6 @@ "calendar_hours": "Часа(ов)", "calendar_minutes": "Минут(ы)", "calendar_allDay": "Весь день", - "calendar_location": "Место: {0}", "calendar_loc": "Место", "calendar_title": "Заголовок", "calendar_update": "Обновить", From 5f5a28484f60ca3ad0d0b61670d02980aff24e1b Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:01 +0100 Subject: [PATCH 170/283] Translated using Weblate (Swedish) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 99.0% (1666 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/sv/ Translation: CryptPad/App --- www/common/translations/messages.sv.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.sv.json b/www/common/translations/messages.sv.json index e8c903b0c..6f3aafa9b 100644 --- a/www/common/translations/messages.sv.json +++ b/www/common/translations/messages.sv.json @@ -650,7 +650,6 @@ "calendar_month": "Månad", "calendar_title": "Rubrik", "calendar_noNotification": "Ingen", - "calendar_location": "Plats: {0}", "settings_notifCalendarTitle": "Kalenderaviseringar", "mediatag_defaultImageName": "bild", "share_formAuditor": "Granskare", From d23972bce99bdbfd2dc8fdf6da5be6d280268b30 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:02 +0100 Subject: [PATCH 171/283] Translated using Weblate (Arabic) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 96.3% (1620 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/ar/ Translation: CryptPad/App --- www/common/translations/messages.ar.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.ar.json b/www/common/translations/messages.ar.json index e9a1d3bc5..f69f365ab 100644 --- a/www/common/translations/messages.ar.json +++ b/www/common/translations/messages.ar.json @@ -1165,7 +1165,6 @@ "calendar_update": "حَدِّثْ", "calendar_title": "عنوان", "calendar_loc": "موقع", - "calendar_location": "الموقع: {0}", "calendar_hours": "ساعات", "calendar_noNotification": "بدون إشعار", "calendar_allDay": "طوال اليوم", From 3e2e48a294935813a5832f06a0d5821b9e7335e9 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:02 +0100 Subject: [PATCH 172/283] Translated using Weblate (Basque) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 98.8% (1662 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/eu/ Translation: CryptPad/App --- www/common/translations/messages.eu.json | 1 - 1 file changed, 1 deletion(-) diff --git a/www/common/translations/messages.eu.json b/www/common/translations/messages.eu.json index f83f56c13..827b1bde0 100644 --- a/www/common/translations/messages.eu.json +++ b/www/common/translations/messages.eu.json @@ -1048,7 +1048,6 @@ "calendar_hours": "Orduak", "calendar_minutes": "Minutuak", "calendar_allDay": "Egunero", - "calendar_location": "Kokapena: {0}", "calendar_loc": "Kokapena", "calendar_title": "Izena", "calendar_update": "Eguneratu", From c615a97997fa3531db154e58598a6a3351239c62 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:03 +0100 Subject: [PATCH 173/283] Translated using Weblate (German) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (German) Currently translated at 99.1% (1667 of 1682 strings) Co-authored-by: David Benqué Co-authored-by: Jan Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/de/ Translation: CryptPad/App --- www/common/translations/messages.de.json | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 34a175d68..8528dc3f3 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -479,7 +479,7 @@ "mdToolbar_list": "Aufzählung", "mdToolbar_check": "Aufgabenliste", "mdToolbar_code": "Code", - "home_host": "Dies ist eine unabhängige Installation der CrypPad-Software.", + "home_host": "Dies ist eine unabhängige Instanz von CryptPad.", "main_catch_phrase": "Suite zur Zusammenarbeit
Ende-zu-Ende-verschlüsselt und quelloffen", "about": "Über uns", "privacy": "Datenschutzerklärung", @@ -1167,7 +1167,6 @@ "calendar_hours": "Stunden", "calendar_minutes": "Minuten", "calendar_allDay": "Ganztägig", - "calendar_location": "Ort: {0}", "calendar_loc": "Ort", "calendar_title": "Titel", "calendar_update": "Aktualisieren", @@ -1667,5 +1666,20 @@ "status": "Statusseite", "access_passwordUsed": "Dieses Passwort wurde bereits für dieses Dokument verwendet. Es kann nicht erneut verwendet werden.", "admin_diskUsageWarning": "Mit Vorsicht zu verwenden! Je nach Größe der auf der Instanz gespeicherten Daten kann die Erstellung dieses Berichts den gesamten auf dem Server verfügbaren Speicher verbrauchen und zu einem Absturz führen.", - "dph_sf_destroyed": "Geteilter Ordner {0} wurde vom Eigentümer zerstört" + "dph_sf_destroyed": "Geteilter Ordner {0} wurde vom Eigentümer zerstört", + "calendar_desc": "Beschreibung", + "admin_forcemfaHint": "Alle Benutzer dieser Instanz werden aufgefordert, eine Zwei-Faktor-Authentifizierung für die Anmeldung bei ihrem Account einzurichten.", + "ssoauth_form_hint_register": "Füge ein CryptPad-Passwort für zusätzliche Sicherheit hinzu oder lasse es leer und fahre fort. Wenn du kein Passwort hinzufügst, können die Administratoren der Instanz auf die Schlüssel zum Schutz deiner Daten zugreifen.", + "ssoauth_form_hint_login": "Bitte gib dein CryptPad-Passwort ein", + "loading_mfa_required": "Auf dieser Instanz ist eine Zwei-Faktor-Authentifizierung erforderlich. Bitte aktualisiere deinen Account mit einer Authentifizierungs-App und dem folgenden Formular.", + "calendar_description": "Beschreibung:{0}{1}", + "duplicate": "Duplizieren", + "kanban_hideTags": "Weniger Tags anzeigen", + "kanban_showTags": "Alle Tags anzeigen", + "sso_login_description": "Einloggen mit", + "sso_register_description": "Registrieren mit", + "ssoauth_header": "CryptPad-Passwort", + "calendar_rec_change": "Ein sich wiederholendes Ereignis wird in einen anderen Kalender verschoben. Du kannst diese Änderung nur auf dieses Ereignis oder alle wiederholten Ereignisse anwenden.", + "calendar_rec_change_first": "Das erste sich wiederholende Ereignis wird in einen anderen Kalender verschoben. Alle wiederholten Ereignisse werden ebenfalls verschoben.", + "admin_forcemfaTitle": "Verpflichtende Zwei-Faktor-Authentifizierung" } From b8c686d1694952b46295f042d63f4f65ea6a953a Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 20 Dec 2023 15:59:03 +0100 Subject: [PATCH 174/283] Translated using Weblate (French) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (French) Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (French) Currently translated at 100.0% (1681 of 1681 strings) Translated using Weblate (French) Currently translated at 99.8% (1679 of 1682 strings) Translated using Weblate (French) Currently translated at 100.0% (1679 of 1679 strings) Translated using Weblate (French) Currently translated at 100.0% (1676 of 1676 strings) Co-authored-by: David Benqué Co-authored-by: Mathilde Co-authored-by: Weblate Translate-URL: https://weblate.cryptpad.org/projects/cryptpad/app/fr/ Translation: CryptPad/App --- www/common/translations/messages.fr.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 5fcd1e670..fd9ab2939 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1155,7 +1155,6 @@ "calendar_hours": "Heures", "calendar_minutes": "Minutes", "calendar_allDay": "Journée entière", - "calendar_location": "Lieu : {0}", "calendar_loc": "Lieu", "calendar_title": "Titre", "calendar_update": "Modifier", @@ -1671,13 +1670,16 @@ "calendar_rec_change_first": "Déplacer le premier événement répété vers un autre calendrier. Tous les autres événements seront aussi déplacés.", "calendar_desc": "Description", "sso_register_description": "S'enregistrer avec", - "calendar_description": "Description:{0}{1}", + "calendar_description": "Description : {0}{1}", "ssoauth_header": "Mot de passe CryptPad", "ssoauth_form_hint_login": "Veuillez entrer votre mot de passe CryptPad", "ssoauth_form_hint_register": "Ajouter un mot de passe CryptPad pour plus de sécurité ou laisser vide et continuer. Si vous n'ajoutez pas de mot de passe, les clés protégeant vos données seront accessibles aux administrateur·ices de l'instance.", "calendar_rec_change": "Déplacer un événement répété vers un autre calendrier. Vous pouvez appliquer ce changement seulement pour cet événement ou pour tous les événements répétés.", "sso_login_description": "Se connecter avec", "duplicate": "Dupliquer", - "kanban_showTags": "Voir toutes les étiquettes", - "kanban_hideTags": "Voir moins d'étiquettes" + "kanban_showTags": "Voir tous les mots-clés", + "kanban_hideTags": "Voir moins de mots-clés", + "admin_forcemfaTitle": "Authentification à deux facteurs obligatoire", + "admin_forcemfaHint": "Tous les utilisateurs de cette instance seront obligés d'activer l'authentification à deux facteurs pour se connecter à leur compte.", + "loading_mfa_required": "L'authentification à deux facteurs est requise pour cette instance. Veuillez mettre à jour votre compte en utilisant une application d'authentification et le formulaire ci-dessous." } From e377577364e950499e87f7d2db32ce2a842c3817 Mon Sep 17 00:00:00 2001 From: David Benque Date: Wed, 20 Dec 2023 15:24:55 +0000 Subject: [PATCH 175/283] Update Changelog --- CHANGELOG.md | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a227a522..87109b4e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,120 @@ SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and cont SPDX-License-Identifier: AGPL-3.0-or-later --> +# 5.6.0 + + +## Goals + +This release introduces support for integrating CryptPad instances with Single-Sign On authentication. It brings a lot of improvements and fixes to Form, Calendar, and other parts of CryptPad. This release begins to improve the accessibility of the toolbar towards full WCAG compliance which we hope to achieve in the near future. + +## Features + +- Authentication + - This version paves the way for SSO authentication for a CryptPad instance via a plugin (est. release Jan. 2024) [#1320](https://github.com/cryptpad/cryptpad/pull/1320) + - New setting to make Two-Factor Authentication mandatory for all user accounts on an instance [#1341](https://github.com/cryptpad/cryptpad/pull/1341) +- Form + - New button to duplicate a question [#1305](https://github.com/cryptpad/cryptpad/pull/1305) +- Calendar + - New description field for calendar events [#1299](https://github.com/cryptpad/cryptpad/pull/1299) + +## Improvements + +- Accessibility of toolbars and some drop-down menus [#1290](https://github.com/cryptpad/cryptpad/pull/1290) + - "+ New" drop-down menu in Drive and Team Drive #1191 + - New `Ctrl + e` modal #1192 + - Code contact request notifications as headings #1197 + - DOM order of toolbar #1198 + - Notifications menu not accessible via Keyboard #1201 + - Sidebar "tabs" not accessible via keyboard #1203 + - Implement keyboard navigation of toolbar menus #1209 + - CryptDrive page needs a logical tab order #1151 + - Elements not accessible using the keyboard #1162 + - Calendar event modal date-picker is cut-off at some screen resolutions #1280 + - Visible focus #1206 +- Rich Text + - Improvements to the Rich Text toolbar and layout for mobile usage [#1296](https://github.com/cryptpad/cryptpad/pull/1296) +- Calendar + - Handling the move of repeating events from a calendar to another [#1308](https://github.com/cryptpad/cryptpad/pull/1308) +- Kanban + - Changed positioning of kanban tag container on smaller screens [#1307](https://github.com/cryptpad/cryptpad/pull/1307) +- New option to increase the number of teams slots for premium users only [#1315](https://github.com/cryptpad/cryptpad/pull/1315) +- Improve licensing information, CryptPad code now complies with the [REUSE](https://reuse.software/) specifications [#1300](https://github.com/cryptpad/cryptpad/pull/1300) +- Deployment + - Basic configuration for Apache HTTPd [#1332](https://github.com/cryptpad/cryptpad/pull/1332) + - Add Docker health check [#1287](https://github.com/cryptpad/cryptpad/pull/1287) +- Cleanup + - Old // XXX comments [#1334](https://github.com/cryptpad/cryptpad/pull/1334) + - Outdated/misplaced files [#1327](https://github.com/cryptpad/cryptpad/pull/1327) + +## Fixes + +- Fix browser autocomplete issues (password, numbers, etc.) [#1342](https://github.com/cryptpad/cryptpad/pull/1342) +- Drive + - Container height fills screen [#1304](https://github.com/cryptpad/cryptpad/pull/1304) + - Context menu on mobile [#1301](https://github.com/cryptpad/cryptpad/pull/1301) +- OnlyOffice applications + - Use correct mime type for .wasm files (export functionality) [#1288](https://github.com/cryptpad/cryptpad/pull/1288) + - Fix filter functionality in Sheets [#1319](https://github.com/cryptpad/cryptpad/issues/1319) +- Form + - Fix an error upon importing a template in forms [#1316](https://github.com/cryptpad/cryptpad/pull/1316) + - Can now set form closing date/time on mobile [#1305](https://github.com/cryptpad/cryptpad/pull/1305) + - Can now edit time options for poll questions on mobile [#1305](https://github.com/cryptpad/cryptpad/pull/1305) + - Dates in CSV exports of forms are now in ISO (not timestamp) format [#1305](https://github.com/cryptpad/cryptpad/pull/1305) + - Page breaks are no longer visible in conditional sections when condition is not met [#1305](https://github.com/cryptpad/cryptpad/pull/1305) + - Final submission page now has margins [#1305](https://github.com/cryptpad/cryptpad/pull/1305) + - Question blocks on mobile are now only draggable at the top of the block to make scrolling possible [#1305](https://github.com/cryptpad/cryptpad/pull/1305) +- Whiteboard + - Fix a few export-related issues [#1328](https://github.com/cryptpad/cryptpad/pull/1328) +- Calendar + - Reformat `www/calendar/export.js` [#1314](https://github.com/cryptpad/cryptpad/pull/1314) + - Fix a bug with stopping the recurrence of a calendar event [#1312](https://github.com/cryptpad/cryptpad/pull/1312) + - Calendar creates itself twice when navigating with the keyboard [#1250](https://github.com/cryptpad/cryptpad/issues/1250) + - Fix timezone in Daylight Saving Time issues [#1317](https://github.com/cryptpad/cryptpad/pull/1317) +- Translations + - Revise the translation of `zh` [#1329](https://github.com/cryptpad/cryptpad/pull/1329) + +## Dependencies +- Added [Moment.js](http://momentjs.com/) for improved handling of dates in Calendar (added as part of [#1317](https://github.com/cryptpad/cryptpad/pull/1317)) + +## Deployment +We [fixed an issue with the Systemd service file and logging](https://github.com/cryptpad/cryptpad/commit/078095c3e25d39707bdaab7ec066ceed6cb7158b), you'll need to add the following lines to your `cryptpad.service` before continuing by following the upgrade notes below. + +```diff +# Restart service after 10 seconds if node service crashes +RestartSec=2 + ++ # Proper logging to journald ++ StandardOutput=journal ++ StandardError=journal+console + +User=cryptpad +Group=cryptpad +``` + +## Upgrade notes + +If you are upgrading from a version older than `5.5.0` please read the upgrade notes of all versions between yours and `5.5.0` to avoid configuration issues. + +To upgrade: + +1. Reload the Systemd daemon, required due to the changes in the **Deployment** section +```bash +sudo systemctl daemon-reload +``` + +2. Stop your server +3. Get the latest code with git +```bash +git fetch origin --tags +git checkout 5.6.0 +``` + +4. Restart your server +5. Review your instance's checkup page to ensure that you are passing all tests + + + # 5.5.0 ## Features From bfc03ddfae665893e414af79160bf4a512f0cd0e Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 20 Dec 2023 16:40:48 +0100 Subject: [PATCH 176/283] Fix lint translation script --- scripts/translations/lint-translations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/translations/lint-translations.js b/scripts/translations/lint-translations.js index f57bc14de..7a9d385ac 100644 --- a/scripts/translations/lint-translations.js +++ b/scripts/translations/lint-translations.js @@ -53,7 +53,7 @@ special_rules.fr = function (s) { ignore instances where the following character is a '/' because this is probably a URL (http(s)://) */ - return /\S[:;\?\!][^\/]{1,}/.test(s); + return /\S[:;\?\!][^\/]{1,}/.test(s.replace(/mailto:/g, " :")); }; var noop = function () {}; From a3f9b2eceb8c277848b168227e8d8dce6ef07ce4 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 20 Dec 2023 17:24:14 +0100 Subject: [PATCH 177/283] Store user data for new SSO accounts (configurable) --- lib/commands/admin-rpc.js | 2 ++ lib/commands/block.js | 42 +++++++++++++++++++------- lib/commands/invitation.js | 19 +++++++----- lib/commands/users.js | 2 ++ lib/decrees.js | 2 ++ www/admin/app-admin.less | 6 ++++ www/admin/inner.js | 60 +++++++++++++++++++++++++++++++++++--- www/common/common-login.js | 6 ++-- 8 files changed, 115 insertions(+), 24 deletions(-) diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index b4b6af536..bdc1cd086 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -462,6 +462,8 @@ var instanceStatus = function (Env, Server, cb) { cb(void 0, { restrictRegistration: Env.restrictRegistration, restrictSsoRegistration: Env.restrictSsoRegistration, + storeSSOUsers: Env.storeSSOUsers, + storeInvitedUsers: Env.storeInvitedUsers, enableEmbedding: Env.enableEmbedding, launchTime: Env.launchTime, diff --git a/lib/commands/block.js b/lib/commands/block.js index c6723f724..6ccef235b 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -123,10 +123,9 @@ Block.writeLoginBlock = function (Env, msg, _cb) { if (err || !state) { return; } // Invalid token, don't abort, check registration proof validatedInvite = true; })); - }).nThen(function (w) { }).nThen(function (w) { if (!Env.restrictRegistration) { return; } - var ssoAllowed = isSSO && !Env.restrictSsoRegistration + var ssoAllowed = isSSO && !Env.restrictSsoRegistration; if (!(registrationProof || validatedInvite || ssoAllowed)) { // we allow users with existing blocks to create new ones // call back with error if registration is restricted and no proof of an existing block was provided @@ -185,15 +184,38 @@ Block.writeLoginBlock = function (Env, msg, _cb) { }); } }); - if (!validatedInvite) { return; } - Invitation.use(Env, inviteToken, publicKey, userData, (err) => { - if (!err) { return; } - Env.Log.error('USE_INVITATION_LINK', { - inviteToken, - userData, - publicKey + + console.log(isSSO, Env.storeSSOUsers); + if (validatedInvite) { + Invitation.use(Env, inviteToken, publicKey, userData, (err) => { + if (!err) { return; } + Env.Log.error('USE_INVITATION_LINK', { + inviteToken, + userData, + publicKey + }); }); - }); + } else if (isSSO && Env.storeSSOUsers) { + console.log('LALALA'); + let edPublic = Array.isArray(userData) && userData[1]; + let name = Array.isArray(userData) && userData[0]; + if (!edPublic) { return; } + let data = { + block: publicKey, + name, + edPublic, + type: 'sso', + alias: name + }; + Users.add(Env, edPublic, data, null, (err) => { + if (err) { + Env.Log.error('INVITATION_ADD_USER', { + error: err, + data: data + }); + } + }); + } }); }; diff --git a/lib/commands/invitation.js b/lib/commands/invitation.js index e8c0437cf..05c0e6151 100644 --- a/lib/commands/invitation.js +++ b/lib/commands/invitation.js @@ -60,14 +60,17 @@ Invitation.use = (Env, id, blockId, userData, _cb) => { data.edPublic = edPublic; data.type = 'invite:' + id; let adminKey = data.createdBy; - Users.add(Env, edPublic, data, adminKey, (err) => { - if (err) { - Env.Log.error('INVITATION_ADD_USER', { - error: err, - data: data - }); - } - }); + console.log(Env.storeInvitedUsers, 'ICI', Env.storeInvitedUsers, Env.storeSSOUsers); + if (Env.storeInvitedUsers) { + Users.add(Env, edPublic, data, adminKey, (err) => { + if (err) { + Env.Log.error('INVITATION_ADD_USER', { + error: err, + data: data + }); + } + }); + } Invite.delete(Env, id, (err) => { if (err) { diff --git a/lib/commands/users.js b/lib/commands/users.js index 3fc161190..37f2203a9 100644 --- a/lib/commands/users.js +++ b/lib/commands/users.js @@ -7,6 +7,7 @@ const Util = require("../common-util"); Users.getAll = (Env, cb) => { User.getAll(Env, (err, data) => { if (err) { return void cb(err); } + console.log(data); cb(null, data); }); }; @@ -16,6 +17,7 @@ Users.add = (Env, edPublic, data, adminKey, _cb) => { data.createdBy = adminKey; data.time = +new Date(); const safeKey = Util.escapeKeyCharacters(edPublic); + console.log(edPublic, data); User.write(Env, safeKey, data, (err) => { if (err) { return void cb(err); } cb(); diff --git a/lib/decrees.js b/lib/decrees.js index 952700aea..f54d9975d 100644 --- a/lib/decrees.js +++ b/lib/decrees.js @@ -114,6 +114,8 @@ commands.ENFORCE_MFA = makeBooleanSetter('enforceMFA'); // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['RESTRICT_REGISTRATION', [true]]], console.log) commands.RESTRICT_REGISTRATION = makeBooleanSetter('restrictRegistration'); commands.RESTRICT_SSO_REGISTRATION = makeBooleanSetter('restrictSsoRegistration'); +commands.STORE_INVITED_USERS = makeBooleanSetter('storeInvitedUsers'); +commands.STORE_SSO_USERS = makeBooleanSetter('storeSSOUsers'); // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['DISABLE_INTEGRATED_EVICTION', [true]]], console.log) commands.DISABLE_INTEGRATED_EVICTION = makeBooleanSetter('disableIntegratedEviction'); diff --git a/www/admin/app-admin.less b/www/admin/app-admin.less index f674160ca..4e75ff7a9 100644 --- a/www/admin/app-admin.less +++ b/www/admin/app-admin.less @@ -246,6 +246,12 @@ } } + .cp-admin-users { + .cp-admin-store-invited, .cp-admin-store-sso { + margin-bottom: 0 !important; + } + } + .cp-admin-broadcast-form { input.flatpickr-input { width: 307.875px !important; // same width as flatpickr calendar diff --git a/www/admin/inner.js b/www/admin/inner.js index d6af245e8..438c3b5d5 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -1498,8 +1498,6 @@ Example // Msg.admin_registrationSsoTitle Messages.admin_registrationSsoTitle = "ALSO CLOSE SSO REGISTRATION"; // XXX create['registration'] = function () { - var key = 'registration'; - var refresh = function () {}; var $div = makeAdminCheckbox({ @@ -1663,8 +1661,10 @@ Example }; Messages.admin_usersAdd = "Add known user"; // XXX - Messages.admin_userHint = "List of known users. You can add more using the form and select automated options"; - Messages.admin_userTitle = "Known users"; + Messages.admin_usersHint = "List of known users. You can add more using the form and select automated options"; + Messages.admin_usersTitle = "Known users"; + Messages.admin_storeInvitedLabel = "Automatically store invited users"; // XXX + Messages.admin_storeSsoLabel = "Automatically store SSO users"; create['users'] = function () { var key = 'users'; var $div = makeBlock(key); // Msg.admin_usersHint, admin_usersTitle @@ -1680,6 +1680,58 @@ Example var refreshUsers = function () {}; + var $invited = makeAdminCheckbox({ + key: 'store-invited', + getState: function () { + return APP.instanceStatus.storeInvitedUsers; + }, + query: function (val, setState) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'ADMIN_DECREE', + data: ['STORE_INVITED_USERS', [val]] + }, function (e, response) { + if (e || response.error) { + UI.warn(Messages.error); + console.error(e, response); + } + APP.updateStatus(function () { + setState(APP.instanceStatus.storeInvitedUsers); + flushCacheNotice(); + }); + }); + } + })(); + $invited.find('#cp-admin-store-invited').hide(); + $invited.find('> span.cp-sidebarlayout-description').hide(); + $div.append($invited); + var $sso = makeAdminCheckbox({ + key: 'store-sso', + getState: function () { + return APP.instanceStatus.storeSSOUsers; + }, + query: function (val, setState) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'ADMIN_DECREE', + data: ['STORE_SSO_USERS', [val]] + }, function (e, response) { + if (e || response.error) { + UI.warn(Messages.error); + console.error(e, response); + } + APP.updateStatus(function () { + setState(APP.instanceStatus.storeSSOUsers); + flushCacheNotice(); + }); + }); + } + })(); + var ssoEnabled = ApiConfig.sso && ApiConfig.sso.list && ApiConfig.sso.list.length; + if (ssoEnabled) { + $sso.find('#cp-admin-store-sso').hide(); + $sso.find('> span.cp-sidebarlayout-description').hide(); + $div.append($sso); + } + var deleteUser = function (/*id*/) { /* sFrameChan.query('Q_ADMIN_RPC', { diff --git a/www/common/common-login.js b/www/common/common-login.js index 2ea0d68ef..a0ec61be4 100644 --- a/www/common/common-login.js +++ b/www/common/common-login.js @@ -516,8 +516,10 @@ define([ // FIXME We currently can't create an account with OTP by default // NOTE If we ever want to do that for SSO accounts it will require major changes // because writeLoginBlock only supports one type of authentication at a time - var userData; - if (token) { userData = [uname, RT.proxy.edPublic]; } + + // XXX userData always sent, maybe only for SSO and token? + // Only SSO users and invited users can be soted by the server and it needs to be configured + var userData = [uname, RT.proxy.edPublic]; Block.writeLoginBlock({ pw: Boolean(passwd), auth: ssoAuth, From adef679b4bc2e4fa93814931e758f10ff0851909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Wed, 20 Dec 2023 18:13:19 +0100 Subject: [PATCH 178/283] update Dockerfile to match new configuration example --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index cd8397bfd..745dd472f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ WORKDIR /cryptpad # Copy CryptPad source code to the container COPY . /cryptpad -RUN sed -i "s@//httpAddress: '::'@httpAddress: '0.0.0.0'@" /cryptpad/config/config.example.js +RUN sed -i "s@//httpAddress: 'localhost'@httpAddress: '0.0.0.0'@" /cryptpad/config/config.example.js RUN sed -i "s@installMethod: 'unspecified'@installMethod: 'docker'@" /cryptpad/config/config.example.js # Install wget for healthcheck From c79e8765e92ff247e987319c3161b0903ab8d924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Thu, 21 Dec 2023 11:54:50 +0100 Subject: [PATCH 179/283] add 5.6.0 as a default version in bug template, removed very old 4.x stuff --- .github/ISSUE_TEMPLATE/bug_resolution.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_resolution.yml b/.github/ISSUE_TEMPLATE/bug_resolution.yml index 9e8efa655..a7dcf2d13 100644 --- a/.github/ISSUE_TEMPLATE/bug_resolution.yml +++ b/.github/ISSUE_TEMPLATE/bug_resolution.yml @@ -89,6 +89,7 @@ body: label: Version description: What version of CryptPad are you running? options: + - 5.6.0 - 5.5.0 - 5.4.1 - 5.4.0 @@ -99,11 +100,6 @@ body: - 5.0.0 - 4.14.1 - 4.14.0 - - 4.13.0 - - 4.12.1 - - 4.12.0 - - 4.11.0 - - 4.10.0 - Other validations: required: true From a96856bb3d1dba7a76863ae819c42f7e960a3686 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Fri, 22 Dec 2023 09:00:59 +0100 Subject: [PATCH 180/283] Allow loading diagram images from Nextcloud https://github.com/cryptpad/cryptpad/issues/1297 --- lib/defaults.js | 4 ++++ lib/http-worker.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lib/defaults.js b/lib/defaults.js index 3d342a659..b149acabc 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -52,6 +52,10 @@ Default.padContentSecurity = function (Env) { return (Default.commonCSP(Env).join('; ') + "script-src 'self' 'unsafe-eval' 'unsafe-inline' resource: " + Env.httpUnsafeOrigin).replace(/\s+/g, ' '); }; +Default.diagramContentSecurity = function (Env) { + return (Default.commonCSP(Env).join('; ') + "script-src 'self' resource: " + Env.httpUnsafeOrigin).replace('img-src ', 'img-src http: https: ').replace(/\s+/g, ' '); +}; + Default.httpHeaders = function (Env) { return { "X-XSS-Protection": "1; mode=block", diff --git a/lib/http-worker.js b/lib/http-worker.js index fbcacbeb4..be59617e5 100644 --- a/lib/http-worker.js +++ b/lib/http-worker.js @@ -127,6 +127,8 @@ var getHeaders = function (Env, type) { var csp; if (type === 'office') { csp = Default.padContentSecurity(Env); + } else if (type === 'diagram') { + csp = Default.diagramContentSecurity(Env); } else { csp = Default.contentSecurity(Env); } @@ -149,6 +151,8 @@ var setHeaders = function (req, res) { type = 'office'; } else if (/^\/api\/(broadcast|config)/.test(req.url)) { type = 'api'; + } else if (/^\/components\/drawio\/src\/main\/webapp\/index.html.*$/.test(req.url)) { + type = 'diagram'; } else { type = 'standard'; } From e681525b637e4b2e3ed015d4d08bca98d0500445 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Fri, 22 Dec 2023 10:35:39 +0100 Subject: [PATCH 181/283] Upgrade to draw.io 21.8.2+4 --- package-lock.json | 15 ++++++--------- package.json | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1eed724c..31b83902f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "components-font-awesome": "^4.6.3", "croppie": "^2.5.0", "dragula": "3.7.2", - "drawio": "file:../drawio-npm", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+4", "express": "~4.18.2", "file-saver": "1.3.1", "fs-extra": "^7.0.0", @@ -68,9 +68,6 @@ "url": "https://opencollective.com/cryptpad" } }, - "../drawio-npm": { - "version": "21.8.2+3" - }, "node_modules/@mcrowe/minibloom": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@mcrowe/minibloom/-/minibloom-0.2.0.tgz", @@ -123,9 +120,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", - "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dependencies": { "undici-types": "~5.26.4" } @@ -1318,8 +1315,8 @@ } }, "node_modules/drawio": { - "resolved": "../drawio-npm", - "link": true + "version": "21.8.2+4", + "resolved": "git+ssh://git@github.com/cryptpad/drawio-npm.git#5555df31ce3a1c6220cefa3aaa16b9a7880bf8b8" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", diff --git a/package.json b/package.json index 19f583950..183033c13 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "requirejs-plugins": "^1.0.2", "scrypt-async": "1.2.0", "sortablejs": "^1.6.0", - "drawio": "file:../drawio-npm", + "drawio": "github:cryptpad/drawio-npm#npm-21.8.2+4", "pako": "^2.1.0", "x2js": "^3.4.4" }, From 194c6fc14dd0937fdda0ad5ff24f0262f24a4b0a Mon Sep 17 00:00:00 2001 From: Guillaume Kulakowski Date: Fri, 22 Dec 2023 15:28:54 +0100 Subject: [PATCH 182/283] Fix #1349 Fix issue in PR #1287 --- Dockerfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 745dd472f..36e92e747 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,12 +14,7 @@ COPY . /cryptpad RUN sed -i "s@//httpAddress: 'localhost'@httpAddress: '0.0.0.0'@" /cryptpad/config/config.example.js RUN sed -i "s@installMethod: 'unspecified'@installMethod: 'docker'@" /cryptpad/config/config.example.js - -# Install wget for healthcheck -RUN apt-get update && apt-get install --no-install-recommends -y wget && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* - + # Install dependencies RUN npm install --production \ && npm run install:components @@ -31,6 +26,11 @@ FROM node:lts-slim RUN groupadd cryptpad -g 4001 RUN useradd cryptpad -u 4001 -g 4001 -d /cryptpad +# Install wget for healthcheck +RUN apt-get update && apt-get install --no-install-recommends -y wget && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + # Copy cryptpad with installed modules COPY --from=build --chown=cryptpad /cryptpad /cryptpad USER cryptpad From 21cae4b4651a8e03749b22a9d01820445366db93 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 27 Dec 2023 12:59:30 +0100 Subject: [PATCH 183/283] date question datepicker/input field now displays correctly #1356 --- www/form/inner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/form/inner.js b/www/form/inner.js index 5cd9e1449..2316b992a 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2065,6 +2065,7 @@ define([ var tag = h('input'); var picker = Flatpickr(tag, { + disableMobile: true, enableTime: true, time_24hr: is24h, dateFormat: dateFormat, From beac74bd4021a8706e45c8a7eca139428e31345a Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 27 Dec 2023 16:14:21 +0100 Subject: [PATCH 184/283] fixes issue with duplicating choice/checkbox grid questions ##1348 --- www/form/inner.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 5cd9e1449..406855285 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -3295,7 +3295,7 @@ define([ }); sorted.forEach(function (uid) { var answer = answers[uid]; - + var viewOnly = content.answers.cantEdit || APP.isClosed; var action = h(viewOnly ? 'button.btn.btn-secondary' : 'button.btn.btn-primary', [ @@ -4108,10 +4108,25 @@ define([ arr = obj.arr; idx = obj.idx; _uid = Util.uid(); + + var opts = type === 'multiradio' || type === 'multicheck' ? { + items: [...Array(content.form[uid].opts.items.length).keys()].map(function (i) { + return { + uid: Util.uid(), + v: content.form[uid].opts.items[i].v + }; + }), + values: [...Array(content.form[uid].opts.values.length).keys()].map(function (i) { + return { + uid: Util.uid(), + v: content.form[uid].opts.values[i].v + }; + }) + } : content.form[uid].opts content.form[_uid] = { q: content.form[uid].q, - opts: content.form[uid].opts, + opts: opts, type: type, }; From 7c10646b9a4b3e4e32fa44a848e3aabdf1784037 Mon Sep 17 00:00:00 2001 From: Mathilde <41020854+mthld@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:24:37 +0100 Subject: [PATCH 185/283] Update readme.md - Added "Privacy /" to the Security header section - Updated the sales email address --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 571fd5948..cb429c8a1 100644 --- a/readme.md +++ b/readme.md @@ -32,7 +32,7 @@ You can find `Dockerfile`, `docker-compose.yml` and `docker-entrypoint.sh` files Previously, Docker images were community maintained, had their own repository and weren't official supported. We changed that with v5.4.0 during July 2023. Thanks to @promasu for all the work on the community images. -# Security +# Privacy / Security CryptPad offers a variety of collaborative tools that encrypt your data in your browser before it is sent to the server and your collaborators. In the event that the server is @@ -95,7 +95,7 @@ This project is tested with [BrowserStack](https://www.browserstack.com/). This software is and will always be available under the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. If you wish to use this technology in a proprietary product, please contact -sales@xwiki.com. +sales@xcryptpad.org [Tor browser]: https://www.torproject.org/download/ [active attack]: https://en.wikipedia.org/wiki/Attack_(computing)#Types_of_attack From 802571e73d445ad949bca299431c609fe6084841 Mon Sep 17 00:00:00 2001 From: Mathilde <41020854+mthld@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:25:06 +0100 Subject: [PATCH 186/283] Update readme.md - Fixed a typo in the sales email address --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index cb429c8a1..e290cbb82 100644 --- a/readme.md +++ b/readme.md @@ -95,7 +95,7 @@ This project is tested with [BrowserStack](https://www.browserstack.com/). This software is and will always be available under the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. If you wish to use this technology in a proprietary product, please contact -sales@xcryptpad.org +sales@cryptpad.org [Tor browser]: https://www.torproject.org/download/ [active attack]: https://en.wikipedia.org/wiki/Attack_(computing)#Types_of_attack From 52c766a599b370daa75205ebe88dd3c491773d2e Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Thu, 28 Dec 2023 12:32:15 +0100 Subject: [PATCH 187/283] kanban exports now exclude deleted items #1325 --- www/kanban/inner.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 302b099dd..5c787e813 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -415,6 +415,10 @@ define([ var list = boards.list || []; var idx = list.indexOf(id); if (idx !== -1) { list.splice(idx, 1); } + var items = boards.data[id].item + items.forEach(function(item) { + delete boards.items[item] + }) delete (boards.data || {})[id]; kanban.removeBoard(id); return void commit(); From ed30ddc6047f007aca2f588585fe67416f1e1803 Mon Sep 17 00:00:00 2001 From: Mathilde <41020854+mthld@users.noreply.github.com> Date: Fri, 29 Dec 2023 09:48:30 +0100 Subject: [PATCH 188/283] Update CODE_OF_CONDUCT.md Update outdated contact email address --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 3889dbaf6..90001563f 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -61,7 +61,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at contact@cryptpad.fr. All +reported by contacting the project team at contact@cryptpad.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. From 7af5ff8f0681536540bba829a0ce5bcd3ff41588 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 3 Jan 2024 13:44:38 +0100 Subject: [PATCH 189/283] added range array to utils + linting --- www/common/common-util.js | 5 +++++ www/form/inner.js | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/www/common/common-util.js b/www/common/common-util.js index e5471c1ff..22509c617 100644 --- a/www/common/common-util.js +++ b/www/common/common-util.js @@ -733,6 +733,11 @@ return !(typeof(Atomics) === "undefined" || !supportsSharedArrayBuffers() || typeof(WebAssembly) === 'undefined'); }; + //Returns an array of integers in range 0 to (length-1) + Util.getKeysArray = function (length) { + return [...Array(length).keys()]; + }; + if (typeof(module) !== 'undefined' && module.exports) { module.exports = Util; } else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) { diff --git a/www/form/inner.js b/www/form/inner.js index 406855285..2c539971b 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4109,20 +4109,22 @@ define([ idx = obj.idx; _uid = Util.uid(); + var itemKeys = Util.getKeysArray(content.form[uid].opts.items.length); + var valueKeys = Util.getKeysArray(content.form[uid].opts.values.length); var opts = type === 'multiradio' || type === 'multicheck' ? { - items: [...Array(content.form[uid].opts.items.length).keys()].map(function (i) { + items: itemKeys.map(function (i) { return { uid: Util.uid(), v: content.form[uid].opts.items[i].v }; }), - values: [...Array(content.form[uid].opts.values.length).keys()].map(function (i) { + values: valueKeys.map(function (i) { return { uid: Util.uid(), v: content.form[uid].opts.values[i].v }; }) - } : content.form[uid].opts + } : content.form[uid].opts; content.form[_uid] = { q: content.form[uid].q, From 13ccab973611313baf0db8c581d6215bc5a13a2e Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 3 Jan 2024 15:32:18 +0100 Subject: [PATCH 190/283] ensured items are not present in export when deleted by drag method --- www/kanban/inner.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 5c787e813..5eecc9915 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -415,10 +415,6 @@ define([ var list = boards.list || []; var idx = list.indexOf(id); if (idx !== -1) { list.splice(idx, 1); } - var items = boards.data[id].item - items.forEach(function(item) { - delete boards.items[item] - }) delete (boards.data || {})[id]; kanban.removeBoard(id); return void commit(); @@ -1154,6 +1150,8 @@ define([ }); framework.setFileExporter('.json', function () { + var content = kanban.getBoardsJSON(); + cleanData(content); return new Blob([JSON.stringify(kanban.getBoardsJSON(), 0, 2)], { type: 'application/json', }); From db77db3a0abaccba111fd2d1900a2e5f1ae45896 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Wed, 3 Jan 2024 16:09:50 +0100 Subject: [PATCH 191/283] moved cleanData() for lint compliance --- www/kanban/inner.js | 53 +++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/www/kanban/inner.js b/www/kanban/inner.js index 5eecc9915..966d5db9a 100644 --- a/www/kanban/inner.js +++ b/www/kanban/inner.js @@ -1137,6 +1137,33 @@ define([ if (framework.isReadOnly() || framework.isLocked()) { $container.addClass('cp-app-readonly'); } + + var cleanData = function (boards) { + if (typeof(boards) !== "object") { return; } + var items = boards.items || {}; + var data = boards.data || {}; + var list = boards.list || []; + + // Remove duplicate boards + list = boards.list = Util.deduplicateString(list); + + Object.keys(data).forEach(function (id) { + if (list.indexOf(Number(id)) === -1) { + list.push(Number(id)); + } + // Remove duplicate items + var b = data[id]; + b.item = Util.deduplicateString(b.item || []); + }); + Object.keys(items).forEach(function (eid) { + var exists = Object.keys(data).some(function (id) { + return (data[id].item || []).indexOf(Number(eid)) !== -1; + }); + if (!exists) { delete items[eid]; } + }); + framework.localChange(); + }; + framework.setFileImporter({accept: ['.json', 'application/json']}, function (content /*, file */) { var parsed; try { parsed = JSON.parse(content); } @@ -1293,32 +1320,6 @@ define([ }; }); - var cleanData = function (boards) { - if (typeof(boards) !== "object") { return; } - var items = boards.items || {}; - var data = boards.data || {}; - var list = boards.list || []; - - // Remove duplicate boards - list = boards.list = Util.deduplicateString(list); - - Object.keys(data).forEach(function (id) { - if (list.indexOf(Number(id)) === -1) { - list.push(Number(id)); - } - // Remove duplicate items - var b = data[id]; - b.item = Util.deduplicateString(b.item || []); - }); - Object.keys(items).forEach(function (eid) { - var exists = Object.keys(data).some(function (id) { - return (data[id].item || []).indexOf(Number(eid)) !== -1; - }); - if (!exists) { delete items[eid]; } - }); - framework.localChange(); - }; - framework.onReady(function () { $("#cp-app-kanban-content").focus(); var content = kanban.getBoardsJSON(); From a5103bc21ba95f3a0104318bef837bfbb98789ac Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 4 Jan 2024 18:34:13 +0100 Subject: [PATCH 192/283] Account deletion for known users and fix UI --- lib/challenge-commands/base.js | 4 ++-- lib/challenge-commands/totp.js | 4 ++-- lib/commands/block.js | 11 +++++++---- lib/commands/invitation.js | 1 - lib/commands/users.js | 2 -- www/common/cryptpad-common.js | 10 ++++++++-- www/common/outer/async-store.js | 14 +++++++------- www/common/outer/login-block.js | 3 ++- www/common/outer/sharedworker.js | 2 +- www/common/sframe-common.js | 1 + www/settings/inner.js | 2 ++ 11 files changed, 32 insertions(+), 22 deletions(-) diff --git a/lib/challenge-commands/base.js b/lib/challenge-commands/base.js index 41549e613..2e23d1dee 100644 --- a/lib/challenge-commands/base.js +++ b/lib/challenge-commands/base.js @@ -82,8 +82,8 @@ const removeBlock = Commands.REMOVE_BLOCK = function (Env, body, cb) { }; removeBlock.complete = function (Env, body, cb) { - const { publicKey, reason } = body; - Block.removeLoginBlock(Env, publicKey, reason, cb); + const { publicKey, edPublic, reason } = body; + Block.removeLoginBlock(Env, publicKey, reason, edPublic, cb); }; diff --git a/lib/challenge-commands/totp.js b/lib/challenge-commands/totp.js index 303b7a93b..ca44e0010 100644 --- a/lib/challenge-commands/totp.js +++ b/lib/challenge-commands/totp.js @@ -513,10 +513,10 @@ const removeBlock = Commands.TOTP_REMOVE_BLOCK = function (Env, body, cb) { }; removeBlock.complete = function (Env, body, cb) { - const { publicKey, reason } = body; + const { publicKey, edPublic, reason } = body; nThen(function (w) { // Remove the block - Block.removeLoginBlock(Env, publicKey, reason, w((err) => { + Block.removeLoginBlock(Env, publicKey, reason, edPublic, w((err) => { if (err) { w.abort(); return void cb(err); diff --git a/lib/commands/block.js b/lib/commands/block.js index 6ccef235b..aeb41ec04 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -185,7 +185,6 @@ Block.writeLoginBlock = function (Env, msg, _cb) { } }); - console.log(isSSO, Env.storeSSOUsers); if (validatedInvite) { Invitation.use(Env, inviteToken, publicKey, userData, (err) => { if (!err) { return; } @@ -195,8 +194,7 @@ Block.writeLoginBlock = function (Env, msg, _cb) { publicKey }); }); - } else if (isSSO && Env.storeSSOUsers) { - console.log('LALALA'); + } else if (isSSO && Env.storeSSOUsers && !registrationProof) { let edPublic = Array.isArray(userData) && userData[1]; let name = Array.isArray(userData) && userData[0]; if (!edPublic) { return; } @@ -229,7 +227,7 @@ Block.writeLoginBlock = function (Env, msg, _cb) { information, we can just sign some constant and use that as proof. */ -Block.removeLoginBlock = function (Env, publicKey, reason, _cb) { +Block.removeLoginBlock = function (Env, publicKey, reason, edPublic, _cb) { var cb = Util.once(Util.mkAsync(_cb)); BlockStore.archive(Env, publicKey, reason, function (err) { @@ -240,6 +238,11 @@ Block.removeLoginBlock = function (Env, publicKey, reason, _cb) { cb(err); }); + if (edPublic && reason !== 'PASSWORD_CHANGE') { + Users.delete(Env, edPublic, (err) => { + if (err) { Env.Log.error('KNOWN_USER_DELETION_ERROR', { error: err, key: edPublic }); } + }); + } // We should also try to remove the SSO data. Errors will be logged // but they don't have to be shown to the user. The account data diff --git a/lib/commands/invitation.js b/lib/commands/invitation.js index 05c0e6151..bafae4f10 100644 --- a/lib/commands/invitation.js +++ b/lib/commands/invitation.js @@ -60,7 +60,6 @@ Invitation.use = (Env, id, blockId, userData, _cb) => { data.edPublic = edPublic; data.type = 'invite:' + id; let adminKey = data.createdBy; - console.log(Env.storeInvitedUsers, 'ICI', Env.storeInvitedUsers, Env.storeSSOUsers); if (Env.storeInvitedUsers) { Users.add(Env, edPublic, data, adminKey, (err) => { if (err) { diff --git a/lib/commands/users.js b/lib/commands/users.js index 37f2203a9..3fc161190 100644 --- a/lib/commands/users.js +++ b/lib/commands/users.js @@ -7,7 +7,6 @@ const Util = require("../common-util"); Users.getAll = (Env, cb) => { User.getAll(Env, (err, data) => { if (err) { return void cb(err); } - console.log(data); cb(null, data); }); }; @@ -17,7 +16,6 @@ Users.add = (Env, edPublic, data, adminKey, _cb) => { data.createdBy = adminKey; data.time = +new Date(); const safeKey = Util.escapeKeyCharacters(edPublic); - console.log(edPublic, data); User.write(Env, safeKey, data, (err) => { if (err) { return void cb(err); } cb(); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 36cef9279..9721e3fa2 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1912,6 +1912,7 @@ define([ common.deleteAccount = function (data, cb) { data = data || {}; + common.CP_onAccountDeletion = true; var bytes = data.bytes; // From Scrypt var auth = data.auth; // MFA data @@ -2125,6 +2126,7 @@ define([ Block.removeLoginBlock({ reason: 'PASSWORD_CHANGE', auth: auth, + edPublic: edPublic, blockKeys: oldBlockKeys, }, waitFor(function (err) { if (err) { return void console.error(err); } @@ -2340,7 +2342,7 @@ define([ LocalStore.logout(function () { common.stopWorker(); common.drive.onDeleted.fire(data.reason); - }); + }, true); }; var lastPing = +new Date(); @@ -2898,13 +2900,17 @@ define([ if (!o && n) { LocalStore.loginReload(); } else if (o && !n) { - LocalStore.logout(); + if (!common.CP_onAccountDeletion) { LocalStore.logout(); } } else if (o && n && o !== n) { common.passwordUpdated = true; window.location.reload(); } }); + common.drive.onDeleted.reg(function () { + common.CP_onAccountDeletion = true; + }); LocalStore.onLogout(function () { + if (common.CP_onAccountDeletion) { return; } console.log('onLogout: disconnect'); common.stopWorker(); }); diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 99cf943c9..e8723d321 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -861,7 +861,6 @@ define([ // Owned drive if (metadata && metadata.owners && metadata.owners.length === 1 && metadata.owners.indexOf(edPublic) !== -1) { - var token; nThen(function (waitFor) { Block.checkRights({ auth: auth, @@ -876,8 +875,7 @@ define([ }).nThen(function (waitFor) { self.accountDeletion = clientId; // Log out from other workers - var token = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER); - store.proxy[Constants.tokenKey] = token; + store.proxy[Constants.tokenKey] = 'DELETED'; onSync(null, waitFor()); }).nThen(function (waitFor) { // Delete Pin Store @@ -896,6 +894,7 @@ define([ Block.removeLoginBlock({ reason: 'ARCHIVE_OWNED', auth: auth, + edPublic: edPublic, blockKeys: blockKeys, }, waitFor(function (err) { if (err) { console.error(err); } @@ -904,7 +903,8 @@ define([ removeOwnedPads(true, waitFor); }).nThen(function () { // Log out current worker - postMessage(clientId, "DELETE_ACCOUNT", token, function () {}); + broadcast([clientId], "DRIVE_DELETED", 'ARCHIVE_OWNED'); + postMessage(clientId, "DELETE_ACCOUNT", 'DELETED', function () {}); store.network.disconnect(); cb({ state: true @@ -2926,6 +2926,7 @@ define([ broadcast([], "UPDATE_METADATA"); }); proxy.on('change', [Constants.tokenKey], function () { + if (store.isDeleted || proxy[Constants.tokenKey] === 'DELETED') { return; } broadcast([], "UPDATE_TOKEN", { token: proxy[Constants.tokenKey] }); }); @@ -3061,9 +3062,8 @@ define([ .on('error', function (info) { if (info.error && info.error === 'EDELETED') { if (store.ownDeletion) { return; } - broadcast([], "LOGOUT", { - reason: info.message - }); + store.isDeleted = true; + broadcast([], "DRIVE_DELETED", info.message); } }); diff --git a/www/common/outer/login-block.js b/www/common/outer/login-block.js index a929373e6..439c34994 100644 --- a/www/common/outer/login-block.js +++ b/www/common/outer/login-block.js @@ -196,7 +196,7 @@ define([ }, cb); }; Block.removeLoginBlock = function (data, cb) { - const { reason, blockKeys, auth } = data; + const { reason, blockKeys, auth, edPublic } = data; var command = 'REMOVE_BLOCK'; if (auth && auth.type) { command = `${auth.type.toUpperCase()}_` + command; } @@ -204,6 +204,7 @@ define([ ServerCommand(blockKeys.sign, { command: command, auth: auth && auth.data, + edPublic: edPublic, reason: reason }, cb); }; diff --git a/www/common/outer/sharedworker.js b/www/common/outer/sharedworker.js index 408b88fdd..41cf9938b 100644 --- a/www/common/outer/sharedworker.js +++ b/www/common/outer/sharedworker.js @@ -104,7 +104,7 @@ var init = function (client, cb) { cfg.broadcast = function (excludes, cmd, data, cb) { cb = cb || function () {}; Object.keys(self.tabs).forEach(function (cId) { - if (excludes.indexOf(cId) !== -1) { return; } + if (excludes.indexOf(+cId) !== -1) { return; } self.tabs[cId].chan.query(cmd, data, function (err, data2) { if (err) { return void cb({error: err}); } cb(data2); diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index df1f4d91a..625a0dfe6 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -1012,6 +1012,7 @@ define([ } catch (e) {} ctx.sframeChan.on('EV_LOGOUT', function () { + if (window.CP_ownAccountDeletion) { return; } $(window).on('keyup', function (e) { if (e.keyCode === 27) { UI.removeLoadingScreen(); diff --git a/www/settings/inner.js b/www/settings/inner.js index bb33bd793..e23459d9d 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -626,10 +626,12 @@ define([ } })); }).nThen(function () { + window.CP_ownAccountDeletion = true; sframeChan.query("Q_SETTINGS_DELETE_ACCOUNT", { bytes: bytes, auth: auth }, function(err, data) { + if (err) { window.CP_ownAccountDeletion = false; } UI.removeLoadingScreen(); if (data && data.error) { $button.prop('disabled', ''); From 1fc39c92f9b7cef580d2668727d0cc24f9f090e0 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jan 2024 13:07:37 +0100 Subject: [PATCH 193/283] Fix redirect to shared folder with read-only link #1238 --- www/common/proxy-manager.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index f09ac87b5..61732b765 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -586,7 +586,7 @@ define([ // 1. add the shared folder to our list of shared folders // NOTE: pushSharedFolder will encrypt the href directly in the object if needed Env.user.userObject.pushSharedFolder(folderData, waitFor(function (err, folderId) { - if (err === "EEXISTS" && folderData.href && folderId) { + if (err === "EEXISTS" && folderData.href && folderId) { // Check upgrade var parsed = Hash.parsePadUrl(folderData.href); var secret = Hash.getSecrets('drive', parsed.hash, folderData.password); SF.upgrade(secret.channel, secret); @@ -594,6 +594,10 @@ define([ waitFor.abort(); return void cb(folderId); } + if (err === "EEXISTS" && folderId) { // Exists but no upgrade, return folderId + waitFor.abort(); + return void cb(folderId); + } if (err) { waitFor.abort(); return void cb(err); From 39599dba75da3444c70778516749588eae807a30 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Fri, 5 Jan 2024 16:20:16 +0100 Subject: [PATCH 194/283] fixed bug affecting question types other than multicheck/grid --- www/form/inner.js | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index 2c539971b..ef9653f56 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4108,24 +4108,29 @@ define([ arr = obj.arr; idx = obj.idx; _uid = Util.uid(); - - var itemKeys = Util.getKeysArray(content.form[uid].opts.items.length); - var valueKeys = Util.getKeysArray(content.form[uid].opts.values.length); - var opts = type === 'multiradio' || type === 'multicheck' ? { - items: itemKeys.map(function (i) { - return { - uid: Util.uid(), - v: content.form[uid].opts.items[i].v - }; - }), - values: valueKeys.map(function (i) { - return { - uid: Util.uid(), - v: content.form[uid].opts.values[i].v - }; - }) - } : content.form[uid].opts; + var opts; + if (type === 'multiradio' || type === 'multicheck') { + var itemKeys = Util.getKeysArray(content.form[uid].opts.items.length); + var valueKeys = Util.getKeysArray(content.form[uid].opts.values.length); + opts = { + items: itemKeys.map(function (i) { + return { + uid: Util.uid(), + v: content.form[uid].opts.items[i].v + }; + }), + values: valueKeys.map(function (i) { + return { + uid: Util.uid(), + v: content.form[uid].opts.values[i].v + }; + }) + }; + } else { + opts = content.form[uid].opts; + } + content.form[_uid] = { q: content.form[uid].q, opts: opts, From f0591280b94f4af5f2ffc15752b16f99c8ba24d8 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Fri, 5 Jan 2024 16:44:51 +0100 Subject: [PATCH 195/283] fixed bug with duplication of 'required' status --- www/form/inner.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/www/form/inner.js b/www/form/inner.js index ef9653f56..d024e1805 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4109,26 +4109,22 @@ define([ idx = obj.idx; _uid = Util.uid(); - var opts; + var opts = content.form[uid].opts; if (type === 'multiradio' || type === 'multicheck') { var itemKeys = Util.getKeysArray(content.form[uid].opts.items.length); var valueKeys = Util.getKeysArray(content.form[uid].opts.values.length); - opts = { - items: itemKeys.map(function (i) { + opts.items = itemKeys.map(function (i) { return { uid: Util.uid(), v: content.form[uid].opts.items[i].v }; - }), - values: valueKeys.map(function (i) { + }); + opts.values = valueKeys.map(function (i) { return { uid: Util.uid(), v: content.form[uid].opts.values[i].v }; - }) - }; - } else { - opts = content.form[uid].opts; + }); } content.form[_uid] = { From 69ea1d5b6368b94eb3e2acc775cb6da07a1610aa Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Fri, 5 Jan 2024 16:55:22 +0100 Subject: [PATCH 196/283] cloning original question instead of altering directly --- www/form/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/form/inner.js b/www/form/inner.js index d024e1805..c1177f10a 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -4109,7 +4109,7 @@ define([ idx = obj.idx; _uid = Util.uid(); - var opts = content.form[uid].opts; + var opts = Util.clone(content.form[uid].opts); if (type === 'multiradio' || type === 'multicheck') { var itemKeys = Util.getKeysArray(content.form[uid].opts.items.length); var valueKeys = Util.getKeysArray(content.form[uid].opts.values.length); From 31b9bbf7965a350b506324d2b5820cc3f53cab27 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jan 2024 17:40:20 +0100 Subject: [PATCH 197/283] Support activity and placeholder in eviction script --- lib/storage/blob.js | 61 +++++++++++++++++++++++++++++++++++---- scripts/clean-activity.js | 21 ++++++++++++++ 2 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 scripts/clean-activity.js diff --git a/lib/storage/blob.js b/lib/storage/blob.js index 97fc8b9e3..172af2e1a 100644 --- a/lib/storage/blob.js +++ b/lib/storage/blob.js @@ -464,7 +464,7 @@ var makeWalker = function (n, handleChild, done) { // do no more than 20 jobs at a time var tasks = Semaphore.create(n); - var recurse = function (path) { + var recurse = function (path, dir) { tasks.take(function (give) { var next = give(W()); @@ -477,7 +477,19 @@ var makeWalker = function (n, handleChild, done) { } if (!stats.isDirectory()) { w.abort(); - return void handleChild(void 0, path, next); + if (/\.activity$/.test(path)) { + // NOTE: some activity files were created for deleted blobs due to + // a bug. We're going to detect them here in order to be able to clean + // them. + if (!dir.includes(Path.basename(path.replace(/\.activity$/, '')))) { + return void handleChild(void 0, path, next, true); + } + // Ignore valid activity files + return next(); + } + // Ignore placeholder files + if (/\.placeholder$/.test(path)) { return next(); } + return void handleChild(void 0, path, next, false); } // fall through })); @@ -487,7 +499,7 @@ var makeWalker = function (n, handleChild, done) { if (err) { return next(); } // everything is fine and it's a directory... dir.forEach(function (d) { - recurse(Path.join(path, d)); + recurse(Path.join(path, d), dir); }); next(); }); @@ -502,7 +514,8 @@ var listProofs = function (root, handler, cb) { Fs.readdir(root, function (err, dir) { if (err) { return void cb(err); } - var walk = makeWalker(20, function (err, path, next) { + var walk = makeWalker(20, function (err, path, next, loneActivity) { + if (loneActivity) { return void next(); } // path is the path to a child node on the filesystem // next handles the next job in a queue @@ -537,12 +550,20 @@ var listProofs = function (root, handler, cb) { }); }; +var getActivityStat = function (path, base, cb) { + var suffix = base ? '' : '.activity'; + Fs.stat(path+suffix, function (err, stats) { + if (err && err.code === 'ENOENT' && !base) { return getActivityStat(path, true, cb); } + cb(err, stats); + }); +}; var listBlobs = function (root, handler, cb) { // iterate over files Fs.readdir(root, function (err, dir) { if (err) { return void cb(err); } - var walk = makeWalker(20, function (err, path, next) { - Fs.stat(path, function (err, stats) { + var walk = makeWalker(20, function (err, path, next, loneActivity) { + if (loneActivity) { return void next(); } + getActivityStat(path, false, function (err, stats) { if (err) { return void handler(err, void 0, next); } @@ -565,6 +586,30 @@ var listBlobs = function (root, handler, cb) { }); }; +var cleanLoneActivity = function (root, cb) { + // iterate over files + Fs.readdir(root, function (err, dir) { + if (err) { return void cb(err); } + var walk = makeWalker(20, function (err, path, next, loneActivity) { + if (!loneActivity) { return void next(); } + Fs.unlink(path, function (err) { + if (err) { + return console.error('ERROR', path, err); + } + console.log('DELETED', path); + next(); + }); + }, function () { + cb(); + }); + + dir.forEach(function (d) { + if (d.length !== 2) { return; } + walk(Path.join(root, d)); + }); + }); +}; + BlobStore.create = function (config, _cb) { var cb = Util.once(Util.mkAsync(_cb)); if (typeof(config.getSession) !== 'function') { @@ -651,6 +696,10 @@ BlobStore.create = function (config, _cb) { removeArchivedProof(Env, safeKey, blobId, cb); }, }, + loneActivity: function (_cb) { + var cb = Util.once(Util.mkAsync(_cb)); + cleanLoneActivity(Env.blobPath, cb); + } }, archive: { diff --git a/scripts/clean-activity.js b/scripts/clean-activity.js new file mode 100644 index 000000000..6cb3f75f6 --- /dev/null +++ b/scripts/clean-activity.js @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team and contributors +// +// SPDX-License-Identifier: AGPL-3.0-or-later + +/** + * Some .activity file were created for deleted blob due to a bug. + * This script can be run once to remove these invalid activity file. +**/ +var nThen = require("nthen"); +var config = require("../lib/load-config"); +var BlobStore = require("../lib/storage/blob"); + +config.getSession = function () {}; +BlobStore.create(config, function (err, store) { + if (err) { return console.error('ERROR', err); } + console.log('Cleaning lone .activity files...'); + store.remove.loneActivity(function (err) { + if (err) { return console.error('ERROR', err); } + console.log('Done'); + }); +}); From 0e918643ce839ee86b6fdd94f2f7e6866c44fa91 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 5 Jan 2024 17:46:04 +0100 Subject: [PATCH 198/283] Check if a blob exists before creating the activity file --- lib/storage/blob.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/storage/blob.js b/lib/storage/blob.js index 172af2e1a..b029b95c5 100644 --- a/lib/storage/blob.js +++ b/lib/storage/blob.js @@ -153,8 +153,12 @@ var clearActivity = function (Env, blobId, cb) { }; var updateActivity = function (Env, blobId, cb) { var path = makeActivityPath(Env, blobId); - var s_data = String(+new Date()); - Fs.writeFile(path, s_data, cb); + var blobPath = makeBlobPath(Env, blobId); + isFile(blobPath, (err, state) => { + if (err || !state) { return void cb(); } + var s_data = String(+new Date()); + Fs.writeFile(path, s_data, cb); + }); }; var archiveActivity = function (Env, blobId, cb) { From 70d47193596662b2ee7278d6671b56812f11f821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathilde=20Gr=C3=BCnig?= <41020854+mthld@users.noreply.github.com> Date: Mon, 8 Jan 2024 12:01:01 +0100 Subject: [PATCH 199/283] fix typo in issue template --- .github/ISSUE_TEMPLATE/bug_resolution.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_resolution.yml b/.github/ISSUE_TEMPLATE/bug_resolution.yml index a7dcf2d13..cdd7418f0 100644 --- a/.github/ISSUE_TEMPLATE/bug_resolution.yml +++ b/.github/ISSUE_TEMPLATE/bug_resolution.yml @@ -55,7 +55,7 @@ body: - type: dropdown id: operating-system attributes: - label: What opreating system are you using? + label: Which operating system are you using? multiple: true options: - Linux/BSD/UNIX From 8c32493a01ba6a2055704376c98bff3efe0557a3 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 8 Jan 2024 12:27:40 +0100 Subject: [PATCH 200/283] calendar datepicker on mobile now easily toggled #1084 --- www/calendar/inner.js | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index f19879091..ab3a22033 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -1307,23 +1307,21 @@ ICS ==> create a new event with the same UID and a RECURRENCE-ID field (with a v updateDateRange(); updateRecurring(); }); + var f = Flatpickr(goDate, { + enableTime: false, + defaultDate: APP.calendar.getDate()._date, + clickOpens: false, + //dateFormat: dateFormat, + onChange: function (date) { + date[0].setHours(12); + f.destroy(); + APP.moveToDate(+date[0]); + updateDateRange(); + updateRecurring(); + }, + }); $(goDate).click(function () { - var f = Flatpickr(goDate, { - enableTime: false, - defaultDate: APP.calendar.getDate()._date, - //dateFormat: dateFormat, - onChange: function (date) { - date[0].setHours(12); - f.destroy(); - APP.moveToDate(+date[0]); - updateDateRange(); - updateRecurring(); - }, - onClose: function () { - setTimeout(f.destroy); - } - }); - f.open(); + f.isOpen ? f.close() : f.open() }); APP.toolbar.$bottomL.append(h('div.cp-calendar-browse', [ goLeft, goToday, goRight, goDate From 95497ebe02de6513808504746bc3e5d669feee66 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 8 Jan 2024 12:36:08 +0100 Subject: [PATCH 201/283] lint compliance --- www/calendar/inner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/calendar/inner.js b/www/calendar/inner.js index ab3a22033..22a33e8f9 100644 --- a/www/calendar/inner.js +++ b/www/calendar/inner.js @@ -1321,7 +1321,7 @@ ICS ==> create a new event with the same UID and a RECURRENCE-ID field (with a v }, }); $(goDate).click(function () { - f.isOpen ? f.close() : f.open() + return f.isOpen ? f.close() : f.open(); }); APP.toolbar.$bottomL.append(h('div.cp-calendar-browse', [ goLeft, goToday, goRight, goDate From 70d84838dfa53369825637eb1ba7759e169f02e7 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 8 Jan 2024 14:08:26 +0100 Subject: [PATCH 202/283] Add DRY_RUN option to the eviction script --- lib/eviction.js | 39 +++++++++++++++++++++++++++++++++++++-- scripts/evict-inactive.js | 4 ++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/eviction.js b/lib/eviction.js index 8bd530f1e..42afbc2c5 100644 --- a/lib/eviction.js +++ b/lib/eviction.js @@ -200,6 +200,11 @@ var evictArchived = function (Env, cb) { // but if it's been stored for the configured time... // expire it + if (Env.DRY_RUN) { + if (item.channel.length === 32) { removed++; } + else if (item.channel.length === 44) { accounts++; } + return void Log.info("EVICT_ARCHIVED_CHANNEL_DRY_RUN", item.channel, next); + } store.removeArchivedChannel(item.channel, w(function (err) { if (err) { return Log.error('EVICT_ARCHIVED_CHANNEL_REMOVAL_ERROR', { @@ -246,6 +251,10 @@ var evictArchived = function (Env, cb) { return void next(); } if (item && item.mtime > retentionTime) { return void next(); } + if (Env.DRY_RUN) { + removed++; + return void Log.info("EVICT_ARCHIVED_BLOB_PROOF_DRY_RUN", item, next); + } blobs.remove.archived.proof(item.safeKey, item.blobId, (function (err) { if (err) { Log.error("EVICT_ARCHIVED_BLOB_PROOF_ERROR", item); @@ -273,6 +282,10 @@ var evictArchived = function (Env, cb) { return void next(); } if (item && item.mtime > retentionTime) { return void next(); } + if (Env.DRY_RUN) { + removed++; + return void Log.info("EVICT_ARCHIVED_BLOB_DRY_RUN", item, next); + } blobs.remove.archived.blob(item.blobId, function (err) { if (err) { Log.error("EVICT_ARCHIVED_BLOB_ERROR", item); @@ -288,6 +301,7 @@ var evictArchived = function (Env, cb) { })); }; + if (Env.DRY_RUN) { Env.Log.info('DRY RUN'); } nThen(loadStorage) .nThen(migrateIncorrectBlobs) .nThen(removeArchivedChannels) @@ -544,6 +558,9 @@ module.exports = function (Env, cb) { } // remove the pin logs of inactive accounts if inactive account removal is configured + if (Env.DRY_RUN) { + return void Log.info("EVICT_INACTIVE_ACCOUNT_DRY_RUN", id, cb); + } pinStore.archiveChannel(id, undefined, function (err) { if (err) { return Log.error('EVICT_INACTIVE_ACCOUNT_PIN_LOG', err, next); @@ -602,7 +619,12 @@ module.exports = function (Env, cb) { // unless we address this race condition with this last-minute double-check if (item.mtime > inactiveTime) { return void next(); } - removed++; + if (Env.DRY_RUN) { + removed++; + return void Log.info("EVICT_ARCHIVE_BLOB_DRY_RUN", { + item: item, + }, next); + } blobs.archive.blob(item.blobId, 'INACTIVE', function (err) { if (err) { return Log.error("EVICT_ARCHIVE_BLOB_ERROR", { @@ -610,6 +632,7 @@ module.exports = function (Env, cb) { item: item, }, next); } + removed++; Log.info("EVICT_ARCHIVE_BLOB", { item: item, }, next); @@ -658,6 +681,10 @@ module.exports = function (Env, cb) { } })); }).nThen(function () { + if (Env.DRY_RUN) { + removed++; + return void Log.info("EVICT_BLOB_PROOF_LONELY_DRY_RUN", item, next); + } blobs.remove.proof(item.safeKey, item.blobId, function (err) { if (err) { return Log.error("EVICT_BLOB_PROOF_LONELY_ERROR", item, next); @@ -698,6 +725,9 @@ module.exports = function (Env, cb) { // check if the database has any ephemeral channels // if it does it's because of a bug, and they should be removed if (item.channel.length === 34) { + if (Env.DRY_RUN) { + return void Log.info("EVICT_EPHEMERAL_DRY_RUN", item.channel, cb); + } return void store.removeChannel(item.channel, w(function (err) { if (err) { return Log.error('EVICT_EPHEMERAL_CHANNEL_REMOVAL_ERROR', { @@ -728,6 +758,10 @@ module.exports = function (Env, cb) { // else fall through to the archival })); }).nThen(function (w) { + if (Env.DRY_RUN) { + archived++; + return void Log.info("EVICT_CHANNEL_ARCHIVAL_DRY_RUN", item.channel, cb); + } return void store.archiveChannel(item.channel, 'INACTIVE', w(function (err) { if (err) { Log.error('EVICT_CHANNEL_ARCHIVAL_ERROR', { @@ -736,8 +770,8 @@ module.exports = function (Env, cb) { }, w()); return; } - Log.info('EVICT_CHANNEL_ARCHIVAL', item.channel, w()); archived++; + Log.info('EVICT_CHANNEL_ARCHIVAL', item.channel, w()); })); }).nThen(cb); }; @@ -754,6 +788,7 @@ module.exports = function (Env, cb) { store.listChannels(handler, w(done), true); // using a hacky "fast mode" since we only need the channel id }; + if (Env.DRY_RUN) { Env.Log.info('DRY RUN'); } nThen(loadStorage) // iterate over all documents and add them to a bloom filter if they have been active diff --git a/scripts/evict-inactive.js b/scripts/evict-inactive.js index f53536ae3..521edf015 100644 --- a/scripts/evict-inactive.js +++ b/scripts/evict-inactive.js @@ -15,6 +15,10 @@ var config = require("../lib/load-config"); var Env = Environment.create(config); +// Set DRY_RUN to true to run the script without deleting anything. A log file +// will be created. +Env.DRY_RUN = false; + var loadPremiumAccounts = function (Env, cb) { nThen(function (w) { // load premium accounts From b22441446c829aec5613cbd1788d57e6fd952b40 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 8 Jan 2024 14:12:04 +0100 Subject: [PATCH 203/283] Fix eviction error and add DRY_RUN to the archive cleaning script --- lib/eviction.js | 2 +- scripts/evict-archived.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/eviction.js b/lib/eviction.js index 42afbc2c5..12aaeff0f 100644 --- a/lib/eviction.js +++ b/lib/eviction.js @@ -203,7 +203,7 @@ var evictArchived = function (Env, cb) { if (Env.DRY_RUN) { if (item.channel.length === 32) { removed++; } else if (item.channel.length === 44) { accounts++; } - return void Log.info("EVICT_ARCHIVED_CHANNEL_DRY_RUN", item.channel, next); + return void Log.info("EVICT_ARCHIVED_CHANNEL_DRY_RUN", item.channel, cb); } store.removeArchivedChannel(item.channel, w(function (err) { if (err) { diff --git a/scripts/evict-archived.js b/scripts/evict-archived.js index 124ebc30c..6914c90ad 100644 --- a/scripts/evict-archived.js +++ b/scripts/evict-archived.js @@ -15,6 +15,10 @@ var config = require("../lib/load-config"); var Env = Environment.create(config); +// Set DRY_RUN to true to run the script without deleting anything. A log file +// will be created. +Env.DRY_RUN = false; + var loadPremiumAccounts = function (Env, cb) { nThen(function (w) { // load premium accounts From 467e8ee7fe29df86072c757e5e867abb26afa710 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 8 Jan 2024 14:41:00 +0100 Subject: [PATCH 204/283] Use ctime to detect deletable archived blobs --- lib/eviction.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/eviction.js b/lib/eviction.js index 12aaeff0f..dd0d777ab 100644 --- a/lib/eviction.js +++ b/lib/eviction.js @@ -250,7 +250,7 @@ var evictArchived = function (Env, cb) { Log.error("EVICT_BLOB_LIST_ARCHIVED_PROOF_ERROR", err); return void next(); } - if (item && item.mtime > retentionTime) { return void next(); } + if (item && item.ctime > retentionTime) { return void next(); } if (Env.DRY_RUN) { removed++; return void Log.info("EVICT_ARCHIVED_BLOB_PROOF_DRY_RUN", item, next); @@ -281,7 +281,7 @@ var evictArchived = function (Env, cb) { Log.error("EVICT_BLOB_LIST_ARCHIVED_BLOBS_ERROR", err); return void next(); } - if (item && item.mtime > retentionTime) { return void next(); } + if (item && item.ctime > retentionTime) { return void next(); } if (Env.DRY_RUN) { removed++; return void Log.info("EVICT_ARCHIVED_BLOB_DRY_RUN", item, next); From 20df2a4d536ab93f9f0fac59eba547ace071aac2 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 8 Jan 2024 15:45:43 +0100 Subject: [PATCH 205/283] Fix TypeError when destroying a shared folder --- www/common/inner/access.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/inner/access.js b/www/common/inner/access.js index d1cfda31f..acaee6723 100644 --- a/www/common/inner/access.js +++ b/www/common/inner/access.js @@ -1028,7 +1028,7 @@ define([ // If this is a form wiht a answer channel, delete it too var p = priv.propChannels; - if (p.answersChannel) { + if (p && p.answersChannel) { sframeChan.query('Q_DELETE_OWNED', { teamId: typeof(owned) !== "boolean" ? owned : undefined, channel: p.answersChannel From c5f479a349ab8c3b03d396be5de292e7307f341e Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 8 Jan 2024 16:24:21 +0100 Subject: [PATCH 206/283] added mailbox handler --- www/common/inner/access.js | 11 +++++++++++ www/common/outer/mailbox-handlers.js | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/www/common/inner/access.js b/www/common/inner/access.js index d1cfda31f..1b2b13d01 100644 --- a/www/common/inner/access.js +++ b/www/common/inner/access.js @@ -554,6 +554,7 @@ define([ }, function (err, res) { err = err || (res && res.error); redrawAll(true); + if (err) { spinner.hide(); var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden @@ -657,8 +658,10 @@ define([ var $sel = $div.find('.cp-usergrid-user.cp-selected'); var sel = $sel.toArray(); if (!sel.length) { return; } + var friend; var toAdd = sel.map(function (el) { var curve = $(el).attr('data-curve'); + friend = friends[curve] var teamId = $(el).attr('data-teamid'); // If the pad is woned by a team, we can transfer ownership to ourselves if (curve === user.curvePublic && teamOwner) { return priv.edPublic; } @@ -690,6 +693,14 @@ define([ }, waitFor(function (err, res) { err = err || (res && res.error); redrawAll(true); + common.mailbox.sendTo("ADD_TO_ACCESS_LIST", { + channel: channel, + title: data.title || title, + }, { + channel: friend.notifications, + curvePublic: friend.curvePublic + }); + if (err) { waitFor.abort(); var text = err === "INSUFFICIENT_PERMISSIONS" ? Messages.fm_forbidden diff --git a/www/common/outer/mailbox-handlers.js b/www/common/outer/mailbox-handlers.js index 50d319741..80bee6907 100644 --- a/www/common/outer/mailbox-handlers.js +++ b/www/common/outer/mailbox-handlers.js @@ -347,6 +347,28 @@ define([ cb(false); }; + handlers['ADD_TO_ACCESS_LIST'] = function(ctx, common, data, cb) { + + var msg = data.msg; + var content = msg.content; + var channel = content.channel; + + ctx.Store.getAllStores().forEach(function (store) { + var res = store.manager.findChannel(channel); + if (!res.length) { return; } + + var data = res[0]; + var id = data.id // check if that's correct + // var teamId = store.data.blockId; + ctx.Store.loadSharedFolder(null, id, data, function () { + // callback of loadSharefFolder, nothing to do here + }, undefined); + }); + + cb(true) + + }; + // Hide duplicates when receiving an ADD_OWNER notification: var addOwners = {}; handlers['ADD_OWNER'] = function (ctx, box, data, cb) { From ff3a40aa3152d5e09a70d3afb02356e4ba516631 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 8 Jan 2024 19:11:20 +0100 Subject: [PATCH 207/283] Fix TypeError --- lib/eviction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/eviction.js b/lib/eviction.js index dd0d777ab..4cac76e71 100644 --- a/lib/eviction.js +++ b/lib/eviction.js @@ -559,7 +559,7 @@ module.exports = function (Env, cb) { // remove the pin logs of inactive accounts if inactive account removal is configured if (Env.DRY_RUN) { - return void Log.info("EVICT_INACTIVE_ACCOUNT_DRY_RUN", id, cb); + return void Log.info("EVICT_INACTIVE_ACCOUNT_DRY_RUN", id, next); } pinStore.archiveChannel(id, undefined, function (err) { if (err) { From d92636bcf8920fb6c81a9d1f23f0d4143f6cc513 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 9 Jan 2024 15:09:41 +0100 Subject: [PATCH 208/283] Fix DRY_RUN issue --- lib/eviction.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/eviction.js b/lib/eviction.js index 4cac76e71..e57041ffb 100644 --- a/lib/eviction.js +++ b/lib/eviction.js @@ -760,6 +760,7 @@ module.exports = function (Env, cb) { }).nThen(function (w) { if (Env.DRY_RUN) { archived++; + w.abort(); return void Log.info("EVICT_CHANNEL_ARCHIVAL_DRY_RUN", item.channel, cb); } return void store.archiveChannel(item.channel, 'INACTIVE', w(function (err) { From 2d2046c16082634290173c466951b668a63b613d Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 10 Jan 2024 15:39:59 +0100 Subject: [PATCH 209/283] Prevent 'empty trash' button to overload async store thread #1344 --- www/common/outer/async-store.js | 3 +- www/common/proxy-manager.js | 51 ++++++++++++++++++++------------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 99cf943c9..33052fe5d 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1403,7 +1403,7 @@ define([ // Hidden hash: if a pad is deleted, we may have to switch back to full hash // in some tabs - Store.checkDeletedPad = function (channel) { + Store.checkDeletedPad = function (channel, cb) { if (!channel) { return; } // Check if the pad is still stored in one of our drives @@ -1411,6 +1411,7 @@ define([ channel: channel, isFile: true // we don't care if it's view or edit }, function (res) { + if (typeof(cb) === "function") { setTimeout(cb); } // If it is stored, abort if (Object.keys(res).length) { return; } // Otherwise, tell all the tabs that this channel was deleted and give them the hrefs diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 61732b765..509e91a3a 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -1019,41 +1019,52 @@ define([ var owned = Env.user.userObject.ownedInTrash(function (owners) { return _ownedByMe(Env, owners); }); + var n = nThen; owned.forEach(function (chan) { - Env.removeOwnedChannel(chan, waitFor(function (obj) { - // If the error is that the file is already removed, nothing to - // report, it's a normal behavior (pad expired probably) - if (obj && obj.error && obj.error !== "ENOENT") { - // RPC may not be responding - // Send a report that can be handled manually - console.error(obj.error, chan); - Feedback.send('ERROR_EMPTYTRASH_OWNED=' + chan + '|' + obj.error, true); - } - console.warn('DELETED', chan); - })); + n = n(function (w) { + Env.removeOwnedChannel(chan, w(function (obj) { + setTimeout(w(), 50); + // If the error is that the file is already removed, nothing to + // report, it's a normal behavior (pad expired probably) + if (obj && obj.error && obj.error !== "ENOENT") { + // RPC may not be responding + // Send a report that can be handled manually + console.error(obj.error, chan); + Feedback.send('ERROR_EMPTYTRASH_OWNED=' + chan + '|' + obj.error, true); + } + console.warn('DELETED', chan); + })); + }).nThen; }); + n(waitFor()); } // Empty the trash Env.user.userObject.emptyTrash(waitFor(function (err, toClean) { - cb(); - + var nn = nThen; // Don't block nThen for the lower-priority tasks - setTimeout(function () { + setTimeout(waitFor(function () { // Unpin deleted pads if needed // Check if we need to restore a full hash (hidden hash deleted from drive) if (!Array.isArray(toClean)) { return; } + var done = waitFor(); var toCheck = Util.deduplicateString(toClean); var toUnpin = []; toCheck.forEach(function (channel) { // Check unpin - var data = findChannel(Env, channel, true); - if (!data.length) { toUnpin.push(channel); } - // Check hidden hash - Env.Store.checkDeletedPad(channel); + nn = nn(function (w) { + var data = findChannel(Env, channel, true); + if (!data.length) { toUnpin.push(channel); } + // Check hidden hash, one at a time, asynchronously + Env.Store.checkDeletedPad(channel, w()); + }).nThen; }); - Env.unpinPads(toUnpin, function () {}); - }); + nn(function () { + Env.unpinPads(toUnpin, function () { + done(); + }); + }); + })); })); }).nThen(cb); }; From af25c8f4b7c7cd1aefdaeb66d0566e37ca85800d Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 10 Jan 2024 16:24:09 +0100 Subject: [PATCH 210/283] Fix read-only shared folders issue #1377 --- www/common/drive-ui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 6bd2699bf..b1803a7d3 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -636,7 +636,7 @@ define([ // UI containers var $tree = APP.$tree = $("#cp-app-drive-tree"); var $content = APP.$content = $("#cp-app-drive-content"); - var $contentContainer = APP.$content = $("#cp-app-drive-content-container"); + var $contentContainer = $("#cp-app-drive-content-container"); var $appContainer = $(".cp-app-drive-container"); var $driveToolbar = APP.toolbar.$bottom; var $contextMenu = createContextMenu(common).appendTo($appContainer); From c5523d4c5ef1621383d74d6f59d85ec67243c206 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 02:02:09 +0000 Subject: [PATCH 211/283] Bump follow-redirects from 1.15.3 to 1.15.4 Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 34e3156bd..2476d1545 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2028,9 +2028,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "funding": [ { "type": "individual", From a852654b4585e3201892bd53e0136d42834a4b34 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 15 Jan 2024 15:59:51 +0100 Subject: [PATCH 212/283] Fix thumbnail not working anymore --- www/common/common-thumbnail.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/www/common/common-thumbnail.js b/www/common/common-thumbnail.js index 2298a904a..7dcf55455 100644 --- a/www/common/common-thumbnail.js +++ b/www/common/common-thumbnail.js @@ -230,17 +230,17 @@ define([ Thumb.fromDOM = function (opts, cb) { var element = opts.getContainer(); if (!element) { return; } - var todo = function () { + var todo = function (html2canvas) { + if (!window.html2canvas) { window.html2canvas = html2canvas; } if (opts.filter) { opts.filter(element, true); } window.html2canvas(element, { allowTaint: true, - onrendered: function (canvas) { - if (opts.filter) { opts.filter(element, false); } - setTimeout(function () { - var D = getResizedDimensions(canvas, 'pad'); - Thumb.fromCanvas(canvas, D, cb); - }, 10); - } + }).then(function (canvas) { + if (opts.filter) { opts.filter(element, false); } + setTimeout(function () { + var D = getResizedDimensions(canvas, 'pad'); + Thumb.fromCanvas(canvas, D, cb); + }, 10); }); }; if (window.html2canvas) { return void todo(); } From 6e132a092f324884de958b53b54fb6e2a51fe1cf Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 16 Jan 2024 16:04:33 +0100 Subject: [PATCH 213/283] lint compliance --- scripts/clean-activity.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/clean-activity.js b/scripts/clean-activity.js index 6cb3f75f6..dbb58c8f3 100644 --- a/scripts/clean-activity.js +++ b/scripts/clean-activity.js @@ -6,7 +6,6 @@ * Some .activity file were created for deleted blob due to a bug. * This script can be run once to remove these invalid activity file. **/ -var nThen = require("nthen"); var config = require("../lib/load-config"); var BlobStore = require("../lib/storage/blob"); From e92c82a7ad1ad7071badb9b1780623ce83406796 Mon Sep 17 00:00:00 2001 From: Fabrice Mouhartem Date: Wed, 17 Jan 2024 14:08:14 +0100 Subject: [PATCH 214/283] #1336: filter out temporary information with diffDOM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The issue was caused by the way ckeditor manages clipboard, creating some chunk inside a data-cke-temp span or div depending on the size (which are sometimes empty… or containing ` `), we filter them before sending data to storage. It fixes the duplicated TOC elements issue. --- www/pad/inner.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/www/pad/inner.js b/www/pad/inner.js index 4e3cdd97b..ceb26fc87 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -112,7 +112,7 @@ define([ // * Remove the drag&drop and resizers from the hyperjson var isWidget = function(el) { return typeof(el.getAttribute) === "function" && - (el.getAttribute('data-cke-hidden-sel') || + (el.getAttribute('data-cke-hidden-sel') || el.getAttribute('data-cke-temp') || (el.getAttribute('class') && (/cke_widget_drag/.test(el.getAttribute('class')) || /cke_image_resizer/.test(el.getAttribute('class'))) @@ -420,6 +420,10 @@ define([ info.node.getAttribute('class').split(' ').indexOf('cke_image_resizer') !== -1)) { return true; } + // CkEditor temporary data (used when copy-paste large chunks for instance + if (info.node && (info.node.tagName === 'SPAN' || info.node.tagName === 'DIV') && info.diff.name === 'data-cke-temp') { + return true; + } /* From 7ba6d1b49d93f970071cc08b368f402e970618d1 Mon Sep 17 00:00:00 2001 From: Fabrice Mouhartem Date: Thu, 18 Jan 2024 10:16:17 +0100 Subject: [PATCH 215/283] #1358: restore table editing in pads as default configuration - Restore context menu as table editing menu depends on it. It has been removed with commit 7f358408af8cdb85434db5433e3f1c87d8d32c80 - The paste button appears to still be there on mobile (Fennec fdroid on android 9) - #1336: missing closing parenthesis in a comment Note that you can add it to your instance configuration with the `customize/` directory: https://docs.cryptpad.org/en/admin_guide/customization.html --- customize.dist/ckeditor-config.js | 2 +- www/pad/inner.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/customize.dist/ckeditor-config.js b/customize.dist/ckeditor-config.js index 762359b9c..a0dfecfe0 100644 --- a/customize.dist/ckeditor-config.js +++ b/customize.dist/ckeditor-config.js @@ -13,7 +13,7 @@ CKEDITOR.editorConfig = function( config ) { config.removeButtons= 'Source,Maximize'; // magicline plugin inserts html crap into the document which is not part of the // document itself and causes problems when it's sent across the wire and reflected back - config.removePlugins= 'resize,elementspath,contextmenu,liststyle,tabletools,tableselection'; + config.removePlugins= 'resize,elementspath,liststyle'; config.resize_enabled= false; //bottom-bar config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print,blockbase64,mathjax,wordcount,comments'; config.toolbarGroups= [ diff --git a/www/pad/inner.js b/www/pad/inner.js index ceb26fc87..416436e8c 100644 --- a/www/pad/inner.js +++ b/www/pad/inner.js @@ -420,7 +420,7 @@ define([ info.node.getAttribute('class').split(' ').indexOf('cke_image_resizer') !== -1)) { return true; } - // CkEditor temporary data (used when copy-paste large chunks for instance + // CkEditor temporary data (used when copy-paste large chunks for instance) if (info.node && (info.node.tagName === 'SPAN' || info.node.tagName === 'DIV') && info.diff.name === 'data-cke-temp') { return true; } From 31c509d598b8d0b3eb005a72456f44c66c6e0407 Mon Sep 17 00:00:00 2001 From: Wolfgang Ginolas Date: Thu, 18 Jan 2024 10:49:38 +0100 Subject: [PATCH 216/283] Prevent draw.io from embedding images. --- www/common/{ => inner}/image-dialog.js | 0 www/common/sframe-app-framework.js | 2 +- www/diagram/inner.js | 3 +++ 3 files changed, 4 insertions(+), 1 deletion(-) rename www/common/{ => inner}/image-dialog.js (100%) diff --git a/www/common/image-dialog.js b/www/common/inner/image-dialog.js similarity index 100% rename from www/common/image-dialog.js rename to www/common/inner/image-dialog.js diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index bb1f4d834..bc082da91 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -1126,7 +1126,7 @@ define([ // Call this, when the user wants to add an image from drive. insertImage: function(data, cb) { - require(['/common/image-dialog.js'], function(imageDialog) { + require(['/common/inner/image-dialog.js'], function(imageDialog) { imageDialog.openImageDialog(common, integrationChannel, data, cb); }); }, diff --git a/www/diagram/inner.js b/www/diagram/inner.js index ce2842587..266123df8 100644 --- a/www/diagram/inner.js +++ b/www/diagram/inner.js @@ -209,6 +209,9 @@ define([ noExitBtn: 1, browser: 0, + noDevice: 1, + filesupport: 0, + modified: 'unsavedChanges', proto: 'json', From 9bdcb7be675c7543f1bf895569929421a975f487 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Thu, 18 Jan 2024 12:08:38 +0000 Subject: [PATCH 217/283] stopped file icon displaying in grid view --- customize.dist/src/less2/include/drive.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/customize.dist/src/less2/include/drive.less b/customize.dist/src/less2/include/drive.less index c76a71528..c059f2741 100644 --- a/customize.dist/src/less2/include/drive.less +++ b/customize.dist/src/less2/include/drive.less @@ -678,7 +678,7 @@ max-height: 100px; background: @cp_drive-thumb-bg; & ~ .fa, & ~ .cptools { - display: inline; + display: none; font-size: 17px; position: absolute; top: 3px; @@ -730,6 +730,7 @@ display: inline-block; white-space: nowrap; &:first-child, &.cp-icon { + display: block-inline; min-width: 20px; text-align: center; font-size: 18px; From 289cc1e1a471f4a1866e3d10ca724544ff614c63 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Thu, 18 Jan 2024 13:35:46 +0000 Subject: [PATCH 218/283] icons appended to thumbnail files only in grid view #1351 --- customize.dist/src/less2/include/drive.less | 19 +++++++++++++++++++ www/common/drive-ui.js | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/customize.dist/src/less2/include/drive.less b/customize.dist/src/less2/include/drive.less index c059f2741..ec0c0263b 100644 --- a/customize.dist/src/less2/include/drive.less +++ b/customize.dist/src/less2/include/drive.less @@ -634,6 +634,7 @@ } } div.cp-app-drive-content-grid { + padding: 1em; ul { margin: -(@drive_icon-margin); @@ -667,6 +668,19 @@ font-size: 18px; } } + .cp-app-drive-element-icon { + font-size: 12px !important; + float: left !important; + margin: 5px !important; + + } + .cp-app-drive-element-name-icon { + text-align: center !important; + float: center !important; + max-width: fit-content !important; + + } + .cp-app-drive-element-state { left: 3px; } @@ -701,6 +715,10 @@ } div.cp-app-drive-content-list { + + .cp-app-drive-element-icon { + display: none !important; + } .cp-app-drive-element-grid { display: none; } @@ -1030,5 +1048,6 @@ margin: 0 1em; } + } diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 6bd2699bf..488bb9119 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -2220,6 +2220,7 @@ define([ $element.prepend(img); $(img).addClass('cp-app-drive-element-grid cp-app-drive-element-thumbnail'); $(img).attr("draggable", false); + addTitle(element, $element, $name) } else { common.displayThumbnail(href || data.roHref, data.channel, data.password, $element, function ($thumb) { @@ -2229,6 +2230,8 @@ define([ $thumb.addClass('cp-app-drive-element-grid cp-app-drive-element-thumbnail'); $thumb.attr("draggable", false); thumbsUrls[element] = $thumb[0].src; + addTitle(element, $element, $name) + }); } @@ -2245,6 +2248,15 @@ define([ $element.append($type).append($adate).append($cdate); }; + var addTitle = function (element, $element, $name) { + var icon = getFileIcon(element) + + $(icon).addClass('cp-app-drive-element-icon') + $name.addClass('cp-app-drive-element-name-icon') + $name.prepend($(icon)) + + } + var addFolderData = function (element, key, $span) { if (!element || !manager.isFolder(element)) { return; } // The element with the class '.name' is underlined when the 'li' is hovered From 044dff41088ae9a80bf5ba7b5f2ad3c46782f728 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 18 Jan 2024 15:46:35 +0100 Subject: [PATCH 219/283] Add email field for invitations and store by default --- lib/commands/admin-rpc.js | 10 ++++++---- lib/commands/block.js | 2 +- lib/commands/invitation.js | 7 ++++--- lib/decrees.js | 4 ++-- www/admin/inner.js | 35 +++++++++++++++++++++-------------- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index bdc1cd086..cdf0a4b85 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -462,8 +462,8 @@ var instanceStatus = function (Env, Server, cb) { cb(void 0, { restrictRegistration: Env.restrictRegistration, restrictSsoRegistration: Env.restrictSsoRegistration, - storeSSOUsers: Env.storeSSOUsers, - storeInvitedUsers: Env.storeInvitedUsers, + dontStoreSSOUsers: Env.dontStoreSSOUsers, + dontStoreInvitedUsers: Env.dontStoreInvitedUsers, enableEmbedding: Env.enableEmbedding, launchTime: Env.launchTime, @@ -880,6 +880,7 @@ var addKnownUser = (Env, Server, cb, data, unsafeKey) => { edPublic, block, alias, + email: obj.email, name, type: 'manual' }; @@ -891,8 +892,9 @@ var getInvitations = (Env, Server, cb) => { Invitation.getAll(Env, cb); }; var createInvitation = (Env, Server, cb, data, unsafeKey) => { - var alias = Array.isArray(data) && data[1]; - Invitation.create(Env, alias, cb, unsafeKey); + const args = Array.isArray(data) && data[1]; + if (!args || typeof(args) !== 'object') { return void cb("EINVAL"); } + Invitation.create(Env, args.alias, args.email, cb, unsafeKey); }; var deleteInvitation = (Env, Server, cb, data) => { var id = Array.isArray(data) && data[1]; diff --git a/lib/commands/block.js b/lib/commands/block.js index aeb41ec04..123a0d6a7 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -194,7 +194,7 @@ Block.writeLoginBlock = function (Env, msg, _cb) { publicKey }); }); - } else if (isSSO && Env.storeSSOUsers && !registrationProof) { + } else if (isSSO && !Env.dontStoreSSOUsers && !registrationProof) { let edPublic = Array.isArray(userData) && userData[1]; let name = Array.isArray(userData) && userData[0]; if (!edPublic) { return; } diff --git a/lib/commands/invitation.js b/lib/commands/invitation.js index bafae4f10..cf22b3920 100644 --- a/lib/commands/invitation.js +++ b/lib/commands/invitation.js @@ -16,11 +16,12 @@ Invitation.getAll = (Env, cb) => { }); }; -Invitation.create = (Env, alias, _cb, unsafeKey) => { +Invitation.create = (Env, alias, email, _cb, unsafeKey) => { const cb = Util.once(Util.mkAsync(_cb)); const id = getUid(); const invitation = { - alias: alias, + alias, + email, createdBy: unsafeKey, time: +new Date() }; @@ -60,7 +61,7 @@ Invitation.use = (Env, id, blockId, userData, _cb) => { data.edPublic = edPublic; data.type = 'invite:' + id; let adminKey = data.createdBy; - if (Env.storeInvitedUsers) { + if (!Env.dontStoreInvitedUsers) { Users.add(Env, edPublic, data, adminKey, (err) => { if (err) { Env.Log.error('INVITATION_ADD_USER', { diff --git a/lib/decrees.js b/lib/decrees.js index f54d9975d..35789fc63 100644 --- a/lib/decrees.js +++ b/lib/decrees.js @@ -114,8 +114,8 @@ commands.ENFORCE_MFA = makeBooleanSetter('enforceMFA'); // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['RESTRICT_REGISTRATION', [true]]], console.log) commands.RESTRICT_REGISTRATION = makeBooleanSetter('restrictRegistration'); commands.RESTRICT_SSO_REGISTRATION = makeBooleanSetter('restrictSsoRegistration'); -commands.STORE_INVITED_USERS = makeBooleanSetter('storeInvitedUsers'); -commands.STORE_SSO_USERS = makeBooleanSetter('storeSSOUsers'); +commands.DISABLE_STORE_INVITED_USERS = makeBooleanSetter('dontStoreInvitedUsers'); +commands.DISABLE_STORE_SSO_USERS = makeBooleanSetter('dontStoreSSOUsers'); // CryptPad_AsyncStore.rpc.send('ADMIN', [ 'ADMIN_DECREE', ['DISABLE_INTEGRATED_EVICTION', [true]]], console.log) commands.DISABLE_INTEGRATED_EVICTION = makeBooleanSetter('disableIntegratedEviction'); diff --git a/www/admin/inner.js b/www/admin/inner.js index 438c3b5d5..f508c46be 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -1574,8 +1574,9 @@ Example var list = h('table'); var input = h('input', { placeholder: 'ALIAS' }); // XXX + var inputEmail = h('input', { placeholder: 'EMAIL' }); // XXX var button = h('button.btn.btn-primary', Messages.admin_invitationCreate); - var add = h('div', [input, button]); + var add = h('div', [input, inputEmail, button]); var $b = $(button); @@ -1641,10 +1642,15 @@ Example refreshInvite(); $b.on('click', () => { + var alias = $(input).val().trim(); + if (!alias) { return void UI.warn(Messages.error); } // XXX bettter message? $b.prop('disabled', true); sFrameChan.query('Q_ADMIN_RPC', { cmd: 'CREATE_INVITATION', - data: $(input).val() + data: { + alias, + email: $(inputEmail).val() + } }, function (e, response) { $b.prop('disabled', false); if (e || response.error) { @@ -1671,10 +1677,11 @@ Example var list = h('table'); var userAlias = h('input', { placeholder: 'ALIAS' }); // XXX + var userEmail = h('input', { placeholder: 'EMAIL' }); // XXX var userEdPublic = h('input', { placeholder: 'USER PUBLIC KEY' }); // XXX var userBlock = h('input', { placeholder: 'USER BLOCK (optional)' }); // XXX var button = h('button.btn.btn-primary', Messages.admin_usersAdd); - var add = h('div', [userAlias, userEdPublic, userBlock, button]); + var add = h('div', [userAlias, userEmail, userEdPublic, userBlock, button]); var $b = $(button); @@ -1683,19 +1690,19 @@ Example var $invited = makeAdminCheckbox({ key: 'store-invited', getState: function () { - return APP.instanceStatus.storeInvitedUsers; + return !APP.instanceStatus.dontStoreInvitedUsers; }, query: function (val, setState) { sFrameChan.query('Q_ADMIN_RPC', { cmd: 'ADMIN_DECREE', - data: ['STORE_INVITED_USERS', [val]] + data: ['DISABLE_STORE_INVITED_USERS', [!val]] }, function (e, response) { if (e || response.error) { UI.warn(Messages.error); console.error(e, response); } APP.updateStatus(function () { - setState(APP.instanceStatus.storeInvitedUsers); + setState(!APP.instanceStatus.dontStoreInvitedUsers); flushCacheNotice(); }); }); @@ -1707,19 +1714,19 @@ Example var $sso = makeAdminCheckbox({ key: 'store-sso', getState: function () { - return APP.instanceStatus.storeSSOUsers; + return !APP.instanceStatus.dontStoreSSOUsers; }, query: function (val, setState) { sFrameChan.query('Q_ADMIN_RPC', { cmd: 'ADMIN_DECREE', - data: ['STORE_SSO_USERS', [val]] + data: ['DISABLE_STORE_SSO_USERS', [!val]] }, function (e, response) { if (e || response.error) { UI.warn(Messages.error); console.error(e, response); } APP.updateStatus(function () { - setState(APP.instanceStatus.storeSSOUsers); + setState(!APP.instanceStatus.dontStoreSSOUsers); flushCacheNotice(); }); }); @@ -1790,13 +1797,12 @@ Example refreshUsers(); $b.on('click', () => { + var alias = $(userAlias).val().trim(); + if (!alias) { return void UI.warn(Messages.error); } // XXX bettter message? $b.prop('disabled', true); - // XXX CHECK ALL VALUES ARE AVAILABLE - // XXX PARSE FULL KEY INTO EDPUBLIC - // XXX PARSE BLOCK HASH INTO BLOCK KEY - // XXX GET BLOCK FROM PIN LOG? var done = () => { $b.prop('disabled', false); }; + // TODO Get "block" from pin log? var keyStr = $(userEdPublic).val().trim(); var parsed = keyStr && Keys.parseUser(keyStr); @@ -1807,7 +1813,8 @@ Example var block = getBlockId($(userBlock).val()); var obj = { - alias: $(userAlias).val(), + alias, + email: $(userEmail).val(), block: block, edPublic: parsed.edPublic, name: parsed.user From 986b05fdfe133056d165500fc6b2306b96c7dc91 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 18 Jan 2024 16:32:06 +0100 Subject: [PATCH 220/283] Add ability to update known user name and email --- lib/commands/admin-rpc.js | 13 ++++++- lib/commands/users.js | 23 +++++++++++ www/admin/inner.js | 82 +++++++++++++++++++++++++++++++++------ www/common/common-util.js | 10 +++++ 4 files changed, 116 insertions(+), 12 deletions(-) diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index cdf0a4b85..b66f3b549 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -886,7 +886,16 @@ var addKnownUser = (Env, Server, cb, data, unsafeKey) => { }; Users.add(Env, edPublic, userData, unsafeKey, cb); }; -// XXX delete user, update user (add block, update storage limit, etc.) +var deleteKnownUser = (Env, Server, cb, data) => { + var id = Array.isArray(data) && data[1]; + Users.delete(Env, id, cb); +}; +var updateKnownUser = (Env, Server, cb, data) => { + var args = Array.isArray(data) && data[1]; + var edPublic = args.edPublic; + var changes = args.changes; + Users.update(Env, edPublic, changes, cb); +}; var getInvitations = (Env, Server, cb) => { Invitation.getAll(Env, cb); @@ -966,6 +975,8 @@ var commands = { GET_ALL_USERS: getKnownUsers, ADD_KNOWN_USER: addKnownUser, + DELETE_KNOWN_USER: deleteKnownUser, + UPDATE_KNOWN_USER: updateKnownUser, }; // addFirstAdmin is an anon_rpc command diff --git a/lib/commands/users.js b/lib/commands/users.js index 3fc161190..f88b2b625 100644 --- a/lib/commands/users.js +++ b/lib/commands/users.js @@ -38,6 +38,29 @@ Users.read = (Env, edPublic, _cb) => { }); }; +Users.update = (Env, edPublic, changes, _cb) => { + const cb = Util.once(Util.mkAsync(_cb)); + Users.read(Env, edPublic, (err, data) => { + if (err === 'ENOENT') { return void cb(); } + if (err) { return void cb(err); } + if (typeof(changes) !== "object") { return void cb('EINVAL'); } + // User exists, update their data + var aborted = Object.keys(changes || {}).some((key) => { + if (changes[key] === false) { + delete data[key]; + return; + } + if (String(changes[key]).length > 300) { + cb('E_TOO_LONG'); + return true; + } + data[key] = changes[key]; + }); + if (aborted) { return; } + User.update(Env, edPublic, data, cb); + }); +}; + // On password change, update the block Users.checkUpdate = (Env, userData, newBlock, cb) => { if (!Array.isArray(userData)) { userData = []; } diff --git a/www/admin/inner.js b/www/admin/inner.js index f508c46be..c2a072b6e 100644 --- a/www/admin/inner.js +++ b/www/admin/inner.js @@ -1585,6 +1585,11 @@ Example var refreshInvite = function () {}; + var refresh = h('div', h('button.btn.btn-primary', Messages.oo_refresh)); + Util.onClickEnter($(refresh).find('button'), function () { + refreshInvite(); + }); + var deleteInvite = function (id) { sFrameChan.query('Q_ADMIN_RPC', { cmd: 'DELETE_INVITATION', @@ -1662,7 +1667,7 @@ Example }); }); - $div.append([add, list]); + $div.append([add, refresh, list]); return $div; }; @@ -1687,6 +1692,11 @@ Example var refreshUsers = function () {}; + var refresh = h('div', h('button.btn.btn-primary', Messages.oo_refresh)); + Util.onClickEnter($(refresh).find('button'), function () { + refreshUsers(); + }); + var $invited = makeAdminCheckbox({ key: 'store-invited', getState: function () { @@ -1739,19 +1749,32 @@ Example $div.append($sso); } - var deleteUser = function (/*id*/) { - /* + var deleteUser = function (id) { sFrameChan.query('Q_ADMIN_RPC', { cmd: 'DELETE_KNOWN_USER', data: id }, function (e, response) { - $b.prop('disabled', false); if (e || response.error) { UI.warn(Messages.error); return void console.error(e, response); } refreshUsers(); - });*/ + }); + }; + var updateUser = function (key, changes) { + sFrameChan.query('Q_ADMIN_RPC', { + cmd: 'UPDATE_KNOWN_USER', + data: { + edPublic: key, + changes: changes + } + }, function (e, response) { + if (e || response.error) { + UI.warn(Messages.error); + return void console.error(e, response); + } + refreshUsers(); + }); }; var $list = $(list); refreshUsers = function () { @@ -1766,15 +1789,19 @@ Example } if (!Array.isArray(response)) { return; } var all = response[0]; - console.log(all); Object.keys(all).forEach(function (key) { var data = all[key]; - + var editUser = () => {}; var del = h('button.btn.btn-danger.fa.fa-trash'); $(del).click(function () { // XXX CONFIRM deleteUser(key); }); + var edit = h('button.btn.btn-secondary.fa.fa-pencil'); + $(edit).click(function () { + // XXX CONFIRM + editUser(); + }); var copy = h('button.btn.btn-secondary.fa.fa-clipboard'); $(copy).click(function () { var success = Clipboard.copy(key, () => { @@ -1782,13 +1809,46 @@ Example }); if (success) { UI.log(Messages.genericCopySuccess); } // XXX merge staging delete this line }); + + var alias = h('td', data.alias); + var email = h('td', data.email); + var actions = h('td', [copy, edit, del]); + var $alias = $(alias); + var $email = $(email); + var $actions = $(actions); + + editUser = () => { + var aliasInput = h('input'); + var emailInput = h('input'); + $(aliasInput).val(data.alias); + $(emailInput).val(data.email); + var save = h('button.btn.btn-primary', Messages.settings_save); + var cancel = h('button.btn.btn-secondary', Messages.cancel); + Util.onClickEnter($(save), function () { + var aliasVal = $(aliasInput).val().trim(); + if (!aliasVal) { return void UI.warn(Messages.error); } + var changes = { + alias: aliasVal, + email: $(emailInput).val().trim() + }; + updateUser(key, changes); + }); + Util.onClickEnter($(cancel), function () { + refreshUsers(); + }); + $alias.html('').append(aliasInput); + $email.html('').append(emailInput); + $actions.html('').append([save, cancel]); + console.warn(alias, email, $alias, $email, aliasInput); + }; + var line = h('tr', [ - h('td', data.alias), + alias, + email, h('td', h('pre', key)), h('td', new Date(data.time).toLocaleString()), //h('td', data.createdBy), - copy, - del + actions ]); $list.append(line); }); @@ -1835,7 +1895,7 @@ Example }); }); - $div.append([add, list]); + $div.append([add, refresh, list]); return $div; }; diff --git a/www/common/common-util.js b/www/common/common-util.js index e5471c1ff..a6be79628 100644 --- a/www/common/common-util.js +++ b/www/common/common-util.js @@ -107,6 +107,16 @@ }); }; + Util.onClickEnter = function ($element, handler, cfg) { + $element.on('click keydown', function (e) { + var isClick = e.type === 'click'; + var isEnter = e.type === 'keydown' && e.which === 13; + var isSpace = e.type === 'keydown' && e.which === 32 && cfg && cfg.space; + if (!isClick && !isEnter && !isSpace) { return; } + handler(); + }); + }; + Util.response = function (errorHandler) { var pending = {}; var timeouts = {}; From 1f011b7fe990aa75e6ff6bd1107e9da6e1cad144 Mon Sep 17 00:00:00 2001 From: zuzanna-maria Date: Mon, 22 Jan 2024 13:22:01 +0000 Subject: [PATCH 221/283] linting --- customize.dist/src/less2/include/drive.less | 5 --- www/common/drive-ui.js | 40 ++++++++++----------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/customize.dist/src/less2/include/drive.less b/customize.dist/src/less2/include/drive.less index ec0c0263b..e8b05bb1e 100644 --- a/customize.dist/src/less2/include/drive.less +++ b/customize.dist/src/less2/include/drive.less @@ -634,7 +634,6 @@ } } div.cp-app-drive-content-grid { - padding: 1em; ul { margin: -(@drive_icon-margin); @@ -672,13 +671,11 @@ font-size: 12px !important; float: left !important; margin: 5px !important; - } .cp-app-drive-element-name-icon { text-align: center !important; float: center !important; max-width: fit-content !important; - } .cp-app-drive-element-state { @@ -715,7 +712,6 @@ } div.cp-app-drive-content-list { - .cp-app-drive-element-icon { display: none !important; } @@ -1048,6 +1044,5 @@ margin: 0 1em; } - } diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 488bb9119..fe1fff1ae 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -2150,6 +2150,22 @@ define([ } */ }; var thumbsUrls = {}; + + // This is duplicated in cryptpad-common, it should be unified + var getFileIcon = function (id) { + var data = manager.getFileData(id); + return UI.getFileIcon(data); + }; + var getIcon = UI.getIcon; + + var addTitle = function (element, $name) { + var icon = getFileIcon(element); + + $(icon).addClass('cp-app-drive-element-icon'); + $name.addClass('cp-app-drive-element-name-icon'); + $name.prepend($(icon)); + }; + var addFileData = function (element, $element) { if (!manager.isFile(element)) { return; } @@ -2220,9 +2236,8 @@ define([ $element.prepend(img); $(img).addClass('cp-app-drive-element-grid cp-app-drive-element-thumbnail'); $(img).attr("draggable", false); - addTitle(element, $element, $name) - } - else { + addTitle(element, $name); + } else { common.displayThumbnail(href || data.roHref, data.channel, data.password, $element, function ($thumb) { // Called only if the thumbnail exists // Remove the .hide() added by displayThumnail() because it hides the icon in list mode too @@ -2230,8 +2245,7 @@ define([ $thumb.addClass('cp-app-drive-element-grid cp-app-drive-element-thumbnail'); $thumb.attr("draggable", false); thumbsUrls[element] = $thumb[0].src; - addTitle(element, $element, $name) - + addTitle(element, $name); }); } @@ -2248,15 +2262,6 @@ define([ $element.append($type).append($adate).append($cdate); }; - var addTitle = function (element, $element, $name) { - var icon = getFileIcon(element) - - $(icon).addClass('cp-app-drive-element-icon') - $name.addClass('cp-app-drive-element-name-icon') - $name.prepend($(icon)) - - } - var addFolderData = function (element, key, $span) { if (!element || !manager.isFolder(element)) { return; } // The element with the class '.name' is underlined when the 'li' is hovered @@ -2320,13 +2325,6 @@ define([ } }; - // This is duplicated in cryptpad-common, it should be unified - var getFileIcon = function (id) { - var data = manager.getFileData(id); - return UI.getFileIcon(data); - }; - var getIcon = UI.getIcon; - var createShareButton = function (id, $container) { var $shareBlock = $(' + + + +
+
+ +
+
+
+ + +
+
+ +
+
+
+ + + +
+
+ + +
+ + + + + + + + + + + + +
+
+
+
+ +
+ +
+ +
+ +
+ + + + +
+
+
+ + + + +
+ +
+ + + + + +
+ + +
+
+
+ +
+ +
+ + + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+ +
+ +
+
+ +
+
+ + +
+
+ +
+ File name: +

-

+
+
+ File size: +

-

+
+
+
+ Title: +

-

+
+
+ Author: +

-

+
+
+ Subject: +

-

+
+
+ Keywords: +

-

+
+
+ Creation Date: +

-

+
+
+ Modification Date: +

-

+
+
+ Creator: +

-

+
+
+
+ PDF Producer: +

-

+
+
+ PDF Version: +

-

+
+
+ Page Count: +

-

+
+
+ Page Size: +

-

+
+
+
+ Fast Web View: +

-

+
+
+ +
+
+ +
+
+ Choose an option + + Alt text (alternative text) helps when people can’t see the image or when it doesn’t load. + +
+
+
+
+ + +
+
+ + Aim for 1-2 sentences that describe the subject, setting, or actions. + +
+
+
+ +
+
+
+
+
+ + +
+
+ + This is used for ornamental images, like borders or watermarks. + +
+
+
+
+ + +
+
+
+ +
+ Preparing document for printing… +
+
+ + 0% +
+
+ +
+
+
+ + +
+ + + + diff --git a/www/lib/pdfjs/modern/web/viewer.mjs b/www/lib/pdfjs/modern/web/viewer.mjs new file mode 100644 index 000000000..e9041cadd --- /dev/null +++ b/www/lib/pdfjs/modern/web/viewer.mjs @@ -0,0 +1,15114 @@ +/** + * @licstart The following is the entire license notice for the + * JavaScript code in this page + * + * Copyright 2023 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @licend The above is the entire license notice for the + * JavaScript code in this page + */ + +/******/ var __webpack_modules__ = ({ + +/***/ 8759: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + FluentBundle: () => (/* reexport */ FluentBundle), + FluentResource: () => (/* reexport */ FluentResource) +}); + +// UNUSED EXPORTS: FluentDateTime, FluentNone, FluentNumber, FluentType + +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/types.js +class FluentType { + constructor(value) { + this.value = value; + } + valueOf() { + return this.value; + } +} +class FluentNone extends FluentType { + constructor(value = "???") { + super(value); + } + toString(scope) { + return `{${this.value}}`; + } +} +class FluentNumber extends FluentType { + constructor(value, opts = {}) { + super(value); + this.opts = opts; + } + toString(scope) { + try { + const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts); + return nf.format(this.value); + } catch (err) { + scope.reportError(err); + return this.value.toString(10); + } + } +} +class FluentDateTime extends FluentType { + constructor(value, opts = {}) { + super(value); + this.opts = opts; + } + toString(scope) { + try { + const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts); + return dtf.format(this.value); + } catch (err) { + scope.reportError(err); + return new Date(this.value).toISOString(); + } + } +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/resolver.js + +const MAX_PLACEABLES = 100; +const FSI = "\u2068"; +const PDI = "\u2069"; +function match(scope, selector, key) { + if (key === selector) { + return true; + } + if (key instanceof FluentNumber && selector instanceof FluentNumber && key.value === selector.value) { + return true; + } + if (selector instanceof FluentNumber && typeof key === "string") { + let category = scope.memoizeIntlObject(Intl.PluralRules, selector.opts).select(selector.value); + if (key === category) { + return true; + } + } + return false; +} +function getDefault(scope, variants, star) { + if (variants[star]) { + return resolvePattern(scope, variants[star].value); + } + scope.reportError(new RangeError("No default")); + return new FluentNone(); +} +function getArguments(scope, args) { + const positional = []; + const named = Object.create(null); + for (const arg of args) { + if (arg.type === "narg") { + named[arg.name] = resolveExpression(scope, arg.value); + } else { + positional.push(resolveExpression(scope, arg)); + } + } + return { + positional, + named + }; +} +function resolveExpression(scope, expr) { + switch (expr.type) { + case "str": + return expr.value; + case "num": + return new FluentNumber(expr.value, { + minimumFractionDigits: expr.precision + }); + case "var": + return resolveVariableReference(scope, expr); + case "mesg": + return resolveMessageReference(scope, expr); + case "term": + return resolveTermReference(scope, expr); + case "func": + return resolveFunctionReference(scope, expr); + case "select": + return resolveSelectExpression(scope, expr); + default: + return new FluentNone(); + } +} +function resolveVariableReference(scope, { + name +}) { + let arg; + if (scope.params) { + if (Object.prototype.hasOwnProperty.call(scope.params, name)) { + arg = scope.params[name]; + } else { + return new FluentNone(`$${name}`); + } + } else if (scope.args && Object.prototype.hasOwnProperty.call(scope.args, name)) { + arg = scope.args[name]; + } else { + scope.reportError(new ReferenceError(`Unknown variable: $${name}`)); + return new FluentNone(`$${name}`); + } + if (arg instanceof FluentType) { + return arg; + } + switch (typeof arg) { + case "string": + return arg; + case "number": + return new FluentNumber(arg); + case "object": + if (arg instanceof Date) { + return new FluentDateTime(arg.getTime()); + } + default: + scope.reportError(new TypeError(`Variable type not supported: $${name}, ${typeof arg}`)); + return new FluentNone(`$${name}`); + } +} +function resolveMessageReference(scope, { + name, + attr +}) { + const message = scope.bundle._messages.get(name); + if (!message) { + scope.reportError(new ReferenceError(`Unknown message: ${name}`)); + return new FluentNone(name); + } + if (attr) { + const attribute = message.attributes[attr]; + if (attribute) { + return resolvePattern(scope, attribute); + } + scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`)); + return new FluentNone(`${name}.${attr}`); + } + if (message.value) { + return resolvePattern(scope, message.value); + } + scope.reportError(new ReferenceError(`No value: ${name}`)); + return new FluentNone(name); +} +function resolveTermReference(scope, { + name, + attr, + args +}) { + const id = `-${name}`; + const term = scope.bundle._terms.get(id); + if (!term) { + scope.reportError(new ReferenceError(`Unknown term: ${id}`)); + return new FluentNone(id); + } + if (attr) { + const attribute = term.attributes[attr]; + if (attribute) { + scope.params = getArguments(scope, args).named; + const resolved = resolvePattern(scope, attribute); + scope.params = null; + return resolved; + } + scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`)); + return new FluentNone(`${id}.${attr}`); + } + scope.params = getArguments(scope, args).named; + const resolved = resolvePattern(scope, term.value); + scope.params = null; + return resolved; +} +function resolveFunctionReference(scope, { + name, + args +}) { + let func = scope.bundle._functions[name]; + if (!func) { + scope.reportError(new ReferenceError(`Unknown function: ${name}()`)); + return new FluentNone(`${name}()`); + } + if (typeof func !== "function") { + scope.reportError(new TypeError(`Function ${name}() is not callable`)); + return new FluentNone(`${name}()`); + } + try { + let resolved = getArguments(scope, args); + return func(resolved.positional, resolved.named); + } catch (err) { + scope.reportError(err); + return new FluentNone(`${name}()`); + } +} +function resolveSelectExpression(scope, { + selector, + variants, + star +}) { + let sel = resolveExpression(scope, selector); + if (sel instanceof FluentNone) { + return getDefault(scope, variants, star); + } + for (const variant of variants) { + const key = resolveExpression(scope, variant.key); + if (match(scope, sel, key)) { + return resolvePattern(scope, variant.value); + } + } + return getDefault(scope, variants, star); +} +function resolveComplexPattern(scope, ptn) { + if (scope.dirty.has(ptn)) { + scope.reportError(new RangeError("Cyclic reference")); + return new FluentNone(); + } + scope.dirty.add(ptn); + const result = []; + const useIsolating = scope.bundle._useIsolating && ptn.length > 1; + for (const elem of ptn) { + if (typeof elem === "string") { + result.push(scope.bundle._transform(elem)); + continue; + } + scope.placeables++; + if (scope.placeables > MAX_PLACEABLES) { + scope.dirty.delete(ptn); + throw new RangeError(`Too many placeables expanded: ${scope.placeables}, ` + `max allowed is ${MAX_PLACEABLES}`); + } + if (useIsolating) { + result.push(FSI); + } + result.push(resolveExpression(scope, elem).toString(scope)); + if (useIsolating) { + result.push(PDI); + } + } + scope.dirty.delete(ptn); + return result.join(""); +} +function resolvePattern(scope, value) { + if (typeof value === "string") { + return scope.bundle._transform(value); + } + return resolveComplexPattern(scope, value); +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/scope.js +class Scope { + constructor(bundle, errors, args) { + this.dirty = new WeakSet(); + this.params = null; + this.placeables = 0; + this.bundle = bundle; + this.errors = errors; + this.args = args; + } + reportError(error) { + if (!this.errors || !(error instanceof Error)) { + throw error; + } + this.errors.push(error); + } + memoizeIntlObject(ctor, opts) { + let cache = this.bundle._intls.get(ctor); + if (!cache) { + cache = {}; + this.bundle._intls.set(ctor, cache); + } + let id = JSON.stringify(opts); + if (!cache[id]) { + cache[id] = new ctor(this.bundle.locales, opts); + } + return cache[id]; + } +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/builtins.js + +function values(opts, allowed) { + const unwrapped = Object.create(null); + for (const [name, opt] of Object.entries(opts)) { + if (allowed.includes(name)) { + unwrapped[name] = opt.valueOf(); + } + } + return unwrapped; +} +const NUMBER_ALLOWED = ["unitDisplay", "currencyDisplay", "useGrouping", "minimumIntegerDigits", "minimumFractionDigits", "maximumFractionDigits", "minimumSignificantDigits", "maximumSignificantDigits"]; +function NUMBER(args, opts) { + let arg = args[0]; + if (arg instanceof FluentNone) { + return new FluentNone(`NUMBER(${arg.valueOf()})`); + } + if (arg instanceof FluentNumber) { + return new FluentNumber(arg.valueOf(), { + ...arg.opts, + ...values(opts, NUMBER_ALLOWED) + }); + } + if (arg instanceof FluentDateTime) { + return new FluentNumber(arg.valueOf(), { + ...values(opts, NUMBER_ALLOWED) + }); + } + throw new TypeError("Invalid argument to NUMBER"); +} +const DATETIME_ALLOWED = ["dateStyle", "timeStyle", "fractionalSecondDigits", "dayPeriod", "hour12", "weekday", "era", "year", "month", "day", "hour", "minute", "second", "timeZoneName"]; +function DATETIME(args, opts) { + let arg = args[0]; + if (arg instanceof FluentNone) { + return new FluentNone(`DATETIME(${arg.valueOf()})`); + } + if (arg instanceof FluentDateTime) { + return new FluentDateTime(arg.valueOf(), { + ...arg.opts, + ...values(opts, DATETIME_ALLOWED) + }); + } + if (arg instanceof FluentNumber) { + return new FluentDateTime(arg.valueOf(), { + ...values(opts, DATETIME_ALLOWED) + }); + } + throw new TypeError("Invalid argument to DATETIME"); +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/memoizer.js +const cache = new Map(); +function getMemoizerForLocale(locales) { + const stringLocale = Array.isArray(locales) ? locales.join(" ") : locales; + let memoizer = cache.get(stringLocale); + if (memoizer === undefined) { + memoizer = new Map(); + cache.set(stringLocale, memoizer); + } + return memoizer; +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/bundle.js + + + + + +class FluentBundle { + constructor(locales, { + functions, + useIsolating = true, + transform = v => v + } = {}) { + this._terms = new Map(); + this._messages = new Map(); + this.locales = Array.isArray(locales) ? locales : [locales]; + this._functions = { + NUMBER: NUMBER, + DATETIME: DATETIME, + ...functions + }; + this._useIsolating = useIsolating; + this._transform = transform; + this._intls = getMemoizerForLocale(locales); + } + hasMessage(id) { + return this._messages.has(id); + } + getMessage(id) { + return this._messages.get(id); + } + addResource(res, { + allowOverrides = false + } = {}) { + const errors = []; + for (let i = 0; i < res.body.length; i++) { + let entry = res.body[i]; + if (entry.id.startsWith("-")) { + if (allowOverrides === false && this._terms.has(entry.id)) { + errors.push(new Error(`Attempt to override an existing term: "${entry.id}"`)); + continue; + } + this._terms.set(entry.id, entry); + } else { + if (allowOverrides === false && this._messages.has(entry.id)) { + errors.push(new Error(`Attempt to override an existing message: "${entry.id}"`)); + continue; + } + this._messages.set(entry.id, entry); + } + } + return errors; + } + formatPattern(pattern, args = null, errors = null) { + if (typeof pattern === "string") { + return this._transform(pattern); + } + let scope = new Scope(this, errors, args); + try { + let value = resolveComplexPattern(scope, pattern); + return value.toString(scope); + } catch (err) { + if (scope.errors && err instanceof Error) { + scope.errors.push(err); + return new FluentNone().toString(scope); + } + throw err; + } + } +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/resource.js +const RE_MESSAGE_START = /^(-?[a-zA-Z][\w-]*) *= */gm; +const RE_ATTRIBUTE_START = /\.([a-zA-Z][\w-]*) *= */y; +const RE_VARIANT_START = /\*?\[/y; +const RE_NUMBER_LITERAL = /(-?[0-9]+(?:\.([0-9]+))?)/y; +const RE_IDENTIFIER = /([a-zA-Z][\w-]*)/y; +const RE_REFERENCE = /([$-])?([a-zA-Z][\w-]*)(?:\.([a-zA-Z][\w-]*))?/y; +const RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/; +const RE_TEXT_RUN = /([^{}\n\r]+)/y; +const RE_STRING_RUN = /([^\\"\n\r]*)/y; +const RE_STRING_ESCAPE = /\\([\\"])/y; +const RE_UNICODE_ESCAPE = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{6})/y; +const RE_LEADING_NEWLINES = /^\n+/; +const RE_TRAILING_SPACES = / +$/; +const RE_BLANK_LINES = / *\r?\n/g; +const RE_INDENT = /( *)$/; +const TOKEN_BRACE_OPEN = /{\s*/y; +const TOKEN_BRACE_CLOSE = /\s*}/y; +const TOKEN_BRACKET_OPEN = /\[\s*/y; +const TOKEN_BRACKET_CLOSE = /\s*] */y; +const TOKEN_PAREN_OPEN = /\s*\(\s*/y; +const TOKEN_ARROW = /\s*->\s*/y; +const TOKEN_COLON = /\s*:\s*/y; +const TOKEN_COMMA = /\s*,?\s*/y; +const TOKEN_BLANK = /\s+/y; +class FluentResource { + constructor(source) { + this.body = []; + RE_MESSAGE_START.lastIndex = 0; + let cursor = 0; + while (true) { + let next = RE_MESSAGE_START.exec(source); + if (next === null) { + break; + } + cursor = RE_MESSAGE_START.lastIndex; + try { + this.body.push(parseMessage(next[1])); + } catch (err) { + if (err instanceof SyntaxError) { + continue; + } + throw err; + } + } + function test(re) { + re.lastIndex = cursor; + return re.test(source); + } + function consumeChar(char, errorClass) { + if (source[cursor] === char) { + cursor++; + return true; + } + if (errorClass) { + throw new errorClass(`Expected ${char}`); + } + return false; + } + function consumeToken(re, errorClass) { + if (test(re)) { + cursor = re.lastIndex; + return true; + } + if (errorClass) { + throw new errorClass(`Expected ${re.toString()}`); + } + return false; + } + function match(re) { + re.lastIndex = cursor; + let result = re.exec(source); + if (result === null) { + throw new SyntaxError(`Expected ${re.toString()}`); + } + cursor = re.lastIndex; + return result; + } + function match1(re) { + return match(re)[1]; + } + function parseMessage(id) { + let value = parsePattern(); + let attributes = parseAttributes(); + if (value === null && Object.keys(attributes).length === 0) { + throw new SyntaxError("Expected message value or attributes"); + } + return { + id, + value, + attributes + }; + } + function parseAttributes() { + let attrs = Object.create(null); + while (test(RE_ATTRIBUTE_START)) { + let name = match1(RE_ATTRIBUTE_START); + let value = parsePattern(); + if (value === null) { + throw new SyntaxError("Expected attribute value"); + } + attrs[name] = value; + } + return attrs; + } + function parsePattern() { + let first; + if (test(RE_TEXT_RUN)) { + first = match1(RE_TEXT_RUN); + } + if (source[cursor] === "{" || source[cursor] === "}") { + return parsePatternElements(first ? [first] : [], Infinity); + } + let indent = parseIndent(); + if (indent) { + if (first) { + return parsePatternElements([first, indent], indent.length); + } + indent.value = trim(indent.value, RE_LEADING_NEWLINES); + return parsePatternElements([indent], indent.length); + } + if (first) { + return trim(first, RE_TRAILING_SPACES); + } + return null; + } + function parsePatternElements(elements = [], commonIndent) { + while (true) { + if (test(RE_TEXT_RUN)) { + elements.push(match1(RE_TEXT_RUN)); + continue; + } + if (source[cursor] === "{") { + elements.push(parsePlaceable()); + continue; + } + if (source[cursor] === "}") { + throw new SyntaxError("Unbalanced closing brace"); + } + let indent = parseIndent(); + if (indent) { + elements.push(indent); + commonIndent = Math.min(commonIndent, indent.length); + continue; + } + break; + } + let lastIndex = elements.length - 1; + let lastElement = elements[lastIndex]; + if (typeof lastElement === "string") { + elements[lastIndex] = trim(lastElement, RE_TRAILING_SPACES); + } + let baked = []; + for (let element of elements) { + if (element instanceof Indent) { + element = element.value.slice(0, element.value.length - commonIndent); + } + if (element) { + baked.push(element); + } + } + return baked; + } + function parsePlaceable() { + consumeToken(TOKEN_BRACE_OPEN, SyntaxError); + let selector = parseInlineExpression(); + if (consumeToken(TOKEN_BRACE_CLOSE)) { + return selector; + } + if (consumeToken(TOKEN_ARROW)) { + let variants = parseVariants(); + consumeToken(TOKEN_BRACE_CLOSE, SyntaxError); + return { + type: "select", + selector, + ...variants + }; + } + throw new SyntaxError("Unclosed placeable"); + } + function parseInlineExpression() { + if (source[cursor] === "{") { + return parsePlaceable(); + } + if (test(RE_REFERENCE)) { + let [, sigil, name, attr = null] = match(RE_REFERENCE); + if (sigil === "$") { + return { + type: "var", + name + }; + } + if (consumeToken(TOKEN_PAREN_OPEN)) { + let args = parseArguments(); + if (sigil === "-") { + return { + type: "term", + name, + attr, + args + }; + } + if (RE_FUNCTION_NAME.test(name)) { + return { + type: "func", + name, + args + }; + } + throw new SyntaxError("Function names must be all upper-case"); + } + if (sigil === "-") { + return { + type: "term", + name, + attr, + args: [] + }; + } + return { + type: "mesg", + name, + attr + }; + } + return parseLiteral(); + } + function parseArguments() { + let args = []; + while (true) { + switch (source[cursor]) { + case ")": + cursor++; + return args; + case undefined: + throw new SyntaxError("Unclosed argument list"); + } + args.push(parseArgument()); + consumeToken(TOKEN_COMMA); + } + } + function parseArgument() { + let expr = parseInlineExpression(); + if (expr.type !== "mesg") { + return expr; + } + if (consumeToken(TOKEN_COLON)) { + return { + type: "narg", + name: expr.name, + value: parseLiteral() + }; + } + return expr; + } + function parseVariants() { + let variants = []; + let count = 0; + let star; + while (test(RE_VARIANT_START)) { + if (consumeChar("*")) { + star = count; + } + let key = parseVariantKey(); + let value = parsePattern(); + if (value === null) { + throw new SyntaxError("Expected variant value"); + } + variants[count++] = { + key, + value + }; + } + if (count === 0) { + return null; + } + if (star === undefined) { + throw new SyntaxError("Expected default variant"); + } + return { + variants, + star + }; + } + function parseVariantKey() { + consumeToken(TOKEN_BRACKET_OPEN, SyntaxError); + let key; + if (test(RE_NUMBER_LITERAL)) { + key = parseNumberLiteral(); + } else { + key = { + type: "str", + value: match1(RE_IDENTIFIER) + }; + } + consumeToken(TOKEN_BRACKET_CLOSE, SyntaxError); + return key; + } + function parseLiteral() { + if (test(RE_NUMBER_LITERAL)) { + return parseNumberLiteral(); + } + if (source[cursor] === '"') { + return parseStringLiteral(); + } + throw new SyntaxError("Invalid expression"); + } + function parseNumberLiteral() { + let [, value, fraction = ""] = match(RE_NUMBER_LITERAL); + let precision = fraction.length; + return { + type: "num", + value: parseFloat(value), + precision + }; + } + function parseStringLiteral() { + consumeChar('"', SyntaxError); + let value = ""; + while (true) { + value += match1(RE_STRING_RUN); + if (source[cursor] === "\\") { + value += parseEscapeSequence(); + continue; + } + if (consumeChar('"')) { + return { + type: "str", + value + }; + } + throw new SyntaxError("Unclosed string literal"); + } + } + function parseEscapeSequence() { + if (test(RE_STRING_ESCAPE)) { + return match1(RE_STRING_ESCAPE); + } + if (test(RE_UNICODE_ESCAPE)) { + let [, codepoint4, codepoint6] = match(RE_UNICODE_ESCAPE); + let codepoint = parseInt(codepoint4 || codepoint6, 16); + return codepoint <= 0xd7ff || 0xe000 <= codepoint ? String.fromCodePoint(codepoint) : "�"; + } + throw new SyntaxError("Unknown escape sequence"); + } + function parseIndent() { + let start = cursor; + consumeToken(TOKEN_BLANK); + switch (source[cursor]) { + case ".": + case "[": + case "*": + case "}": + case undefined: + return false; + case "{": + return makeIndent(source.slice(start, cursor)); + } + if (source[cursor - 1] === " ") { + return makeIndent(source.slice(start, cursor)); + } + return false; + } + function trim(text, re) { + return text.replace(re, ""); + } + function makeIndent(blank) { + let value = blank.replace(RE_BLANK_LINES, "\n"); + let length = RE_INDENT.exec(blank)[1].length; + return new Indent(value, length); + } + } +} +class Indent { + constructor(value, length) { + this.value = value; + this.length = length; + } +} +;// CONCATENATED MODULE: ./node_modules/@fluent/bundle/esm/index.js + + + + +/***/ }), + +/***/ 8275: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + DOMLocalization: () => (/* reexport */ DOMLocalization) +}); + +// UNUSED EXPORTS: Localization + +;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/overlay.js +const reOverlay = /<|&#?\w+;/; +const TEXT_LEVEL_ELEMENTS = { + "http://www.w3.org/1999/xhtml": ["em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "data", "time", "code", "var", "samp", "kbd", "sub", "sup", "i", "b", "u", "mark", "bdi", "bdo", "span", "br", "wbr"] +}; +const LOCALIZABLE_ATTRIBUTES = { + "http://www.w3.org/1999/xhtml": { + global: ["title", "aria-label", "aria-valuetext"], + a: ["download"], + area: ["download", "alt"], + input: ["alt", "placeholder"], + menuitem: ["label"], + menu: ["label"], + optgroup: ["label"], + option: ["label"], + track: ["label"], + img: ["alt"], + textarea: ["placeholder"], + th: ["abbr"] + }, + "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul": { + global: ["accesskey", "aria-label", "aria-valuetext", "label", "title", "tooltiptext"], + description: ["value"], + key: ["key", "keycode"], + label: ["value"], + textbox: ["placeholder", "value"] + } +}; +function translateElement(element, translation) { + const { + value + } = translation; + if (typeof value === "string") { + if (element.localName === "title" && element.namespaceURI === "http://www.w3.org/1999/xhtml") { + element.textContent = value; + } else if (!reOverlay.test(value)) { + element.textContent = value; + } else { + const templateElement = element.ownerDocument.createElementNS("http://www.w3.org/1999/xhtml", "template"); + templateElement.innerHTML = value; + overlayChildNodes(templateElement.content, element); + } + } + overlayAttributes(translation, element); +} +function overlayChildNodes(fromFragment, toElement) { + for (const childNode of fromFragment.childNodes) { + if (childNode.nodeType === childNode.TEXT_NODE) { + continue; + } + if (childNode.hasAttribute("data-l10n-name")) { + const sanitized = getNodeForNamedElement(toElement, childNode); + fromFragment.replaceChild(sanitized, childNode); + continue; + } + if (isElementAllowed(childNode)) { + const sanitized = createSanitizedElement(childNode); + fromFragment.replaceChild(sanitized, childNode); + continue; + } + console.warn(`An element of forbidden type "${childNode.localName}" was found in ` + "the translation. Only safe text-level elements and elements with " + "data-l10n-name are allowed."); + fromFragment.replaceChild(createTextNodeFromTextContent(childNode), childNode); + } + toElement.textContent = ""; + toElement.appendChild(fromFragment); +} +function hasAttribute(attributes, name) { + if (!attributes) { + return false; + } + for (let attr of attributes) { + if (attr.name === name) { + return true; + } + } + return false; +} +function overlayAttributes(fromElement, toElement) { + const explicitlyAllowed = toElement.hasAttribute("data-l10n-attrs") ? toElement.getAttribute("data-l10n-attrs").split(",").map(i => i.trim()) : null; + for (const attr of Array.from(toElement.attributes)) { + if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && !hasAttribute(fromElement.attributes, attr.name)) { + toElement.removeAttribute(attr.name); + } + } + if (!fromElement.attributes) { + return; + } + for (const attr of Array.from(fromElement.attributes)) { + if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) && toElement.getAttribute(attr.name) !== attr.value) { + toElement.setAttribute(attr.name, attr.value); + } + } +} +function getNodeForNamedElement(sourceElement, translatedChild) { + const childName = translatedChild.getAttribute("data-l10n-name"); + const sourceChild = sourceElement.querySelector(`[data-l10n-name="${childName}"]`); + if (!sourceChild) { + console.warn(`An element named "${childName}" wasn't found in the source.`); + return createTextNodeFromTextContent(translatedChild); + } + if (sourceChild.localName !== translatedChild.localName) { + console.warn(`An element named "${childName}" was found in the translation ` + `but its type ${translatedChild.localName} didn't match the ` + `element found in the source (${sourceChild.localName}).`); + return createTextNodeFromTextContent(translatedChild); + } + sourceElement.removeChild(sourceChild); + const clone = sourceChild.cloneNode(false); + return shallowPopulateUsing(translatedChild, clone); +} +function createSanitizedElement(element) { + const clone = element.ownerDocument.createElement(element.localName); + return shallowPopulateUsing(element, clone); +} +function createTextNodeFromTextContent(element) { + return element.ownerDocument.createTextNode(element.textContent); +} +function isElementAllowed(element) { + const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI]; + return allowed && allowed.includes(element.localName); +} +function isAttrNameLocalizable(name, element, explicitlyAllowed = null) { + if (explicitlyAllowed && explicitlyAllowed.includes(name)) { + return true; + } + const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI]; + if (!allowed) { + return false; + } + const attrName = name.toLowerCase(); + const elemName = element.localName; + if (allowed.global.includes(attrName)) { + return true; + } + if (!allowed[elemName]) { + return false; + } + if (allowed[elemName].includes(attrName)) { + return true; + } + if (element.namespaceURI === "http://www.w3.org/1999/xhtml" && elemName === "input" && attrName === "value") { + const type = element.type.toLowerCase(); + if (type === "submit" || type === "button" || type === "reset") { + return true; + } + } + return false; +} +function shallowPopulateUsing(fromElement, toElement) { + toElement.textContent = fromElement.textContent; + overlayAttributes(fromElement, toElement); + return toElement; +} +;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_iterable.mjs +class CachedIterable extends Array { + static from(iterable) { + if (iterable instanceof this) { + return iterable; + } + return new this(iterable); + } +} +;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_sync_iterable.mjs + +class CachedSyncIterable extends CachedIterable { + constructor(iterable) { + super(); + if (Symbol.iterator in Object(iterable)) { + this.iterator = iterable[Symbol.iterator](); + } else { + throw new TypeError("Argument must implement the iteration protocol."); + } + } + [Symbol.iterator]() { + const cached = this; + let cur = 0; + return { + next() { + if (cached.length <= cur) { + cached.push(cached.iterator.next()); + } + return cached[cur++]; + } + }; + } + touchNext(count = 1) { + let idx = 0; + while (idx++ < count) { + const last = this[this.length - 1]; + if (last && last.done) { + break; + } + this.push(this.iterator.next()); + } + return this[this.length - 1]; + } +} +;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_async_iterable.mjs + +class CachedAsyncIterable extends CachedIterable { + constructor(iterable) { + super(); + if (Symbol.asyncIterator in Object(iterable)) { + this.iterator = iterable[Symbol.asyncIterator](); + } else if (Symbol.iterator in Object(iterable)) { + this.iterator = iterable[Symbol.iterator](); + } else { + throw new TypeError("Argument must implement the iteration protocol."); + } + } + [Symbol.asyncIterator]() { + const cached = this; + let cur = 0; + return { + async next() { + if (cached.length <= cur) { + cached.push(cached.iterator.next()); + } + return cached[cur++]; + } + }; + } + async touchNext(count = 1) { + let idx = 0; + while (idx++ < count) { + const last = this[this.length - 1]; + if (last && (await last).done) { + break; + } + this.push(this.iterator.next()); + } + return this[this.length - 1]; + } +} +;// CONCATENATED MODULE: ./node_modules/cached-iterable/src/index.mjs + + +;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/localization.js + +class Localization { + constructor(resourceIds = [], generateBundles) { + this.resourceIds = resourceIds; + this.generateBundles = generateBundles; + this.onChange(true); + } + addResourceIds(resourceIds, eager = false) { + this.resourceIds.push(...resourceIds); + this.onChange(eager); + return this.resourceIds.length; + } + removeResourceIds(resourceIds) { + this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r)); + this.onChange(); + return this.resourceIds.length; + } + async formatWithFallback(keys, method) { + const translations = []; + let hasAtLeastOneBundle = false; + for await (const bundle of this.bundles) { + hasAtLeastOneBundle = true; + const missingIds = keysFromBundle(method, bundle, keys, translations); + if (missingIds.size === 0) { + break; + } + if (typeof console !== "undefined") { + const locale = bundle.locales[0]; + const ids = Array.from(missingIds).join(", "); + console.warn(`[fluent] Missing translations in ${locale}: ${ids}`); + } + } + if (!hasAtLeastOneBundle && typeof console !== "undefined") { + console.warn(`[fluent] Request for keys failed because no resource bundles got generated. + keys: ${JSON.stringify(keys)}. + resourceIds: ${JSON.stringify(this.resourceIds)}.`); + } + return translations; + } + formatMessages(keys) { + return this.formatWithFallback(keys, messageFromBundle); + } + formatValues(keys) { + return this.formatWithFallback(keys, valueFromBundle); + } + async formatValue(id, args) { + const [val] = await this.formatValues([{ + id, + args + }]); + return val; + } + handleEvent() { + this.onChange(); + } + onChange(eager = false) { + this.bundles = CachedAsyncIterable.from(this.generateBundles(this.resourceIds)); + if (eager) { + this.bundles.touchNext(2); + } + } +} +function valueFromBundle(bundle, errors, message, args) { + if (message.value) { + return bundle.formatPattern(message.value, args, errors); + } + return null; +} +function messageFromBundle(bundle, errors, message, args) { + const formatted = { + value: null, + attributes: null + }; + if (message.value) { + formatted.value = bundle.formatPattern(message.value, args, errors); + } + let attrNames = Object.keys(message.attributes); + if (attrNames.length > 0) { + formatted.attributes = new Array(attrNames.length); + for (let [i, name] of attrNames.entries()) { + let value = bundle.formatPattern(message.attributes[name], args, errors); + formatted.attributes[i] = { + name, + value + }; + } + } + return formatted; +} +function keysFromBundle(method, bundle, keys, translations) { + const messageErrors = []; + const missingIds = new Set(); + keys.forEach(({ + id, + args + }, i) => { + if (translations[i] !== undefined) { + return; + } + let message = bundle.getMessage(id); + if (message) { + messageErrors.length = 0; + translations[i] = method(bundle, messageErrors, message, args); + if (messageErrors.length > 0 && typeof console !== "undefined") { + const locale = bundle.locales[0]; + const errors = messageErrors.join(", "); + console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`); + } + } else { + missingIds.add(id); + } + }); + return missingIds; +} +;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/dom_localization.js + + +const L10NID_ATTR_NAME = "data-l10n-id"; +const L10NARGS_ATTR_NAME = "data-l10n-args"; +const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`; +class DOMLocalization extends Localization { + constructor(resourceIds, generateBundles) { + super(resourceIds, generateBundles); + this.roots = new Set(); + this.pendingrAF = null; + this.pendingElements = new Set(); + this.windowElement = null; + this.mutationObserver = null; + this.observerConfig = { + attributes: true, + characterData: false, + childList: true, + subtree: true, + attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME] + }; + } + onChange(eager = false) { + super.onChange(eager); + if (this.roots) { + this.translateRoots(); + } + } + setAttributes(element, id, args) { + element.setAttribute(L10NID_ATTR_NAME, id); + if (args) { + element.setAttribute(L10NARGS_ATTR_NAME, JSON.stringify(args)); + } else { + element.removeAttribute(L10NARGS_ATTR_NAME); + } + return element; + } + getAttributes(element) { + return { + id: element.getAttribute(L10NID_ATTR_NAME), + args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null) + }; + } + connectRoot(newRoot) { + for (const root of this.roots) { + if (root === newRoot || root.contains(newRoot) || newRoot.contains(root)) { + throw new Error("Cannot add a root that overlaps with existing root."); + } + } + if (this.windowElement) { + if (this.windowElement !== newRoot.ownerDocument.defaultView) { + throw new Error(`Cannot connect a root: + DOMLocalization already has a root from a different window.`); + } + } else { + this.windowElement = newRoot.ownerDocument.defaultView; + this.mutationObserver = new this.windowElement.MutationObserver(mutations => this.translateMutations(mutations)); + } + this.roots.add(newRoot); + this.mutationObserver.observe(newRoot, this.observerConfig); + } + disconnectRoot(root) { + this.roots.delete(root); + this.pauseObserving(); + if (this.roots.size === 0) { + this.mutationObserver = null; + this.windowElement = null; + this.pendingrAF = null; + this.pendingElements.clear(); + return true; + } + this.resumeObserving(); + return false; + } + translateRoots() { + const roots = Array.from(this.roots); + return Promise.all(roots.map(root => this.translateFragment(root))); + } + pauseObserving() { + if (!this.mutationObserver) { + return; + } + this.translateMutations(this.mutationObserver.takeRecords()); + this.mutationObserver.disconnect(); + } + resumeObserving() { + if (!this.mutationObserver) { + return; + } + for (const root of this.roots) { + this.mutationObserver.observe(root, this.observerConfig); + } + } + translateMutations(mutations) { + for (const mutation of mutations) { + switch (mutation.type) { + case "attributes": + if (mutation.target.hasAttribute("data-l10n-id")) { + this.pendingElements.add(mutation.target); + } + break; + case "childList": + for (const addedNode of mutation.addedNodes) { + if (addedNode.nodeType === addedNode.ELEMENT_NODE) { + if (addedNode.childElementCount) { + for (const element of this.getTranslatables(addedNode)) { + this.pendingElements.add(element); + } + } else if (addedNode.hasAttribute(L10NID_ATTR_NAME)) { + this.pendingElements.add(addedNode); + } + } + } + break; + } + } + if (this.pendingElements.size > 0) { + if (this.pendingrAF === null) { + this.pendingrAF = this.windowElement.requestAnimationFrame(() => { + this.translateElements(Array.from(this.pendingElements)); + this.pendingElements.clear(); + this.pendingrAF = null; + }); + } + } + } + translateFragment(frag) { + return this.translateElements(this.getTranslatables(frag)); + } + async translateElements(elements) { + if (!elements.length) { + return undefined; + } + const keys = elements.map(this.getKeysForElement); + const translations = await this.formatMessages(keys); + return this.applyTranslations(elements, translations); + } + applyTranslations(elements, translations) { + this.pauseObserving(); + for (let i = 0; i < elements.length; i++) { + if (translations[i] !== undefined) { + translateElement(elements[i], translations[i]); + } + } + this.resumeObserving(); + } + getTranslatables(element) { + const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY)); + if (typeof element.hasAttribute === "function" && element.hasAttribute(L10NID_ATTR_NAME)) { + nodes.push(element); + } + return nodes; + } + getKeysForElement(element) { + return { + id: element.getAttribute(L10NID_ATTR_NAME), + args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null) + }; + } +} +;// CONCATENATED MODULE: ./node_modules/@fluent/dom/esm/index.js + + + +/***/ }), + +/***/ 631: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AltTextManager: () => (/* binding */ AltTextManager) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +class AltTextManager { + #boundUpdateUIState = this.#updateUIState.bind(this); + #boundSetPosition = this.#setPosition.bind(this); + #boundOnClick = this.#onClick.bind(this); + #currentEditor = null; + #cancelButton; + #dialog; + #eventBus; + #hasUsedPointer = false; + #optionDescription; + #optionDecorative; + #overlayManager; + #saveButton; + #textarea; + #uiManager; + #previousAltText = null; + #svgElement = null; + #rectElement = null; + #container; + #telemetryData = null; + constructor({ + dialog, + optionDescription, + optionDecorative, + textarea, + cancelButton, + saveButton + }, container, overlayManager, eventBus) { + this.#dialog = dialog; + this.#optionDescription = optionDescription; + this.#optionDecorative = optionDecorative; + this.#textarea = textarea; + this.#cancelButton = cancelButton; + this.#saveButton = saveButton; + this.#overlayManager = overlayManager; + this.#eventBus = eventBus; + this.#container = container; + dialog.addEventListener("close", this.#close.bind(this)); + dialog.addEventListener("contextmenu", event => { + if (event.target !== this.#textarea) { + event.preventDefault(); + } + }); + cancelButton.addEventListener("click", this.#finish.bind(this)); + saveButton.addEventListener("click", this.#save.bind(this)); + optionDescription.addEventListener("change", this.#boundUpdateUIState); + optionDecorative.addEventListener("change", this.#boundUpdateUIState); + this.#overlayManager.register(dialog); + } + get _elements() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_elements", [this.#optionDescription, this.#optionDecorative, this.#textarea, this.#saveButton, this.#cancelButton]); + } + #createSVGElement() { + if (this.#svgElement) { + return; + } + const svgFactory = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.DOMSVGFactory(); + const svg = this.#svgElement = svgFactory.createElement("svg"); + svg.setAttribute("width", "0"); + svg.setAttribute("height", "0"); + const defs = svgFactory.createElement("defs"); + svg.append(defs); + const mask = svgFactory.createElement("mask"); + defs.append(mask); + mask.setAttribute("id", "alttext-manager-mask"); + mask.setAttribute("maskContentUnits", "objectBoundingBox"); + let rect = svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("fill", "white"); + rect.setAttribute("width", "1"); + rect.setAttribute("height", "1"); + rect.setAttribute("x", "0"); + rect.setAttribute("y", "0"); + rect = this.#rectElement = svgFactory.createElement("rect"); + mask.append(rect); + rect.setAttribute("fill", "black"); + this.#dialog.append(svg); + } + async editAltText(uiManager, editor) { + if (this.#currentEditor || !editor) { + return; + } + this.#createSVGElement(); + this.#hasUsedPointer = false; + for (const element of this._elements) { + element.addEventListener("click", this.#boundOnClick); + } + const { + altText, + decorative + } = editor.altTextData; + if (decorative === true) { + this.#optionDecorative.checked = true; + this.#optionDescription.checked = false; + } else { + this.#optionDecorative.checked = false; + this.#optionDescription.checked = true; + } + this.#previousAltText = this.#textarea.value = altText?.trim() || ""; + this.#updateUIState(); + this.#currentEditor = editor; + this.#uiManager = uiManager; + this.#uiManager.removeEditListeners(); + this.#eventBus._on("resize", this.#boundSetPosition); + try { + await this.#overlayManager.open(this.#dialog); + this.#setPosition(); + } catch (ex) { + this.#close(); + throw ex; + } + } + #setPosition() { + if (!this.#currentEditor) { + return; + } + const dialog = this.#dialog; + const { + style + } = dialog; + const { + x: containerX, + y: containerY, + width: containerW, + height: containerH + } = this.#container.getBoundingClientRect(); + const { + innerWidth: windowW, + innerHeight: windowH + } = window; + const { + width: dialogW, + height: dialogH + } = dialog.getBoundingClientRect(); + const { + x, + y, + width, + height + } = this.#currentEditor.getClientDimensions(); + const MARGIN = 10; + const isLTR = this.#uiManager.direction === "ltr"; + const xs = Math.max(x, containerX); + const xe = Math.min(x + width, containerX + containerW); + const ys = Math.max(y, containerY); + const ye = Math.min(y + height, containerY + containerH); + this.#rectElement.setAttribute("width", `${(xe - xs) / windowW}`); + this.#rectElement.setAttribute("height", `${(ye - ys) / windowH}`); + this.#rectElement.setAttribute("x", `${xs / windowW}`); + this.#rectElement.setAttribute("y", `${ys / windowH}`); + let left = null; + let top = Math.max(y, 0); + top += Math.min(windowH - (top + dialogH), 0); + if (isLTR) { + if (x + width + MARGIN + dialogW < windowW) { + left = x + width + MARGIN; + } else if (x > dialogW + MARGIN) { + left = x - dialogW - MARGIN; + } + } else if (x > dialogW + MARGIN) { + left = x - dialogW - MARGIN; + } else if (x + width + MARGIN + dialogW < windowW) { + left = x + width + MARGIN; + } + if (left === null) { + top = null; + left = Math.max(x, 0); + left += Math.min(windowW - (left + dialogW), 0); + if (y > dialogH + MARGIN) { + top = y - dialogH - MARGIN; + } else if (y + height + MARGIN + dialogH < windowH) { + top = y + height + MARGIN; + } + } + if (top !== null) { + dialog.classList.add("positioned"); + if (isLTR) { + style.left = `${left}px`; + } else { + style.right = `${windowW - left - dialogW}px`; + } + style.top = `${top}px`; + } else { + dialog.classList.remove("positioned"); + style.left = ""; + style.top = ""; + } + } + #finish() { + if (this.#overlayManager.active === this.#dialog) { + this.#overlayManager.close(this.#dialog); + } + } + #close() { + this.#eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "editing", + subtype: this.#currentEditor.editorType, + data: this.#telemetryData || { + action: "alt_text_cancel", + alt_text_keyboard: !this.#hasUsedPointer + } + } + }); + this.#telemetryData = null; + this.#removeOnClickListeners(); + this.#uiManager?.addEditListeners(); + this.#eventBus._off("resize", this.#boundSetPosition); + this.#currentEditor.altTextFinish(); + this.#currentEditor = null; + this.#uiManager = null; + } + #updateUIState() { + this.#textarea.disabled = this.#optionDecorative.checked; + } + #save() { + const altText = this.#textarea.value.trim(); + const decorative = this.#optionDecorative.checked; + this.#currentEditor.altTextData = { + altText, + decorative + }; + this.#telemetryData = { + action: "alt_text_save", + alt_text_description: !!altText, + alt_text_edit: !!this.#previousAltText && this.#previousAltText !== altText, + alt_text_decorative: decorative, + alt_text_keyboard: !this.#hasUsedPointer + }; + this.#finish(); + } + #onClick(evt) { + if (evt.detail === 0) { + return; + } + this.#hasUsedPointer = true; + this.#removeOnClickListeners(); + } + #removeOnClickListeners() { + for (const element of this._elements) { + element.removeEventListener("click", this.#boundOnClick); + } + } + destroy() { + this.#uiManager = null; + this.#finish(); + this.#svgElement?.remove(); + this.#svgElement = this.#rectElement = null; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 2640: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AnnotationEditorLayerBuilder: () => (/* binding */ AnnotationEditorLayerBuilder) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7910); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__]); +([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + +class AnnotationEditorLayerBuilder { + #annotationLayer = null; + #drawLayer = null; + #textLayer = null; + #uiManager; + constructor(options) { + this.pageDiv = options.pageDiv; + this.pdfPage = options.pdfPage; + this.accessibilityManager = options.accessibilityManager; + this.l10n = options.l10n || web_l10n_utils__WEBPACK_IMPORTED_MODULE_1__.NullL10n; + this.annotationEditorLayer = null; + this.div = null; + this._cancelled = false; + this.#uiManager = options.uiManager; + this.#annotationLayer = options.annotationLayer || null; + this.#textLayer = options.textLayer || null; + this.#drawLayer = options.drawLayer || null; + } + async render(viewport, intent = "display") { + if (intent !== "display") { + return; + } + if (this._cancelled) { + return; + } + const clonedViewport = viewport.clone({ + dontFlip: true + }); + if (this.div) { + this.annotationEditorLayer.update({ + viewport: clonedViewport + }); + this.show(); + return; + } + const div = this.div = document.createElement("div"); + div.className = "annotationEditorLayer"; + div.tabIndex = 0; + div.hidden = true; + div.dir = this.#uiManager.direction; + this.pageDiv.append(div); + this.annotationEditorLayer = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorLayer({ + uiManager: this.#uiManager, + div, + accessibilityManager: this.accessibilityManager, + pageIndex: this.pdfPage.pageNumber - 1, + l10n: this.l10n, + viewport: clonedViewport, + annotationLayer: this.#annotationLayer, + textLayer: this.#textLayer, + drawLayer: this.#drawLayer + }); + const parameters = { + viewport: clonedViewport, + div, + annotations: null, + intent + }; + this.annotationEditorLayer.render(parameters); + this.show(); + } + cancel() { + this._cancelled = true; + if (!this.div) { + return; + } + this.pageDiv = null; + this.annotationEditorLayer.destroy(); + this.div.remove(); + } + hide() { + if (!this.div) { + return; + } + this.div.hidden = true; + } + show() { + if (!this.div || this.annotationEditorLayer.isEmpty) { + return; + } + this.div.hidden = false; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1296: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AnnotationEditorParams: () => (/* binding */ AnnotationEditorParams) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +class AnnotationEditorParams { + constructor(options, eventBus) { + this.eventBus = eventBus; + this.#bindListeners(options); + } + #bindListeners({ + editorFreeTextFontSize, + editorFreeTextColor, + editorInkColor, + editorInkThickness, + editorInkOpacity, + editorStampAddImage + }) { + const dispatchEvent = (typeStr, value) => { + this.eventBus.dispatch("switchannotationeditorparams", { + source: this, + type: pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType[typeStr], + value + }); + }; + editorFreeTextFontSize.addEventListener("input", function () { + dispatchEvent("FREETEXT_SIZE", this.valueAsNumber); + }); + editorFreeTextColor.addEventListener("input", function () { + dispatchEvent("FREETEXT_COLOR", this.value); + }); + editorInkColor.addEventListener("input", function () { + dispatchEvent("INK_COLOR", this.value); + }); + editorInkThickness.addEventListener("input", function () { + dispatchEvent("INK_THICKNESS", this.valueAsNumber); + }); + editorInkOpacity.addEventListener("input", function () { + dispatchEvent("INK_OPACITY", this.valueAsNumber); + }); + editorStampAddImage.addEventListener("click", () => { + dispatchEvent("CREATE"); + }); + this.eventBus._on("annotationeditorparamschanged", evt => { + for (const [type, value] of evt.details) { + switch (type) { + case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.FREETEXT_SIZE: + editorFreeTextFontSize.value = value; + break; + case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.FREETEXT_COLOR: + editorFreeTextColor.value = value; + break; + case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.INK_COLOR: + editorInkColor.value = value; + break; + case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.INK_THICKNESS: + editorInkThickness.value = value; + break; + case pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorParamsType.INK_OPACITY: + editorInkOpacity.value = value; + break; + } + } + }); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 6735: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AnnotationLayerBuilder: () => (/* binding */ AnnotationLayerBuilder) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +class AnnotationLayerBuilder { + #onPresentationModeChanged = null; + constructor({ + pageDiv, + pdfPage, + linkService, + downloadManager, + annotationStorage = null, + imageResourcesPath = "", + renderForms = true, + enableScripting = false, + hasJSActionsPromise = null, + fieldObjectsPromise = null, + annotationCanvasMap = null, + accessibilityManager = null + }) { + this.pageDiv = pageDiv; + this.pdfPage = pdfPage; + this.linkService = linkService; + this.downloadManager = downloadManager; + this.imageResourcesPath = imageResourcesPath; + this.renderForms = renderForms; + this.annotationStorage = annotationStorage; + this.enableScripting = enableScripting; + this._hasJSActionsPromise = hasJSActionsPromise || Promise.resolve(false); + this._fieldObjectsPromise = fieldObjectsPromise || Promise.resolve(null); + this._annotationCanvasMap = annotationCanvasMap; + this._accessibilityManager = accessibilityManager; + this.annotationLayer = null; + this.div = null; + this._cancelled = false; + this._eventBus = linkService.eventBus; + } + async render(viewport, intent = "display") { + if (this.div) { + if (this._cancelled || !this.annotationLayer) { + return; + } + this.annotationLayer.update({ + viewport: viewport.clone({ + dontFlip: true + }) + }); + return; + } + const [annotations, hasJSActions, fieldObjects] = await Promise.all([this.pdfPage.getAnnotations({ + intent + }), this._hasJSActionsPromise, this._fieldObjectsPromise]); + if (this._cancelled) { + return; + } + const div = this.div = document.createElement("div"); + div.className = "annotationLayer"; + this.pageDiv.append(div); + if (annotations.length === 0) { + this.hide(); + return; + } + this.annotationLayer = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationLayer({ + div, + accessibilityManager: this._accessibilityManager, + annotationCanvasMap: this._annotationCanvasMap, + page: this.pdfPage, + viewport: viewport.clone({ + dontFlip: true + }) + }); + await this.annotationLayer.render({ + annotations, + imageResourcesPath: this.imageResourcesPath, + renderForms: this.renderForms, + linkService: this.linkService, + downloadManager: this.downloadManager, + annotationStorage: this.annotationStorage, + enableScripting: this.enableScripting, + hasJSActions, + fieldObjects + }); + if (this.linkService.isInPresentationMode) { + this.#updatePresentationModeState(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN); + } + if (!this.#onPresentationModeChanged) { + this.#onPresentationModeChanged = evt => { + this.#updatePresentationModeState(evt.state); + }; + this._eventBus?._on("presentationmodechanged", this.#onPresentationModeChanged); + } + } + cancel() { + this._cancelled = true; + if (this.#onPresentationModeChanged) { + this._eventBus?._off("presentationmodechanged", this.#onPresentationModeChanged); + this.#onPresentationModeChanged = null; + } + } + hide() { + if (!this.div) { + return; + } + this.div.hidden = true; + } + #updatePresentationModeState(state) { + if (!this.div) { + return; + } + let disableFormElements = false; + switch (state) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN: + disableFormElements = true; + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL: + break; + default: + return; + } + for (const section of this.div.childNodes) { + if (section.hasAttribute("data-internal-link")) { + continue; + } + section.inert = disableFormElements; + } + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 39: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ DefaultExternalServices: () => (/* binding */ DefaultExternalServices), +/* harmony export */ PDFPrintServiceFactory: () => (/* binding */ PDFPrintServiceFactory), +/* harmony export */ PDFViewerApplication: () => (/* binding */ PDFViewerApplication) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869); +/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8961); +/* harmony import */ var _event_utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6554); +/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3234); +/* harmony import */ var web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(631); +/* harmony import */ var web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1296); +/* harmony import */ var _overlay_manager_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(1996); +/* harmony import */ var _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6329); +/* harmony import */ var web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(716); +/* harmony import */ var web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(3611); +/* harmony import */ var web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(6312); +/* harmony import */ var web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(1795); +/* harmony import */ var _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(3557); +/* harmony import */ var _pdf_history_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(6418); +/* harmony import */ var web_pdf_layer_viewer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(3706); +/* harmony import */ var web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(1141); +/* harmony import */ var web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(323); +/* harmony import */ var _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(5119); +/* harmony import */ var _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(2599); +/* harmony import */ var web_pdf_sidebar__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(4487); +/* harmony import */ var web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(3510); +/* harmony import */ var _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(9290); +/* harmony import */ var web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(1544); +/* harmony import */ var web_toolbar__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(276); +/* harmony import */ var _view_history_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(1096); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__, web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__, web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__, _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__, web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__, web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__, web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__, web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__, _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__, web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__, web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__, _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__, web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__, _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__, web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__, web_toolbar__WEBPACK_IMPORTED_MODULE_23__]); +([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__, web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__, web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__, _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__, web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__, web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__, web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__, web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__, _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__, web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__, web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__, _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__, web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__, _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__, web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__, web_toolbar__WEBPACK_IMPORTED_MODULE_23__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + + + + + + + + + + + + + + + + + + + + + + + + +const FORCE_PAGES_LOADED_TIMEOUT = 10000; +const WHEEL_ZOOM_DISABLED_TIMEOUT = 1000; +const ViewOnLoad = { + UNKNOWN: -1, + PREVIOUS: 0, + INITIAL: 1 +}; +class DefaultExternalServices { + constructor() { + throw new Error("Cannot initialize DefaultExternalServices."); + } + static updateFindControlState(data) {} + static updateFindMatchesCount(data) {} + static initPassiveLoading(callbacks) {} + static reportTelemetry(data) {} + static createDownloadManager() { + throw new Error("Not implemented: createDownloadManager"); + } + static createPreferences() { + throw new Error("Not implemented: createPreferences"); + } + static async createL10n() { + throw new Error("Not implemented: createL10n"); + } + static createScripting() { + throw new Error("Not implemented: createScripting"); + } + static updateEditorStates(data) { + throw new Error("Not implemented: updateEditorStates"); + } + static getNimbusExperimentData() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "getNimbusExperimentData", Promise.resolve(null)); + } +} +const PDFViewerApplication = { + initialBookmark: document.location.hash.substring(1), + _initializedCapability: new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(), + appConfig: null, + pdfDocument: null, + pdfLoadingTask: null, + printService: null, + pdfViewer: null, + pdfThumbnailViewer: null, + pdfRenderingQueue: null, + pdfPresentationMode: null, + pdfDocumentProperties: null, + pdfLinkService: null, + pdfHistory: null, + pdfSidebar: null, + pdfOutlineViewer: null, + pdfAttachmentViewer: null, + pdfLayerViewer: null, + pdfCursorTools: null, + pdfScriptingManager: null, + store: null, + downloadManager: null, + overlayManager: null, + preferences: null, + toolbar: null, + secondaryToolbar: null, + eventBus: null, + l10n: null, + annotationEditorParams: null, + isInitialViewSet: false, + downloadComplete: false, + isViewerEmbedded: window.parent !== window, + url: "", + baseUrl: "", + _downloadUrl: "", + externalServices: DefaultExternalServices, + _boundEvents: Object.create(null), + documentInfo: null, + metadata: null, + _contentDispositionFilename: null, + _contentLength: null, + _saveInProgress: false, + _wheelUnusedTicks: 0, + _wheelUnusedFactor: 1, + _touchUnusedTicks: 0, + _touchUnusedFactor: 1, + _PDFBug: null, + _hasAnnotationEditors: false, + _title: document.title, + _printAnnotationStoragePromise: null, + _touchInfo: null, + _isCtrlKeyDown: false, + _nimbusDataPromise: null, + async initialize(appConfig) { + let l10nPromise; + this.appConfig = appConfig; + try { + await this.preferences.initializedPromise; + } catch (ex) { + console.error(`initialize: "${ex.message}".`); + } + if (_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pdfBugEnabled")) { + await this._parseHashParams(); + } + let mode; + switch (_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("viewerCssTheme")) { + case 1: + mode = "is-light"; + break; + case 2: + mode = "is-dark"; + break; + } + if (mode) { + document.documentElement.classList.add(mode); + } + l10nPromise = this.externalServices.createL10n(); + this.l10n = await l10nPromise; + document.getElementsByTagName("html")[0].dir = this.l10n.getDirection(); + this.l10n.translate(appConfig.appContainer || document.documentElement); + if (this.isViewerEmbedded && _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("externalLinkTarget") === _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.LinkTarget.NONE) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("externalLinkTarget", _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.LinkTarget.TOP); + } + await this._initializeViewerComponents(); + this.bindEvents(); + this.bindWindowEvents(); + this._initializedCapability.resolve(); + }, + async _parseHashParams() { + const hash = document.location.hash.substring(1); + if (!hash) { + return; + } + const { + mainContainer, + viewerContainer + } = this.appConfig, + params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(hash); + if (params.get("disableworker") === "true") { + try { + await loadFakeWorker(); + } catch (ex) { + console.error(`_parseHashParams: "${ex.message}".`); + } + } + if (params.has("disablerange")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableRange", params.get("disablerange") === "true"); + } + if (params.has("disablestream")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableStream", params.get("disablestream") === "true"); + } + if (params.has("disableautofetch")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableAutoFetch", params.get("disableautofetch") === "true"); + } + if (params.has("disablefontface")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableFontFace", params.get("disablefontface") === "true"); + } + if (params.has("disablehistory")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableHistory", params.get("disablehistory") === "true"); + } + if (params.has("verbosity")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("verbosity", params.get("verbosity") | 0); + } + if (params.has("textlayer")) { + switch (params.get("textlayer")) { + case "off": + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("textLayerMode", _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.TextLayerMode.DISABLE); + break; + case "visible": + case "shadow": + case "hover": + viewerContainer.classList.add(`textLayer-${params.get("textlayer")}`); + try { + await loadPDFBug(this); + this._PDFBug.loadCSS(); + } catch (ex) { + console.error(`_parseHashParams: "${ex.message}".`); + } + break; + } + } + if (params.has("pdfbug")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("pdfBug", true); + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("fontExtraProperties", true); + const enabled = params.get("pdfbug").split(","); + try { + await loadPDFBug(this); + this._PDFBug.init(mainContainer, enabled); + } catch (ex) { + console.error(`_parseHashParams: "${ex.message}".`); + } + } + if (params.has("locale")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("locale", params.get("locale")); + } + }, + async _initializeViewerComponents() { + const { + appConfig, + externalServices, + l10n + } = this; + const eventBus = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("isInAutomation") ? new _event_utils_js__WEBPACK_IMPORTED_MODULE_3__.AutomationEventBus() : new _event_utils_js__WEBPACK_IMPORTED_MODULE_3__.EventBus(); + this.eventBus = eventBus; + this.overlayManager = new _overlay_manager_js__WEBPACK_IMPORTED_MODULE_24__.OverlayManager(); + const pdfRenderingQueue = new _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_17__.PDFRenderingQueue(); + pdfRenderingQueue.onIdle = this._cleanup.bind(this); + this.pdfRenderingQueue = pdfRenderingQueue; + const pdfLinkService = new _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.PDFLinkService({ + eventBus, + externalLinkTarget: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("externalLinkTarget"), + externalLinkRel: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("externalLinkRel"), + ignoreDestinationZoom: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("ignoreDestinationZoom") + }); + this.pdfLinkService = pdfLinkService; + const downloadManager = externalServices.createDownloadManager(); + this.downloadManager = downloadManager; + const findController = new _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_12__.PDFFindController({ + linkService: pdfLinkService, + eventBus, + updateMatchesCountOnProgress: true + }); + this.findController = findController; + const pdfScriptingManager = new _pdf_scripting_manager_js__WEBPACK_IMPORTED_MODULE_18__.PDFScriptingManager({ + eventBus, + externalServices, + docProperties: this._scriptingDocProperties.bind(this) + }); + this.pdfScriptingManager = pdfScriptingManager; + const container = appConfig.mainContainer, + viewer = appConfig.viewerContainer; + const annotationEditorMode = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("annotationEditorMode"); + const isOffscreenCanvasSupported = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("isOffscreenCanvasSupported") && pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.FeatureTest.isOffscreenCanvasSupported; + const pageColors = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("forcePageColors") || window.matchMedia("(forced-colors: active)").matches ? { + background: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pageColorsBackground"), + foreground: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pageColorsForeground") + } : null; + const altTextManager = appConfig.altTextDialog ? new web_alt_text_manager__WEBPACK_IMPORTED_MODULE_5__.AltTextManager(appConfig.altTextDialog, container, this.overlayManager, eventBus) : null; + const pdfViewer = new _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_21__.PDFViewer({ + container, + viewer, + eventBus, + renderingQueue: pdfRenderingQueue, + linkService: pdfLinkService, + downloadManager, + altTextManager, + findController, + scriptingManager: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enableScripting") && pdfScriptingManager, + l10n, + textLayerMode: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("textLayerMode"), + annotationMode: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("annotationMode"), + annotationEditorMode, + annotationEditorHighlightColors: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("highlightEditorColors"), + imageResourcesPath: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("imageResourcesPath"), + enablePrintAutoRotate: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enablePrintAutoRotate"), + isOffscreenCanvasSupported, + maxCanvasPixels: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("maxCanvasPixels"), + enablePermissions: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enablePermissions"), + pageColors + }); + this.pdfViewer = pdfViewer; + pdfRenderingQueue.setViewer(pdfViewer); + pdfLinkService.setViewer(pdfViewer); + pdfScriptingManager.setViewer(pdfViewer); + if (appConfig.sidebar?.thumbnailView) { + this.pdfThumbnailViewer = new web_pdf_thumbnail_viewer__WEBPACK_IMPORTED_MODULE_20__.PDFThumbnailViewer({ + container: appConfig.sidebar.thumbnailView, + eventBus, + renderingQueue: pdfRenderingQueue, + linkService: pdfLinkService, + pageColors + }); + pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer); + } + if (!this.isViewerEmbedded && !_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("disableHistory")) { + this.pdfHistory = new _pdf_history_js__WEBPACK_IMPORTED_MODULE_13__.PDFHistory({ + linkService: pdfLinkService, + eventBus + }); + pdfLinkService.setHistory(this.pdfHistory); + } + if (!this.supportsIntegratedFind && appConfig.findBar) { + this.findBar = new web_pdf_find_bar__WEBPACK_IMPORTED_MODULE_11__.PDFFindBar(appConfig.findBar, eventBus); + } + if (appConfig.annotationEditorParams) { + if (annotationEditorMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditorType.DISABLE) { + if (!isOffscreenCanvasSupported) { + appConfig.toolbar?.editorStampButton?.classList.add("hidden"); + } + const editorHighlightButton = appConfig.toolbar?.editorHighlightButton; + if (editorHighlightButton && _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("enableHighlightEditor")) { + editorHighlightButton.hidden = false; + } + this.annotationEditorParams = new web_annotation_editor_params__WEBPACK_IMPORTED_MODULE_6__.AnnotationEditorParams(appConfig.annotationEditorParams, eventBus); + } else { + for (const id of ["editorModeButtons", "editorModeSeparator"]) { + document.getElementById(id)?.classList.add("hidden"); + } + } + } + if (appConfig.documentProperties) { + this.pdfDocumentProperties = new web_pdf_document_properties__WEBPACK_IMPORTED_MODULE_10__.PDFDocumentProperties(appConfig.documentProperties, this.overlayManager, eventBus, l10n, () => this._docFilename); + } + if (appConfig.secondaryToolbar?.cursorHandToolButton) { + this.pdfCursorTools = new web_pdf_cursor_tools__WEBPACK_IMPORTED_MODULE_9__.PDFCursorTools({ + container, + eventBus, + cursorToolOnLoad: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("cursorToolOnLoad") + }); + } + if (appConfig.toolbar) { + this.toolbar = new web_toolbar__WEBPACK_IMPORTED_MODULE_23__.Toolbar(appConfig.toolbar, eventBus); + } + if (appConfig.secondaryToolbar) { + this.secondaryToolbar = new web_secondary_toolbar__WEBPACK_IMPORTED_MODULE_22__.SecondaryToolbar(appConfig.secondaryToolbar, eventBus); + } + if (this.supportsFullscreen && appConfig.secondaryToolbar?.presentationModeButton) { + this.pdfPresentationMode = new web_pdf_presentation_mode__WEBPACK_IMPORTED_MODULE_16__.PDFPresentationMode({ + container, + pdfViewer, + eventBus + }); + } + if (appConfig.passwordOverlay) { + this.passwordPrompt = new _password_prompt_js__WEBPACK_IMPORTED_MODULE_7__.PasswordPrompt(appConfig.passwordOverlay, this.overlayManager, this.isViewerEmbedded); + } + if (appConfig.sidebar?.outlineView) { + this.pdfOutlineViewer = new web_pdf_outline_viewer__WEBPACK_IMPORTED_MODULE_15__.PDFOutlineViewer({ + container: appConfig.sidebar.outlineView, + eventBus, + l10n, + linkService: pdfLinkService, + downloadManager + }); + } + if (appConfig.sidebar?.attachmentsView) { + this.pdfAttachmentViewer = new web_pdf_attachment_viewer__WEBPACK_IMPORTED_MODULE_8__.PDFAttachmentViewer({ + container: appConfig.sidebar.attachmentsView, + eventBus, + l10n, + downloadManager + }); + } + if (appConfig.sidebar?.layersView) { + this.pdfLayerViewer = new web_pdf_layer_viewer__WEBPACK_IMPORTED_MODULE_14__.PDFLayerViewer({ + container: appConfig.sidebar.layersView, + eventBus, + l10n + }); + } + if (appConfig.sidebar) { + this.pdfSidebar = new web_pdf_sidebar__WEBPACK_IMPORTED_MODULE_19__.PDFSidebar({ + elements: appConfig.sidebar, + eventBus, + l10n + }); + this.pdfSidebar.onToggled = this.forceRendering.bind(this); + this.pdfSidebar.onUpdateThumbnails = () => { + for (const pageView of pdfViewer.getCachedPageViews()) { + if (pageView.renderingState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) { + this.pdfThumbnailViewer.getThumbnail(pageView.id - 1)?.setImage(pageView); + } + } + this.pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber); + }; + } + }, + async run(config) { + this.preferences = this.externalServices.createPreferences(); + await this.initialize(config); + const { + appConfig, + eventBus + } = this; + let file; + const queryString = document.location.search.substring(1); + const params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(queryString); + file = params.get("file") ?? _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultUrl"); + validateFileURL(file); + const fileInput = appConfig.openFileInput; + fileInput.value = null; + fileInput.addEventListener("change", function (evt) { + const { + files + } = evt.target; + if (!files || files.length === 0) { + return; + } + eventBus.dispatch("fileinputchange", { + source: this, + fileInput: evt.target + }); + }); + appConfig.mainContainer.addEventListener("dragover", function (evt) { + evt.preventDefault(); + evt.dataTransfer.dropEffect = evt.dataTransfer.effectAllowed === "copy" ? "copy" : "move"; + }); + appConfig.mainContainer.addEventListener("drop", function (evt) { + evt.preventDefault(); + const { + files + } = evt.dataTransfer; + if (!files || files.length === 0) { + return; + } + eventBus.dispatch("fileinputchange", { + source: this, + fileInput: evt.dataTransfer + }); + }); + if (!_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsDocumentFonts")) { + _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.set("disableFontFace", true); + this.l10n.get("pdfjs-web-fonts-disabled").then(msg => { + console.warn(msg); + }); + } + if (!this.supportsPrinting) { + appConfig.toolbar?.print?.classList.add("hidden"); + appConfig.secondaryToolbar?.printButton.classList.add("hidden"); + } + if (!this.supportsFullscreen) { + appConfig.secondaryToolbar?.presentationModeButton.classList.add("hidden"); + } + if (this.supportsIntegratedFind) { + appConfig.toolbar?.viewFind?.classList.add("hidden"); + } + if (file) { + this.open({ + url: file + }); + } else { + this._hideViewBookmark(); + } + }, + get initialized() { + return this._initializedCapability.settled; + }, + get initializedPromise() { + return this._initializedCapability.promise; + }, + zoomIn(steps, scaleFactor) { + if (this.pdfViewer.isInPresentationMode) { + return; + } + this.pdfViewer.increaseScale({ + drawingDelay: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultZoomDelay"), + steps, + scaleFactor + }); + }, + zoomOut(steps, scaleFactor) { + if (this.pdfViewer.isInPresentationMode) { + return; + } + this.pdfViewer.decreaseScale({ + drawingDelay: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultZoomDelay"), + steps, + scaleFactor + }); + }, + zoomReset() { + if (this.pdfViewer.isInPresentationMode) { + return; + } + this.pdfViewer.currentScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCALE_VALUE; + }, + get pagesCount() { + return this.pdfDocument ? this.pdfDocument.numPages : 0; + }, + get page() { + return this.pdfViewer.currentPageNumber; + }, + set page(val) { + this.pdfViewer.currentPageNumber = val; + }, + get supportsPrinting() { + return PDFPrintServiceFactory.instance.supportsPrinting; + }, + get supportsFullscreen() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsFullscreen", document.fullscreenEnabled); + }, + get supportsPinchToZoom() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsPinchToZoom", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsPinchToZoom")); + }, + get supportsIntegratedFind() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsIntegratedFind", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsIntegratedFind")); + }, + get loadingBar() { + const barElement = document.getElementById("loadingBar"); + const bar = barElement ? new _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ProgressBar(barElement) : null; + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "loadingBar", bar); + }, + get supportsMouseWheelZoomCtrlKey() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsMouseWheelZoomCtrlKey", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsMouseWheelZoomCtrlKey")); + }, + get supportsMouseWheelZoomMetaKey() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "supportsMouseWheelZoomMetaKey", _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("supportsMouseWheelZoomMetaKey")); + }, + initPassiveLoading(file) { + throw new Error("Not implemented: initPassiveLoading"); + }, + setTitleUsingUrl(url = "", downloadUrl = null) { + this.url = url; + this.baseUrl = url.split("#", 1)[0]; + if (downloadUrl) { + this._downloadUrl = downloadUrl === url ? this.baseUrl : downloadUrl.split("#", 1)[0]; + } + if ((0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.isDataScheme)(url)) { + this._hideViewBookmark(); + } + let title = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getPdfFilenameFromUrl)(url, ""); + if (!title) { + try { + title = decodeURIComponent((0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getFilenameFromUrl)(url)) || url; + } catch { + title = url; + } + } + this.setTitle(title); + }, + setTitle(title = this._title) { + this._title = title; + if (this.isViewerEmbedded) { + return; + } + const editorIndicator = this._hasAnnotationEditors && !this.pdfRenderingQueue.printing; + document.title = `${editorIndicator ? "* " : ""}${title}`; + }, + get _docFilename() { + return this._contentDispositionFilename || (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getPdfFilenameFromUrl)(this.url); + }, + _hideViewBookmark() { + const { + secondaryToolbar + } = this.appConfig; + secondaryToolbar?.viewBookmarkButton.classList.add("hidden"); + if (secondaryToolbar?.presentationModeButton.classList.contains("hidden")) { + document.getElementById("viewBookmarkSeparator")?.classList.add("hidden"); + } + }, + async close() { + this._unblockDocumentLoadEvent(); + this._hideViewBookmark(); + if (!this.pdfLoadingTask) { + return; + } + if (this.pdfDocument?.annotationStorage.size > 0 && this._annotationStorageModified) { + try { + await this.save(); + } catch {} + } + const promises = []; + promises.push(this.pdfLoadingTask.destroy()); + this.pdfLoadingTask = null; + if (this.pdfDocument) { + this.pdfDocument = null; + this.pdfThumbnailViewer?.setDocument(null); + this.pdfViewer.setDocument(null); + this.pdfLinkService.setDocument(null); + this.pdfDocumentProperties?.setDocument(null); + } + this.pdfLinkService.externalLinkEnabled = true; + this.store = null; + this.isInitialViewSet = false; + this.downloadComplete = false; + this.url = ""; + this.baseUrl = ""; + this._downloadUrl = ""; + this.documentInfo = null; + this.metadata = null; + this._contentDispositionFilename = null; + this._contentLength = null; + this._saveInProgress = false; + this._hasAnnotationEditors = false; + promises.push(this.pdfScriptingManager.destroyPromise, this.passwordPrompt.close()); + this.setTitle(); + this.pdfSidebar?.reset(); + this.pdfOutlineViewer?.reset(); + this.pdfAttachmentViewer?.reset(); + this.pdfLayerViewer?.reset(); + this.pdfHistory?.reset(); + this.findBar?.reset(); + this.toolbar?.reset(); + this.secondaryToolbar?.reset(); + this._PDFBug?.cleanup(); + await Promise.all(promises); + }, + async open(args) { + if (this.pdfLoadingTask) { + await this.close(); + } + const workerParams = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.getAll(_app_options_js__WEBPACK_IMPORTED_MODULE_2__.OptionKind.WORKER); + Object.assign(pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.GlobalWorkerOptions, workerParams); + if (args.url) { + this.setTitleUsingUrl(args.originalUrl || args.url, args.url); + } + const apiParams = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.getAll(_app_options_js__WEBPACK_IMPORTED_MODULE_2__.OptionKind.API); + const loadingTask = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.getDocument)({ + ...apiParams, + ...args + }); + this.pdfLoadingTask = loadingTask; + loadingTask.onPassword = (updateCallback, reason) => { + if (this.isViewerEmbedded) { + this._unblockDocumentLoadEvent(); + } + this.pdfLinkService.externalLinkEnabled = false; + this.passwordPrompt.setUpdateCallback(updateCallback, reason); + this.passwordPrompt.open(); + }; + loadingTask.onProgress = ({ + loaded, + total + }) => { + this.progress(loaded / total); + }; + return loadingTask.promise.then(pdfDocument => { + this.load(pdfDocument); + }, reason => { + if (loadingTask !== this.pdfLoadingTask) { + return undefined; + } + let key = "pdfjs-loading-error"; + if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.InvalidPDFException) { + key = "pdfjs-invalid-file-error"; + } else if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.MissingPDFException) { + key = "pdfjs-missing-file-error"; + } else if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.UnexpectedResponseException) { + key = "pdfjs-unexpected-response-error"; + } + return this.l10n.get(key).then(msg => { + this._documentError(msg, { + message: reason?.message + }); + throw reason; + }); + }); + }, + _ensureDownloadComplete() { + if (this.pdfDocument && this.downloadComplete) { + return; + } + throw new Error("PDF document not downloaded."); + }, + async download(options = {}) { + const url = this._downloadUrl, + filename = this._docFilename; + try { + this._ensureDownloadComplete(); + const data = await this.pdfDocument.getData(); + const blob = new Blob([data], { + type: "application/pdf" + }); + await this.downloadManager.download(blob, url, filename, options); + } catch { + await this.downloadManager.downloadUrl(url, filename, options); + } + }, + async save(options = {}) { + if (this._saveInProgress) { + return; + } + this._saveInProgress = true; + await this.pdfScriptingManager.dispatchWillSave(); + const url = this._downloadUrl, + filename = this._docFilename; + try { + this._ensureDownloadComplete(); + const data = await this.pdfDocument.saveDocument(); + const blob = new Blob([data], { + type: "application/pdf" + }); + await this.downloadManager.download(blob, url, filename, options); + } catch (reason) { + console.error(`Error when saving the document: ${reason.message}`); + await this.download(options); + } finally { + await this.pdfScriptingManager.dispatchDidSave(); + this._saveInProgress = false; + } + if (this._hasAnnotationEditors) { + this.externalServices.reportTelemetry({ + type: "editing", + data: { + type: "save" + } + }); + } + }, + downloadOrSave(options = {}) { + if (this.pdfDocument?.annotationStorage.size > 0) { + this.save(options); + } else { + this.download(options); + } + }, + openInExternalApp() { + this.downloadOrSave({ + openInExternalApp: true + }); + }, + _documentError(message, moreInfo = null) { + this._unblockDocumentLoadEvent(); + this._otherError(message, moreInfo); + this.eventBus.dispatch("documenterror", { + source: this, + message, + reason: moreInfo?.message ?? null + }); + }, + _otherError(message, moreInfo = null) { + const moreInfoText = [`PDF.js v${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.version || "?"} (build: ${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.build || "?"})`]; + if (moreInfo) { + moreInfoText.push(`Message: ${moreInfo.message}`); + if (moreInfo.stack) { + moreInfoText.push(`Stack: ${moreInfo.stack}`); + } else { + if (moreInfo.filename) { + moreInfoText.push(`File: ${moreInfo.filename}`); + } + if (moreInfo.lineNumber) { + moreInfoText.push(`Line: ${moreInfo.lineNumber}`); + } + } + } + console.error(`${message}\n\n${moreInfoText.join("\n")}`); + }, + progress(level) { + if (!this.loadingBar || this.downloadComplete) { + return; + } + const percent = Math.round(level * 100); + if (percent <= this.loadingBar.percent) { + return; + } + this.loadingBar.percent = percent; + if (this.pdfDocument?.loadingParams.disableAutoFetch ?? _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("disableAutoFetch")) { + this.loadingBar.setDisableAutoFetch(); + } + }, + load(pdfDocument) { + this.pdfDocument = pdfDocument; + pdfDocument.getDownloadInfo().then(({ + length + }) => { + this._contentLength = length; + this.downloadComplete = true; + this.loadingBar?.hide(); + firstPagePromise.then(() => { + this.eventBus.dispatch("documentloaded", { + source: this + }); + }); + }); + const pageLayoutPromise = pdfDocument.getPageLayout().catch(() => {}); + const pageModePromise = pdfDocument.getPageMode().catch(() => {}); + const openActionPromise = pdfDocument.getOpenAction().catch(() => {}); + this.toolbar?.setPagesCount(pdfDocument.numPages, false); + this.secondaryToolbar?.setPagesCount(pdfDocument.numPages); + this.pdfLinkService.setDocument(pdfDocument); + this.pdfDocumentProperties?.setDocument(pdfDocument); + const pdfViewer = this.pdfViewer; + pdfViewer.setDocument(pdfDocument); + const { + firstPagePromise, + onePageRendered, + pagesPromise + } = pdfViewer; + this.pdfThumbnailViewer?.setDocument(pdfDocument); + const storedPromise = (this.store = new _view_history_js__WEBPACK_IMPORTED_MODULE_25__.ViewHistory(pdfDocument.fingerprints[0])).getMultiple({ + page: null, + zoom: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCALE_VALUE, + scrollLeft: "0", + scrollTop: "0", + rotation: null, + sidebarView: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN, + scrollMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.UNKNOWN, + spreadMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.UNKNOWN + }).catch(() => {}); + firstPagePromise.then(pdfPage => { + this.loadingBar?.setWidth(this.appConfig.viewerContainer); + this._initializeAnnotationStorageCallbacks(pdfDocument); + Promise.all([_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.animationStarted, storedPromise, pageLayoutPromise, pageModePromise, openActionPromise]).then(async ([timeStamp, stored, pageLayout, pageMode, openAction]) => { + const viewOnLoad = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("viewOnLoad"); + this._initializePdfHistory({ + fingerprint: pdfDocument.fingerprints[0], + viewOnLoad, + initialDest: openAction?.dest + }); + const initialBookmark = this.initialBookmark; + const zoom = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("defaultZoomValue"); + let hash = zoom ? `zoom=${zoom}` : null; + let rotation = null; + let sidebarView = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("sidebarViewOnLoad"); + let scrollMode = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("scrollModeOnLoad"); + let spreadMode = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("spreadModeOnLoad"); + if (stored?.page && viewOnLoad !== ViewOnLoad.INITIAL) { + hash = `page=${stored.page}&zoom=${zoom || stored.zoom},` + `${stored.scrollLeft},${stored.scrollTop}`; + rotation = parseInt(stored.rotation, 10); + if (sidebarView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN) { + sidebarView = stored.sidebarView | 0; + } + if (scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.UNKNOWN) { + scrollMode = stored.scrollMode | 0; + } + if (spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.UNKNOWN) { + spreadMode = stored.spreadMode | 0; + } + } + if (pageMode && sidebarView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN) { + sidebarView = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.apiPageModeToSidebarView)(pageMode); + } + if (pageLayout && scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.UNKNOWN && spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.UNKNOWN) { + const modes = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.apiPageLayoutToViewerModes)(pageLayout); + spreadMode = modes.spreadMode; + } + this.setInitialView(hash, { + rotation, + sidebarView, + scrollMode, + spreadMode + }); + this.eventBus.dispatch("documentinit", { + source: this + }); + if (!this.isViewerEmbedded) { + pdfViewer.focus(); + } + await Promise.race([pagesPromise, new Promise(resolve => { + setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT); + })]); + if (!initialBookmark && !hash) { + return; + } + if (pdfViewer.hasEqualPageSizes) { + return; + } + this.initialBookmark = initialBookmark; + pdfViewer.currentScaleValue = pdfViewer.currentScaleValue; + this.setInitialView(hash); + }).catch(() => { + this.setInitialView(); + }).then(function () { + pdfViewer.update(); + }); + }); + pagesPromise.then(() => { + this._unblockDocumentLoadEvent(); + this._initializeAutoPrint(pdfDocument, openActionPromise); + }, reason => { + this.l10n.get("pdfjs-loading-error").then(msg => { + this._documentError(msg, { + message: reason?.message + }); + }); + }); + onePageRendered.then(data => { + this.externalServices.reportTelemetry({ + type: "pageInfo", + timestamp: data.timestamp + }); + if (this.pdfOutlineViewer) { + pdfDocument.getOutline().then(outline => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.pdfOutlineViewer.render({ + outline, + pdfDocument + }); + }); + } + if (this.pdfAttachmentViewer) { + pdfDocument.getAttachments().then(attachments => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.pdfAttachmentViewer.render({ + attachments + }); + }); + } + if (this.pdfLayerViewer) { + pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this.pdfLayerViewer.render({ + optionalContentConfig, + pdfDocument + }); + }); + } + }); + this._initializePageLabels(pdfDocument); + this._initializeMetadata(pdfDocument); + }, + async _scriptingDocProperties(pdfDocument) { + if (!this.documentInfo) { + await new Promise(resolve => { + this.eventBus._on("metadataloaded", resolve, { + once: true + }); + }); + if (pdfDocument !== this.pdfDocument) { + return null; + } + } + if (!this._contentLength) { + await new Promise(resolve => { + this.eventBus._on("documentloaded", resolve, { + once: true + }); + }); + if (pdfDocument !== this.pdfDocument) { + return null; + } + } + return { + ...this.documentInfo, + baseURL: this.baseUrl, + filesize: this._contentLength, + filename: this._docFilename, + metadata: this.metadata?.getRaw(), + authors: this.metadata?.get("dc:creator"), + numPages: this.pagesCount, + URL: this.url + }; + }, + async _initializeAutoPrint(pdfDocument, openActionPromise) { + const [openAction, jsActions] = await Promise.all([openActionPromise, this.pdfViewer.enableScripting ? null : pdfDocument.getJSActions()]); + if (pdfDocument !== this.pdfDocument) { + return; + } + let triggerAutoPrint = openAction?.action === "Print"; + if (jsActions) { + console.warn("Warning: JavaScript support is not enabled"); + for (const name in jsActions) { + if (triggerAutoPrint) { + break; + } + switch (name) { + case "WillClose": + case "WillSave": + case "DidSave": + case "WillPrint": + case "DidPrint": + continue; + } + triggerAutoPrint = jsActions[name].some(js => _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.AutoPrintRegExp.test(js)); + } + } + if (triggerAutoPrint) { + this.triggerPrinting(); + } + }, + async _initializeMetadata(pdfDocument) { + const { + info, + metadata, + contentDispositionFilename, + contentLength + } = await pdfDocument.getMetadata(); + if (pdfDocument !== this.pdfDocument) { + return; + } + this.documentInfo = info; + this.metadata = metadata; + this._contentDispositionFilename ??= contentDispositionFilename; + this._contentLength ??= contentLength; + console.log(`PDF ${pdfDocument.fingerprints[0]} [${info.PDFFormatVersion} ` + `${(info.Producer || "-").trim()} / ${(info.Creator || "-").trim()}] ` + `(PDF.js: ${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.version || "?"} [${pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.build || "?"}])`); + let pdfTitle = info.Title; + const metadataTitle = metadata?.get("dc:title"); + if (metadataTitle) { + if (metadataTitle !== "Untitled" && !/[\uFFF0-\uFFFF]/g.test(metadataTitle)) { + pdfTitle = metadataTitle; + } + } + if (pdfTitle) { + this.setTitle(`${pdfTitle} - ${this._contentDispositionFilename || this._title}`); + } else if (this._contentDispositionFilename) { + this.setTitle(this._contentDispositionFilename); + } + if (info.IsXFAPresent && !info.IsAcroFormPresent && !pdfDocument.isPureXfa) { + if (pdfDocument.loadingParams.enableXfa) { + console.warn("Warning: XFA Foreground documents are not supported"); + } else { + console.warn("Warning: XFA support is not enabled"); + } + } else if ((info.IsAcroFormPresent || info.IsXFAPresent) && !this.pdfViewer.renderForms) { + console.warn("Warning: Interactive form support is not enabled"); + } + if (info.IsSignaturesPresent) { + console.warn("Warning: Digital signatures validation is not supported"); + } + this.eventBus.dispatch("metadataloaded", { + source: this + }); + }, + async _initializePageLabels(pdfDocument) { + const labels = await pdfDocument.getPageLabels(); + if (pdfDocument !== this.pdfDocument) { + return; + } + if (!labels || _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("disablePageLabels")) { + return; + } + const numLabels = labels.length; + let standardLabels = 0, + emptyLabels = 0; + for (let i = 0; i < numLabels; i++) { + const label = labels[i]; + if (label === (i + 1).toString()) { + standardLabels++; + } else if (label === "") { + emptyLabels++; + } else { + break; + } + } + if (standardLabels >= numLabels || emptyLabels >= numLabels) { + return; + } + const { + pdfViewer, + pdfThumbnailViewer, + toolbar + } = this; + pdfViewer.setPageLabels(labels); + pdfThumbnailViewer?.setPageLabels(labels); + toolbar?.setPagesCount(numLabels, true); + toolbar?.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel); + }, + _initializePdfHistory({ + fingerprint, + viewOnLoad, + initialDest = null + }) { + if (!this.pdfHistory) { + return; + } + this.pdfHistory.initialize({ + fingerprint, + resetHistory: viewOnLoad === ViewOnLoad.INITIAL, + updateUrl: _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("historyUpdateUrl") + }); + if (this.pdfHistory.initialBookmark) { + this.initialBookmark = this.pdfHistory.initialBookmark; + this.initialRotation = this.pdfHistory.initialRotation; + } + if (initialDest && !this.initialBookmark && viewOnLoad === ViewOnLoad.UNKNOWN) { + this.initialBookmark = JSON.stringify(initialDest); + this.pdfHistory.push({ + explicitDest: initialDest, + pageNumber: null + }); + } + }, + _initializeAnnotationStorageCallbacks(pdfDocument) { + if (pdfDocument !== this.pdfDocument) { + return; + } + const { + annotationStorage + } = pdfDocument; + annotationStorage.onSetModified = () => { + window.addEventListener("beforeunload", beforeUnload); + this._annotationStorageModified = true; + }; + annotationStorage.onResetModified = () => { + window.removeEventListener("beforeunload", beforeUnload); + delete this._annotationStorageModified; + }; + annotationStorage.onAnnotationEditor = typeStr => { + this._hasAnnotationEditors = !!typeStr; + this.setTitle(); + if (typeStr) { + this.externalServices.reportTelemetry({ + type: "editing", + data: { + type: typeStr + } + }); + } + }; + }, + setInitialView(storedHash, { + rotation, + sidebarView, + scrollMode, + spreadMode + } = {}) { + const setRotation = angle => { + if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidRotation)(angle)) { + this.pdfViewer.pagesRotation = angle; + } + }; + const setViewerModes = (scroll, spread) => { + if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidScrollMode)(scroll)) { + this.pdfViewer.scrollMode = scroll; + } + if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidSpreadMode)(spread)) { + this.pdfViewer.spreadMode = spread; + } + }; + this.isInitialViewSet = true; + this.pdfSidebar?.setInitialView(sidebarView); + setViewerModes(scrollMode, spreadMode); + if (this.initialBookmark) { + setRotation(this.initialRotation); + delete this.initialRotation; + this.pdfLinkService.setHash(this.initialBookmark); + this.initialBookmark = null; + } else if (storedHash) { + setRotation(rotation); + this.pdfLinkService.setHash(storedHash); + } + this.toolbar?.setPageNumber(this.pdfViewer.currentPageNumber, this.pdfViewer.currentPageLabel); + this.secondaryToolbar?.setPageNumber(this.pdfViewer.currentPageNumber); + if (!this.pdfViewer.currentScaleValue) { + this.pdfViewer.currentScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCALE_VALUE; + } + }, + _cleanup() { + if (!this.pdfDocument) { + return; + } + this.pdfViewer.cleanup(); + this.pdfThumbnailViewer?.cleanup(); + this.pdfDocument.cleanup(_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("fontExtraProperties")); + }, + forceRendering() { + this.pdfRenderingQueue.printing = !!this.printService; + this.pdfRenderingQueue.isThumbnailViewEnabled = this.pdfSidebar?.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS; + this.pdfRenderingQueue.renderHighestPriority(); + }, + beforePrint() { + this._printAnnotationStoragePromise = this.pdfScriptingManager.dispatchWillPrint().catch(() => {}).then(() => { + return this.pdfDocument?.annotationStorage.print; + }); + if (this.printService) { + return; + } + if (!this.supportsPrinting) { + this.l10n.get("pdfjs-printing-not-supported").then(msg => { + this._otherError(msg); + }); + return; + } + if (!this.pdfViewer.pageViewsReady) { + this.l10n.get("pdfjs-printing-not-ready").then(msg => { + window.alert(msg); + }); + return; + } + const pagesOverview = this.pdfViewer.getPagesOverview(); + const printContainer = this.appConfig.printContainer; + const printResolution = _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("printResolution"); + const optionalContentConfigPromise = this.pdfViewer.optionalContentConfigPromise; + const printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, this._printAnnotationStoragePromise); + this.printService = printService; + this.forceRendering(); + this.setTitle(); + printService.layout(); + if (this._hasAnnotationEditors) { + this.externalServices.reportTelemetry({ + type: "editing", + data: { + type: "print" + } + }); + } + }, + afterPrint() { + if (this._printAnnotationStoragePromise) { + this._printAnnotationStoragePromise.then(() => { + this.pdfScriptingManager.dispatchDidPrint(); + }); + this._printAnnotationStoragePromise = null; + } + if (this.printService) { + this.printService.destroy(); + this.printService = null; + this.pdfDocument?.annotationStorage.resetModified(); + } + this.forceRendering(); + this.setTitle(); + }, + rotatePages(delta) { + this.pdfViewer.pagesRotation += delta; + }, + requestPresentationMode() { + this.pdfPresentationMode?.request(); + }, + triggerPrinting() { + if (!this.supportsPrinting) { + return; + } + window.print(); + }, + bindEvents() { + const { + eventBus, + _boundEvents + } = this; + _boundEvents.beforePrint = this.beforePrint.bind(this); + _boundEvents.afterPrint = this.afterPrint.bind(this); + eventBus._on("resize", webViewerResize); + eventBus._on("hashchange", webViewerHashchange); + eventBus._on("beforeprint", _boundEvents.beforePrint); + eventBus._on("afterprint", _boundEvents.afterPrint); + eventBus._on("pagerender", webViewerPageRender); + eventBus._on("pagerendered", webViewerPageRendered); + eventBus._on("updateviewarea", webViewerUpdateViewarea); + eventBus._on("pagechanging", webViewerPageChanging); + eventBus._on("scalechanging", webViewerScaleChanging); + eventBus._on("rotationchanging", webViewerRotationChanging); + eventBus._on("sidebarviewchanged", webViewerSidebarViewChanged); + eventBus._on("pagemode", webViewerPageMode); + eventBus._on("namedaction", webViewerNamedAction); + eventBus._on("presentationmodechanged", webViewerPresentationModeChanged); + eventBus._on("presentationmode", webViewerPresentationMode); + eventBus._on("switchannotationeditormode", webViewerSwitchAnnotationEditorMode); + eventBus._on("switchannotationeditorparams", webViewerSwitchAnnotationEditorParams); + eventBus._on("print", webViewerPrint); + eventBus._on("download", webViewerDownload); + eventBus._on("openinexternalapp", webViewerOpenInExternalApp); + eventBus._on("firstpage", webViewerFirstPage); + eventBus._on("lastpage", webViewerLastPage); + eventBus._on("nextpage", webViewerNextPage); + eventBus._on("previouspage", webViewerPreviousPage); + eventBus._on("zoomin", webViewerZoomIn); + eventBus._on("zoomout", webViewerZoomOut); + eventBus._on("zoomreset", webViewerZoomReset); + eventBus._on("pagenumberchanged", webViewerPageNumberChanged); + eventBus._on("scalechanged", webViewerScaleChanged); + eventBus._on("rotatecw", webViewerRotateCw); + eventBus._on("rotateccw", webViewerRotateCcw); + eventBus._on("optionalcontentconfig", webViewerOptionalContentConfig); + eventBus._on("switchscrollmode", webViewerSwitchScrollMode); + eventBus._on("scrollmodechanged", webViewerScrollModeChanged); + eventBus._on("switchspreadmode", webViewerSwitchSpreadMode); + eventBus._on("spreadmodechanged", webViewerSpreadModeChanged); + eventBus._on("documentproperties", webViewerDocumentProperties); + eventBus._on("findfromurlhash", webViewerFindFromUrlHash); + eventBus._on("updatefindmatchescount", webViewerUpdateFindMatchesCount); + eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState); + if (_app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("pdfBug")) { + _boundEvents.reportPageStatsPDFBug = reportPageStatsPDFBug; + eventBus._on("pagerendered", _boundEvents.reportPageStatsPDFBug); + eventBus._on("pagechanging", _boundEvents.reportPageStatsPDFBug); + } + eventBus._on("fileinputchange", webViewerFileInputChange); + eventBus._on("openfile", webViewerOpenFile); + }, + bindWindowEvents() { + const { + eventBus, + _boundEvents + } = this; + function addWindowResolutionChange(evt = null) { + if (evt) { + webViewerResolutionChange(evt); + } + const mediaQueryList = window.matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`); + mediaQueryList.addEventListener("change", addWindowResolutionChange, { + once: true + }); + _boundEvents.removeWindowResolutionChange ||= function () { + mediaQueryList.removeEventListener("change", addWindowResolutionChange); + _boundEvents.removeWindowResolutionChange = null; + }; + } + addWindowResolutionChange(); + _boundEvents.windowResize = () => { + eventBus.dispatch("resize", { + source: window + }); + }; + _boundEvents.windowHashChange = () => { + eventBus.dispatch("hashchange", { + source: window, + hash: document.location.hash.substring(1) + }); + }; + _boundEvents.windowBeforePrint = () => { + eventBus.dispatch("beforeprint", { + source: window + }); + }; + _boundEvents.windowAfterPrint = () => { + eventBus.dispatch("afterprint", { + source: window + }); + }; + _boundEvents.windowUpdateFromSandbox = event => { + eventBus.dispatch("updatefromsandbox", { + source: window, + detail: event.detail + }); + }; + window.addEventListener("visibilitychange", webViewerVisibilityChange); + window.addEventListener("wheel", webViewerWheel, { + passive: false + }); + window.addEventListener("touchstart", webViewerTouchStart, { + passive: false + }); + window.addEventListener("touchmove", webViewerTouchMove, { + passive: false + }); + window.addEventListener("touchend", webViewerTouchEnd, { + passive: false + }); + window.addEventListener("click", webViewerClick); + window.addEventListener("keydown", webViewerKeyDown); + window.addEventListener("keyup", webViewerKeyUp); + window.addEventListener("resize", _boundEvents.windowResize); + window.addEventListener("hashchange", _boundEvents.windowHashChange); + window.addEventListener("beforeprint", _boundEvents.windowBeforePrint); + window.addEventListener("afterprint", _boundEvents.windowAfterPrint); + window.addEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox); + }, + unbindEvents() { + const { + eventBus, + _boundEvents + } = this; + eventBus._off("resize", webViewerResize); + eventBus._off("hashchange", webViewerHashchange); + eventBus._off("beforeprint", _boundEvents.beforePrint); + eventBus._off("afterprint", _boundEvents.afterPrint); + eventBus._off("pagerender", webViewerPageRender); + eventBus._off("pagerendered", webViewerPageRendered); + eventBus._off("updateviewarea", webViewerUpdateViewarea); + eventBus._off("pagechanging", webViewerPageChanging); + eventBus._off("scalechanging", webViewerScaleChanging); + eventBus._off("rotationchanging", webViewerRotationChanging); + eventBus._off("sidebarviewchanged", webViewerSidebarViewChanged); + eventBus._off("pagemode", webViewerPageMode); + eventBus._off("namedaction", webViewerNamedAction); + eventBus._off("presentationmodechanged", webViewerPresentationModeChanged); + eventBus._off("presentationmode", webViewerPresentationMode); + eventBus._off("print", webViewerPrint); + eventBus._off("download", webViewerDownload); + eventBus._off("openinexternalapp", webViewerOpenInExternalApp); + eventBus._off("firstpage", webViewerFirstPage); + eventBus._off("lastpage", webViewerLastPage); + eventBus._off("nextpage", webViewerNextPage); + eventBus._off("previouspage", webViewerPreviousPage); + eventBus._off("zoomin", webViewerZoomIn); + eventBus._off("zoomout", webViewerZoomOut); + eventBus._off("zoomreset", webViewerZoomReset); + eventBus._off("pagenumberchanged", webViewerPageNumberChanged); + eventBus._off("scalechanged", webViewerScaleChanged); + eventBus._off("rotatecw", webViewerRotateCw); + eventBus._off("rotateccw", webViewerRotateCcw); + eventBus._off("optionalcontentconfig", webViewerOptionalContentConfig); + eventBus._off("switchscrollmode", webViewerSwitchScrollMode); + eventBus._off("scrollmodechanged", webViewerScrollModeChanged); + eventBus._off("switchspreadmode", webViewerSwitchSpreadMode); + eventBus._off("spreadmodechanged", webViewerSpreadModeChanged); + eventBus._off("documentproperties", webViewerDocumentProperties); + eventBus._off("findfromurlhash", webViewerFindFromUrlHash); + eventBus._off("updatefindmatchescount", webViewerUpdateFindMatchesCount); + eventBus._off("updatefindcontrolstate", webViewerUpdateFindControlState); + if (_boundEvents.reportPageStatsPDFBug) { + eventBus._off("pagerendered", _boundEvents.reportPageStatsPDFBug); + eventBus._off("pagechanging", _boundEvents.reportPageStatsPDFBug); + _boundEvents.reportPageStatsPDFBug = null; + } + eventBus._off("fileinputchange", webViewerFileInputChange); + eventBus._off("openfile", webViewerOpenFile); + _boundEvents.beforePrint = null; + _boundEvents.afterPrint = null; + }, + unbindWindowEvents() { + const { + _boundEvents + } = this; + window.removeEventListener("visibilitychange", webViewerVisibilityChange); + window.removeEventListener("wheel", webViewerWheel, { + passive: false + }); + window.removeEventListener("touchstart", webViewerTouchStart, { + passive: false + }); + window.removeEventListener("touchmove", webViewerTouchMove, { + passive: false + }); + window.removeEventListener("touchend", webViewerTouchEnd, { + passive: false + }); + window.removeEventListener("click", webViewerClick); + window.removeEventListener("keydown", webViewerKeyDown); + window.removeEventListener("keyup", webViewerKeyUp); + window.removeEventListener("resize", _boundEvents.windowResize); + window.removeEventListener("hashchange", _boundEvents.windowHashChange); + window.removeEventListener("beforeprint", _boundEvents.windowBeforePrint); + window.removeEventListener("afterprint", _boundEvents.windowAfterPrint); + window.removeEventListener("updatefromsandbox", _boundEvents.windowUpdateFromSandbox); + _boundEvents.removeWindowResolutionChange?.(); + _boundEvents.windowResize = null; + _boundEvents.windowHashChange = null; + _boundEvents.windowBeforePrint = null; + _boundEvents.windowAfterPrint = null; + _boundEvents.windowUpdateFromSandbox = null; + }, + _accumulateTicks(ticks, prop) { + if (this[prop] > 0 && ticks < 0 || this[prop] < 0 && ticks > 0) { + this[prop] = 0; + } + this[prop] += ticks; + const wholeTicks = Math.trunc(this[prop]); + this[prop] -= wholeTicks; + return wholeTicks; + }, + _accumulateFactor(previousScale, factor, prop) { + if (factor === 1) { + return 1; + } + if (this[prop] > 1 && factor < 1 || this[prop] < 1 && factor > 1) { + this[prop] = 1; + } + const newFactor = Math.floor(previousScale * factor * this[prop] * 100) / (100 * previousScale); + this[prop] = factor / newFactor; + return newFactor; + }, + _centerAtPos(previousScale, x, y) { + const { + pdfViewer + } = this; + const scaleDiff = pdfViewer.currentScale / previousScale - 1; + if (scaleDiff !== 0) { + const [top, left] = pdfViewer.containerTopLeft; + pdfViewer.container.scrollLeft += (x - left) * scaleDiff; + pdfViewer.container.scrollTop += (y - top) * scaleDiff; + } + }, + _unblockDocumentLoadEvent() { + document.blockUnblockOnload?.(false); + this._unblockDocumentLoadEvent = () => {}; + }, + get scriptingReady() { + return this.pdfScriptingManager.ready; + } +}; +{ + const HOSTED_VIEWER_ORIGINS = ["null", "http://mozilla.github.io", "https://mozilla.github.io"]; + var validateFileURL = function (file) { + if (!file) { + return; + } + try { + const viewerOrigin = new URL(window.location.href).origin || "null"; + if (HOSTED_VIEWER_ORIGINS.includes(viewerOrigin)) { + return; + } + const fileOrigin = new URL(file, window.location.href).origin; + if (fileOrigin !== viewerOrigin) { + throw new Error("file origin does not match viewer's"); + } + } catch (ex) { + PDFViewerApplication.l10n.get("pdfjs-loading-error").then(msg => { + PDFViewerApplication._documentError(msg, { + message: ex?.message + }); + }); + throw ex; + } + }; +} +async function loadFakeWorker() { + pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.GlobalWorkerOptions.workerSrc ||= _app_options_js__WEBPACK_IMPORTED_MODULE_2__.AppOptions.get("workerSrc"); + await import(/* webpackIgnore: true */ pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PDFWorker.workerSrc); +} +async function loadPDFBug(self) { + const { + debuggerScriptPath + } = self.appConfig; + const { + PDFBug + } = await import(/* webpackIgnore: true */ debuggerScriptPath); + self._PDFBug = PDFBug; +} +function reportPageStatsPDFBug({ + pageNumber +}) { + if (!globalThis.Stats?.enabled) { + return; + } + const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1); + globalThis.Stats.add(pageNumber, pageView?.pdfPage?.stats); +} +function webViewerPageRender({ + pageNumber +}) { + if (pageNumber === PDFViewerApplication.page) { + PDFViewerApplication.toolbar?.updateLoadingIndicatorState(true); + } +} +function webViewerPageRendered({ + pageNumber, + error +}) { + if (pageNumber === PDFViewerApplication.page) { + PDFViewerApplication.toolbar?.updateLoadingIndicatorState(false); + } + if (PDFViewerApplication.pdfSidebar?.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) { + const pageView = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1); + const thumbnailView = PDFViewerApplication.pdfThumbnailViewer?.getThumbnail(pageNumber - 1); + if (pageView) { + thumbnailView?.setImage(pageView); + } + } + if (error) { + PDFViewerApplication.l10n.get("pdfjs-rendering-error").then(msg => { + PDFViewerApplication._otherError(msg, error); + }); + } +} +function webViewerPageMode({ + mode +}) { + let view; + switch (mode) { + case "thumbs": + view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS; + break; + case "bookmarks": + case "outline": + view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE; + break; + case "attachments": + view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS; + break; + case "layers": + view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS; + break; + case "none": + view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE; + break; + default: + console.error('Invalid "pagemode" hash parameter: ' + mode); + return; + } + PDFViewerApplication.pdfSidebar?.switchView(view, true); +} +function webViewerNamedAction(evt) { + switch (evt.action) { + case "GoToPage": + PDFViewerApplication.appConfig.toolbar?.pageNumber.select(); + break; + case "Find": + if (!PDFViewerApplication.supportsIntegratedFind) { + PDFViewerApplication?.findBar.toggle(); + } + break; + case "Print": + PDFViewerApplication.triggerPrinting(); + break; + case "SaveAs": + PDFViewerApplication.downloadOrSave(); + break; + } +} +function webViewerPresentationModeChanged(evt) { + PDFViewerApplication.pdfViewer.presentationModeState = evt.state; +} +function webViewerSidebarViewChanged({ + view +}) { + PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled = view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS; + if (PDFViewerApplication.isInitialViewSet) { + PDFViewerApplication.store?.set("sidebarView", view).catch(() => {}); + } +} +function webViewerUpdateViewarea({ + location +}) { + if (PDFViewerApplication.isInitialViewSet) { + PDFViewerApplication.store?.setMultiple({ + page: location.pageNumber, + zoom: location.scale, + scrollLeft: location.left, + scrollTop: location.top, + rotation: location.rotation + }).catch(() => {}); + } + if (PDFViewerApplication.appConfig.secondaryToolbar) { + const href = PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams); + PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href = href; + } +} +function webViewerScrollModeChanged(evt) { + if (PDFViewerApplication.isInitialViewSet && !PDFViewerApplication.pdfViewer.isInPresentationMode) { + PDFViewerApplication.store?.set("scrollMode", evt.mode).catch(() => {}); + } +} +function webViewerSpreadModeChanged(evt) { + if (PDFViewerApplication.isInitialViewSet && !PDFViewerApplication.pdfViewer.isInPresentationMode) { + PDFViewerApplication.store?.set("spreadMode", evt.mode).catch(() => {}); + } +} +function webViewerResize() { + const { + pdfDocument, + pdfViewer, + pdfRenderingQueue + } = PDFViewerApplication; + if (pdfRenderingQueue.printing && window.matchMedia("print").matches) { + return; + } + if (!pdfDocument) { + return; + } + const currentScaleValue = pdfViewer.currentScaleValue; + if (currentScaleValue === "auto" || currentScaleValue === "page-fit" || currentScaleValue === "page-width") { + pdfViewer.currentScaleValue = currentScaleValue; + } + pdfViewer.update(); +} +function webViewerHashchange(evt) { + const hash = evt.hash; + if (!hash) { + return; + } + if (!PDFViewerApplication.isInitialViewSet) { + PDFViewerApplication.initialBookmark = hash; + } else if (!PDFViewerApplication.pdfHistory?.popStateInProgress) { + PDFViewerApplication.pdfLinkService.setHash(hash); + } +} +{ + var webViewerFileInputChange = function (evt) { + if (PDFViewerApplication.pdfViewer?.isInPresentationMode) { + return; + } + const file = evt.fileInput.files[0]; + PDFViewerApplication.open({ + url: URL.createObjectURL(file), + originalUrl: file.name + }); + }; + var webViewerOpenFile = function (evt) { + const fileInput = PDFViewerApplication.appConfig.openFileInput; + fileInput.click(); + }; +} +function webViewerPresentationMode() { + PDFViewerApplication.requestPresentationMode(); +} +function webViewerSwitchAnnotationEditorMode(evt) { + PDFViewerApplication.pdfViewer.annotationEditorMode = evt; +} +function webViewerSwitchAnnotationEditorParams(evt) { + PDFViewerApplication.pdfViewer.annotationEditorParams = evt; +} +function webViewerPrint() { + PDFViewerApplication.triggerPrinting(); +} +function webViewerDownload() { + PDFViewerApplication.downloadOrSave(); +} +function webViewerOpenInExternalApp() { + PDFViewerApplication.openInExternalApp(); +} +function webViewerFirstPage() { + PDFViewerApplication.page = 1; +} +function webViewerLastPage() { + PDFViewerApplication.page = PDFViewerApplication.pagesCount; +} +function webViewerNextPage() { + PDFViewerApplication.pdfViewer.nextPage(); +} +function webViewerPreviousPage() { + PDFViewerApplication.pdfViewer.previousPage(); +} +function webViewerZoomIn() { + PDFViewerApplication.zoomIn(); +} +function webViewerZoomOut() { + PDFViewerApplication.zoomOut(); +} +function webViewerZoomReset() { + PDFViewerApplication.zoomReset(); +} +function webViewerPageNumberChanged(evt) { + const pdfViewer = PDFViewerApplication.pdfViewer; + if (evt.value !== "") { + PDFViewerApplication.pdfLinkService.goToPage(evt.value); + } + if (evt.value !== pdfViewer.currentPageNumber.toString() && evt.value !== pdfViewer.currentPageLabel) { + PDFViewerApplication.toolbar?.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel); + } +} +function webViewerScaleChanged(evt) { + PDFViewerApplication.pdfViewer.currentScaleValue = evt.value; +} +function webViewerRotateCw() { + PDFViewerApplication.rotatePages(90); +} +function webViewerRotateCcw() { + PDFViewerApplication.rotatePages(-90); +} +function webViewerOptionalContentConfig(evt) { + PDFViewerApplication.pdfViewer.optionalContentConfigPromise = evt.promise; +} +function webViewerSwitchScrollMode(evt) { + PDFViewerApplication.pdfViewer.scrollMode = evt.mode; +} +function webViewerSwitchSpreadMode(evt) { + PDFViewerApplication.pdfViewer.spreadMode = evt.mode; +} +function webViewerDocumentProperties() { + PDFViewerApplication.pdfDocumentProperties?.open(); +} +function webViewerFindFromUrlHash(evt) { + PDFViewerApplication.eventBus.dispatch("find", { + source: evt.source, + type: "", + query: evt.query, + caseSensitive: false, + entireWord: false, + highlightAll: true, + findPrevious: false, + matchDiacritics: true + }); +} +function webViewerUpdateFindMatchesCount({ + matchesCount +}) { + if (PDFViewerApplication.supportsIntegratedFind) { + PDFViewerApplication.externalServices.updateFindMatchesCount(matchesCount); + } else { + PDFViewerApplication.findBar.updateResultsCount(matchesCount); + } +} +function webViewerUpdateFindControlState({ + state, + previous, + matchesCount, + rawQuery +}) { + if (PDFViewerApplication.supportsIntegratedFind) { + PDFViewerApplication.externalServices.updateFindControlState({ + result: state, + findPrevious: previous, + matchesCount, + rawQuery + }); + } else { + PDFViewerApplication.findBar?.updateUIState(state, previous, matchesCount); + } +} +function webViewerScaleChanging(evt) { + PDFViewerApplication.toolbar?.setPageScale(evt.presetValue, evt.scale); + PDFViewerApplication.pdfViewer.update(); +} +function webViewerRotationChanging(evt) { + if (PDFViewerApplication.pdfThumbnailViewer) { + PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation; + } + PDFViewerApplication.forceRendering(); + PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber; +} +function webViewerPageChanging({ + pageNumber, + pageLabel +}) { + PDFViewerApplication.toolbar?.setPageNumber(pageNumber, pageLabel); + PDFViewerApplication.secondaryToolbar?.setPageNumber(pageNumber); + if (PDFViewerApplication.pdfSidebar?.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) { + PDFViewerApplication.pdfThumbnailViewer?.scrollThumbnailIntoView(pageNumber); + } + const currentPage = PDFViewerApplication.pdfViewer.getPageView(pageNumber - 1); + PDFViewerApplication.toolbar?.updateLoadingIndicatorState(currentPage?.renderingState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.RUNNING); +} +function webViewerResolutionChange(evt) { + PDFViewerApplication.pdfViewer.refresh(); +} +function webViewerVisibilityChange(evt) { + if (document.visibilityState === "visible") { + setZoomDisabledTimeout(); + } +} +let zoomDisabledTimeout = null; +function setZoomDisabledTimeout() { + if (zoomDisabledTimeout) { + clearTimeout(zoomDisabledTimeout); + } + zoomDisabledTimeout = setTimeout(function () { + zoomDisabledTimeout = null; + }, WHEEL_ZOOM_DISABLED_TIMEOUT); +} +function webViewerWheel(evt) { + const { + pdfViewer, + supportsMouseWheelZoomCtrlKey, + supportsMouseWheelZoomMetaKey, + supportsPinchToZoom + } = PDFViewerApplication; + if (pdfViewer.isInPresentationMode) { + return; + } + const deltaMode = evt.deltaMode; + let scaleFactor = Math.exp(-evt.deltaY / 100); + const isBuiltInMac = false; + const isPinchToZoom = evt.ctrlKey && !PDFViewerApplication._isCtrlKeyDown && deltaMode === WheelEvent.DOM_DELTA_PIXEL && evt.deltaX === 0 && (Math.abs(scaleFactor - 1) < 0.05 || isBuiltInMac) && evt.deltaZ === 0; + if (isPinchToZoom || evt.ctrlKey && supportsMouseWheelZoomCtrlKey || evt.metaKey && supportsMouseWheelZoomMetaKey) { + evt.preventDefault(); + if (zoomDisabledTimeout || document.visibilityState === "hidden" || PDFViewerApplication.overlayManager.active) { + return; + } + const previousScale = pdfViewer.currentScale; + if (isPinchToZoom && supportsPinchToZoom) { + scaleFactor = PDFViewerApplication._accumulateFactor(previousScale, scaleFactor, "_wheelUnusedFactor"); + if (scaleFactor < 1) { + PDFViewerApplication.zoomOut(null, scaleFactor); + } else if (scaleFactor > 1) { + PDFViewerApplication.zoomIn(null, scaleFactor); + } else { + return; + } + } else { + const delta = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.normalizeWheelEventDirection)(evt); + let ticks = 0; + if (deltaMode === WheelEvent.DOM_DELTA_LINE || deltaMode === WheelEvent.DOM_DELTA_PAGE) { + if (Math.abs(delta) >= 1) { + ticks = Math.sign(delta); + } else { + ticks = PDFViewerApplication._accumulateTicks(delta, "_wheelUnusedTicks"); + } + } else { + const PIXELS_PER_LINE_SCALE = 30; + ticks = PDFViewerApplication._accumulateTicks(delta / PIXELS_PER_LINE_SCALE, "_wheelUnusedTicks"); + } + if (ticks < 0) { + PDFViewerApplication.zoomOut(-ticks); + } else if (ticks > 0) { + PDFViewerApplication.zoomIn(ticks); + } else { + return; + } + } + PDFViewerApplication._centerAtPos(previousScale, evt.clientX, evt.clientY); + } else { + setZoomDisabledTimeout(); + } +} +function webViewerTouchStart(evt) { + if (PDFViewerApplication.pdfViewer.isInPresentationMode || evt.touches.length < 2) { + return; + } + evt.preventDefault(); + if (evt.touches.length !== 2 || PDFViewerApplication.overlayManager.active) { + PDFViewerApplication._touchInfo = null; + return; + } + let [touch0, touch1] = evt.touches; + if (touch0.identifier > touch1.identifier) { + [touch0, touch1] = [touch1, touch0]; + } + PDFViewerApplication._touchInfo = { + touch0X: touch0.pageX, + touch0Y: touch0.pageY, + touch1X: touch1.pageX, + touch1Y: touch1.pageY + }; +} +function webViewerTouchMove(evt) { + if (!PDFViewerApplication._touchInfo || evt.touches.length !== 2) { + return; + } + const { + pdfViewer, + _touchInfo, + supportsPinchToZoom + } = PDFViewerApplication; + let [touch0, touch1] = evt.touches; + if (touch0.identifier > touch1.identifier) { + [touch0, touch1] = [touch1, touch0]; + } + const { + pageX: page0X, + pageY: page0Y + } = touch0; + const { + pageX: page1X, + pageY: page1Y + } = touch1; + const { + touch0X: pTouch0X, + touch0Y: pTouch0Y, + touch1X: pTouch1X, + touch1Y: pTouch1Y + } = _touchInfo; + if (Math.abs(pTouch0X - page0X) <= 1 && Math.abs(pTouch0Y - page0Y) <= 1 && Math.abs(pTouch1X - page1X) <= 1 && Math.abs(pTouch1Y - page1Y) <= 1) { + return; + } + _touchInfo.touch0X = page0X; + _touchInfo.touch0Y = page0Y; + _touchInfo.touch1X = page1X; + _touchInfo.touch1Y = page1Y; + if (pTouch0X === page0X && pTouch0Y === page0Y) { + const v1X = pTouch1X - page0X; + const v1Y = pTouch1Y - page0Y; + const v2X = page1X - page0X; + const v2Y = page1Y - page0Y; + const det = v1X * v2Y - v1Y * v2X; + if (Math.abs(det) > 0.02 * Math.hypot(v1X, v1Y) * Math.hypot(v2X, v2Y)) { + return; + } + } else if (pTouch1X === page1X && pTouch1Y === page1Y) { + const v1X = pTouch0X - page1X; + const v1Y = pTouch0Y - page1Y; + const v2X = page0X - page1X; + const v2Y = page0Y - page1Y; + const det = v1X * v2Y - v1Y * v2X; + if (Math.abs(det) > 0.02 * Math.hypot(v1X, v1Y) * Math.hypot(v2X, v2Y)) { + return; + } + } else { + const diff0X = page0X - pTouch0X; + const diff1X = page1X - pTouch1X; + const diff0Y = page0Y - pTouch0Y; + const diff1Y = page1Y - pTouch1Y; + const dotProduct = diff0X * diff1X + diff0Y * diff1Y; + if (dotProduct >= 0) { + return; + } + } + evt.preventDefault(); + const distance = Math.hypot(page0X - page1X, page0Y - page1Y) || 1; + const pDistance = Math.hypot(pTouch0X - pTouch1X, pTouch0Y - pTouch1Y) || 1; + const previousScale = pdfViewer.currentScale; + if (supportsPinchToZoom) { + const newScaleFactor = PDFViewerApplication._accumulateFactor(previousScale, distance / pDistance, "_touchUnusedFactor"); + if (newScaleFactor < 1) { + PDFViewerApplication.zoomOut(null, newScaleFactor); + } else if (newScaleFactor > 1) { + PDFViewerApplication.zoomIn(null, newScaleFactor); + } else { + return; + } + } else { + const PIXELS_PER_LINE_SCALE = 30; + const ticks = PDFViewerApplication._accumulateTicks((distance - pDistance) / PIXELS_PER_LINE_SCALE, "_touchUnusedTicks"); + if (ticks < 0) { + PDFViewerApplication.zoomOut(-ticks); + } else if (ticks > 0) { + PDFViewerApplication.zoomIn(ticks); + } else { + return; + } + } + PDFViewerApplication._centerAtPos(previousScale, (page0X + page1X) / 2, (page0Y + page1Y) / 2); +} +function webViewerTouchEnd(evt) { + if (!PDFViewerApplication._touchInfo) { + return; + } + evt.preventDefault(); + PDFViewerApplication._touchInfo = null; + PDFViewerApplication._touchUnusedTicks = 0; + PDFViewerApplication._touchUnusedFactor = 1; +} +function webViewerClick(evt) { + if (!PDFViewerApplication.secondaryToolbar?.isOpen) { + return; + } + const appConfig = PDFViewerApplication.appConfig; + if (PDFViewerApplication.pdfViewer.containsElement(evt.target) || appConfig.toolbar?.container.contains(evt.target) && evt.target !== appConfig.secondaryToolbar?.toggleButton) { + PDFViewerApplication.secondaryToolbar.close(); + } +} +function webViewerKeyUp(evt) { + if (evt.key === "Control") { + PDFViewerApplication._isCtrlKeyDown = false; + } +} +function webViewerKeyDown(evt) { + PDFViewerApplication._isCtrlKeyDown = evt.key === "Control"; + if (PDFViewerApplication.overlayManager.active) { + return; + } + const { + eventBus, + pdfViewer + } = PDFViewerApplication; + const isViewerInPresentationMode = pdfViewer.isInPresentationMode; + let handled = false, + ensureViewerFocused = false; + const cmd = (evt.ctrlKey ? 1 : 0) | (evt.altKey ? 2 : 0) | (evt.shiftKey ? 4 : 0) | (evt.metaKey ? 8 : 0); + if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) { + switch (evt.keyCode) { + case 70: + if (!PDFViewerApplication.supportsIntegratedFind && !evt.shiftKey) { + PDFViewerApplication.findBar?.open(); + handled = true; + } + break; + case 71: + if (!PDFViewerApplication.supportsIntegratedFind) { + const { + state + } = PDFViewerApplication.findController; + if (state) { + const newState = { + source: window, + type: "again", + findPrevious: cmd === 5 || cmd === 12 + }; + eventBus.dispatch("find", { + ...state, + ...newState + }); + } + handled = true; + } + break; + case 61: + case 107: + case 187: + case 171: + PDFViewerApplication.zoomIn(); + handled = true; + break; + case 173: + case 109: + case 189: + PDFViewerApplication.zoomOut(); + handled = true; + break; + case 48: + case 96: + if (!isViewerInPresentationMode) { + setTimeout(function () { + PDFViewerApplication.zoomReset(); + }); + handled = false; + } + break; + case 38: + if (isViewerInPresentationMode || PDFViewerApplication.page > 1) { + PDFViewerApplication.page = 1; + handled = true; + ensureViewerFocused = true; + } + break; + case 40: + if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) { + PDFViewerApplication.page = PDFViewerApplication.pagesCount; + handled = true; + ensureViewerFocused = true; + } + break; + } + } + if (cmd === 1 || cmd === 8) { + switch (evt.keyCode) { + case 83: + eventBus.dispatch("download", { + source: window + }); + handled = true; + break; + case 79: + { + eventBus.dispatch("openfile", { + source: window + }); + handled = true; + } + break; + } + } + if (cmd === 3 || cmd === 10) { + switch (evt.keyCode) { + case 80: + PDFViewerApplication.requestPresentationMode(); + handled = true; + PDFViewerApplication.externalServices.reportTelemetry({ + type: "buttons", + data: { + id: "presentationModeKeyboard" + } + }); + break; + case 71: + if (PDFViewerApplication.appConfig.toolbar) { + PDFViewerApplication.appConfig.toolbar.pageNumber.select(); + handled = true; + } + break; + } + } + if (handled) { + if (ensureViewerFocused && !isViewerInPresentationMode) { + pdfViewer.focus(); + } + evt.preventDefault(); + return; + } + const curElement = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.getActiveOrFocusedElement)(); + const curElementTagName = curElement?.tagName.toUpperCase(); + if (curElementTagName === "INPUT" || curElementTagName === "TEXTAREA" || curElementTagName === "SELECT" || curElementTagName === "BUTTON" && (evt.keyCode === 13 || evt.keyCode === 32) || curElement?.isContentEditable) { + if (evt.keyCode !== 27) { + return; + } + } + if (cmd === 0) { + let turnPage = 0, + turnOnlyIfPageFit = false; + switch (evt.keyCode) { + case 38: + case 33: + if (pdfViewer.isVerticalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + turnPage = -1; + break; + case 8: + if (!isViewerInPresentationMode) { + turnOnlyIfPageFit = true; + } + turnPage = -1; + break; + case 37: + if (pdfViewer.isHorizontalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + case 75: + case 80: + turnPage = -1; + break; + case 27: + if (PDFViewerApplication.secondaryToolbar?.isOpen) { + PDFViewerApplication.secondaryToolbar.close(); + handled = true; + } + if (!PDFViewerApplication.supportsIntegratedFind && PDFViewerApplication.findBar?.opened) { + PDFViewerApplication.findBar.close(); + handled = true; + } + break; + case 40: + case 34: + if (pdfViewer.isVerticalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + turnPage = 1; + break; + case 13: + case 32: + if (!isViewerInPresentationMode) { + turnOnlyIfPageFit = true; + } + turnPage = 1; + break; + case 39: + if (pdfViewer.isHorizontalScrollbarEnabled) { + turnOnlyIfPageFit = true; + } + case 74: + case 78: + turnPage = 1; + break; + case 36: + if (isViewerInPresentationMode || PDFViewerApplication.page > 1) { + PDFViewerApplication.page = 1; + handled = true; + ensureViewerFocused = true; + } + break; + case 35: + if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) { + PDFViewerApplication.page = PDFViewerApplication.pagesCount; + handled = true; + ensureViewerFocused = true; + } + break; + case 83: + PDFViewerApplication.pdfCursorTools?.switchTool(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.SELECT); + break; + case 72: + PDFViewerApplication.pdfCursorTools?.switchTool(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.HAND); + break; + case 82: + PDFViewerApplication.rotatePages(90); + break; + case 115: + PDFViewerApplication.pdfSidebar?.toggle(); + break; + } + if (turnPage !== 0 && (!turnOnlyIfPageFit || pdfViewer.currentScaleValue === "page-fit")) { + if (turnPage > 0) { + pdfViewer.nextPage(); + } else { + pdfViewer.previousPage(); + } + handled = true; + } + } + if (cmd === 4) { + switch (evt.keyCode) { + case 13: + case 32: + if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== "page-fit") { + break; + } + pdfViewer.previousPage(); + handled = true; + break; + case 82: + PDFViewerApplication.rotatePages(-90); + break; + } + } + if (!handled && !isViewerInPresentationMode) { + if (evt.keyCode >= 33 && evt.keyCode <= 40 || evt.keyCode === 32 && curElementTagName !== "BUTTON") { + ensureViewerFocused = true; + } + } + if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) { + pdfViewer.focus(); + } + if (handled) { + evt.preventDefault(); + } +} +function beforeUnload(evt) { + evt.preventDefault(); + evt.returnValue = ""; + return false; +} +function webViewerAnnotationEditorStatesChanged(data) { + PDFViewerApplication.externalServices.updateEditorStates(data); +} +function webViewerReportTelemetry({ + details +}) { + PDFViewerApplication.externalServices.reportTelemetry(details); +} +const PDFPrintServiceFactory = { + instance: { + supportsPrinting: false, + createPrintService() { + throw new Error("Not implemented: createPrintService"); + } + } +}; + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 8961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AppOptions: () => (/* binding */ AppOptions), +/* harmony export */ OptionKind: () => (/* binding */ OptionKind), +/* harmony export */ compatibilityParams: () => (/* binding */ compatibilityParams) +/* harmony export */ }); +const compatibilityParams = Object.create(null); +{ + const userAgent = navigator.userAgent || ""; + const platform = navigator.platform || ""; + const maxTouchPoints = navigator.maxTouchPoints || 1; + const isAndroid = /Android/.test(userAgent); + const isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) || platform === "MacIntel" && maxTouchPoints > 1; + (function checkCanvasSizeLimitation() { + if (isIOS || isAndroid) { + compatibilityParams.maxCanvasPixels = 5242880; + } + })(); +} +const OptionKind = { + BROWSER: 0x01, + VIEWER: 0x02, + API: 0x04, + WORKER: 0x08, + PREFERENCE: 0x80 +}; +const defaultOptions = { + canvasMaxAreaInBytes: { + value: -1, + kind: OptionKind.BROWSER + OptionKind.API + }, + isInAutomation: { + value: false, + kind: OptionKind.BROWSER + }, + supportsDocumentFonts: { + value: true, + kind: OptionKind.BROWSER + }, + supportsIntegratedFind: { + value: false, + kind: OptionKind.BROWSER + }, + supportsMouseWheelZoomCtrlKey: { + value: true, + kind: OptionKind.BROWSER + }, + supportsMouseWheelZoomMetaKey: { + value: true, + kind: OptionKind.BROWSER + }, + supportsPinchToZoom: { + value: true, + kind: OptionKind.BROWSER + }, + annotationEditorMode: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + annotationMode: { + value: 2, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + cursorToolOnLoad: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + defaultZoomDelay: { + value: 400, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + defaultZoomValue: { + value: "", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + disableHistory: { + value: false, + kind: OptionKind.VIEWER + }, + disablePageLabels: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableHighlightEditor: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enablePermissions: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enablePrintAutoRotate: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + enableScripting: { + value: true, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + externalLinkRel: { + value: "noopener noreferrer nofollow", + kind: OptionKind.VIEWER + }, + externalLinkTarget: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + highlightEditorColors: { + value: "yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + historyUpdateUrl: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + ignoreDestinationZoom: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + imageResourcesPath: { + value: "./images/", + kind: OptionKind.VIEWER + }, + maxCanvasPixels: { + value: 16777216, + kind: OptionKind.VIEWER + }, + forcePageColors: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + pageColorsBackground: { + value: "Canvas", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + pageColorsForeground: { + value: "CanvasText", + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + pdfBugEnabled: { + value: false, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + printResolution: { + value: 150, + kind: OptionKind.VIEWER + }, + sidebarViewOnLoad: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + scrollModeOnLoad: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + spreadModeOnLoad: { + value: -1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + textLayerMode: { + value: 1, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + viewOnLoad: { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }, + cMapPacked: { + value: true, + kind: OptionKind.API + }, + cMapUrl: { + value: "../web/cmaps/", + kind: OptionKind.API + }, + disableAutoFetch: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + disableFontFace: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + disableRange: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + disableStream: { + value: false, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + docBaseUrl: { + value: "", + kind: OptionKind.API + }, + enableXfa: { + value: true, + kind: OptionKind.API + OptionKind.PREFERENCE + }, + fontExtraProperties: { + value: false, + kind: OptionKind.API + }, + isEvalSupported: { + value: true, + kind: OptionKind.API + }, + isOffscreenCanvasSupported: { + value: true, + kind: OptionKind.API + }, + maxImageSize: { + value: -1, + kind: OptionKind.API + }, + pdfBug: { + value: false, + kind: OptionKind.API + }, + standardFontDataUrl: { + value: "../web/standard_fonts/", + kind: OptionKind.API + }, + verbosity: { + value: 1, + kind: OptionKind.API + }, + workerPort: { + value: null, + kind: OptionKind.WORKER + }, + workerSrc: { + value: "../build/pdf.worker.mjs", + kind: OptionKind.WORKER + } +}; +{ + defaultOptions.defaultUrl = { + value: "compressed.tracemonkey-pldi-09.pdf", + kind: OptionKind.VIEWER + }; + defaultOptions.sandboxBundleSrc = { + value: "../build/pdf.sandbox.mjs", + kind: OptionKind.VIEWER + }; + defaultOptions.viewerCssTheme = { + value: 0, + kind: OptionKind.VIEWER + OptionKind.PREFERENCE + }; +} +{ + defaultOptions.disablePreferences = { + value: false, + kind: OptionKind.VIEWER + }; + defaultOptions.locale = { + value: navigator.language || "en-US", + kind: OptionKind.VIEWER + }; +} +const userOptions = Object.create(null); +class AppOptions { + constructor() { + throw new Error("Cannot initialize AppOptions."); + } + static get(name) { + const userOption = userOptions[name]; + if (userOption !== undefined) { + return userOption; + } + const defaultOption = defaultOptions[name]; + if (defaultOption !== undefined) { + return compatibilityParams[name] ?? defaultOption.value; + } + return undefined; + } + static getAll(kind = null) { + const options = Object.create(null); + for (const name in defaultOptions) { + const defaultOption = defaultOptions[name]; + if (kind) { + if (!(kind & defaultOption.kind)) { + continue; + } + } + const userOption = userOptions[name]; + options[name] = userOption !== undefined ? userOption : compatibilityParams[name] ?? defaultOption.value; + } + return options; + } + static set(name, value) { + userOptions[name] = value; + } + static setAll(options, init = false) { + if (init) { + if (this.get("disablePreferences")) { + return; + } + if (Object.keys(userOptions).length) { + console.warn("setAll: The Preferences may override manually set AppOptions; " + 'please use the "disablePreferences"-option in order to prevent that.'); + } + } + for (const name in options) { + userOptions[name] = options[name]; + } + } + static remove(name) { + delete userOptions[name]; + } +} + + +/***/ }), + +/***/ 9415: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ BaseTreeViewer: () => (/* binding */ BaseTreeViewer) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); + +const TREEITEM_OFFSET_TOP = -100; +const TREEITEM_SELECTED_CLASS = "selected"; +class BaseTreeViewer { + constructor(options) { + if (this.constructor === BaseTreeViewer) { + throw new Error("Cannot initialize BaseTreeViewer."); + } + this.container = options.container; + this.eventBus = options.eventBus; + this._l10n = options.l10n; + this.reset(); + } + reset() { + this._pdfDocument = null; + this._lastToggleIsShow = true; + this._currentTreeItem = null; + this.container.textContent = ""; + this.container.classList.remove("treeWithDeepNesting"); + } + _dispatchEvent(count) { + throw new Error("Not implemented: _dispatchEvent"); + } + _bindLink(element, params) { + throw new Error("Not implemented: _bindLink"); + } + _normalizeTextContent(str) { + return (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeNullCharacters)(str, true) || "\u2013"; + } + _addToggleButton(div, hidden = false) { + const toggler = document.createElement("div"); + toggler.className = "treeItemToggler"; + if (hidden) { + toggler.classList.add("treeItemsHidden"); + } + toggler.onclick = evt => { + evt.stopPropagation(); + toggler.classList.toggle("treeItemsHidden"); + if (evt.shiftKey) { + const shouldShowAll = !toggler.classList.contains("treeItemsHidden"); + this._toggleTreeItem(div, shouldShowAll); + } + }; + div.prepend(toggler); + } + _toggleTreeItem(root, show = false) { + this._l10n.pause(); + this._lastToggleIsShow = show; + for (const toggler of root.querySelectorAll(".treeItemToggler")) { + toggler.classList.toggle("treeItemsHidden", !show); + } + this._l10n.resume(); + } + _toggleAllTreeItems() { + this._toggleTreeItem(this.container, !this._lastToggleIsShow); + } + _finishRendering(fragment, count, hasAnyNesting = false) { + if (hasAnyNesting) { + this.container.classList.add("treeWithDeepNesting"); + this._lastToggleIsShow = !fragment.querySelector(".treeItemsHidden"); + } + this._l10n.pause(); + this.container.append(fragment); + this._l10n.resume(); + this._dispatchEvent(count); + } + render(params) { + throw new Error("Not implemented: render"); + } + _updateCurrentTreeItem(treeItem = null) { + if (this._currentTreeItem) { + this._currentTreeItem.classList.remove(TREEITEM_SELECTED_CLASS); + this._currentTreeItem = null; + } + if (treeItem) { + treeItem.classList.add(TREEITEM_SELECTED_CLASS); + this._currentTreeItem = treeItem; + } + } + _scrollToCurrentTreeItem(treeItem) { + if (!treeItem) { + return; + } + this._l10n.pause(); + let currentNode = treeItem.parentNode; + while (currentNode && currentNode !== this.container) { + if (currentNode.classList.contains("treeItem")) { + const toggler = currentNode.firstElementChild; + toggler?.classList.remove("treeItemsHidden"); + } + currentNode = currentNode.parentNode; + } + this._l10n.resume(); + this._updateCurrentTreeItem(treeItem); + this.container.scrollTo(treeItem.offsetLeft, treeItem.offsetTop + TREEITEM_OFFSET_TOP); + } +} + + +/***/ }), + +/***/ 4397: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ DownloadManager: () => (/* binding */ DownloadManager) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +; +function download(blobUrl, filename) { + const a = document.createElement("a"); + if (!a.click) { + throw new Error('DownloadManager: "a.click()" is not supported.'); + } + a.href = blobUrl; + a.target = "_parent"; + if ("download" in a) { + a.download = filename; + } + (document.body || document.documentElement).append(a); + a.click(); + a.remove(); +} +class DownloadManager { + #openBlobUrls = new WeakMap(); + downloadUrl(url, filename, _options) { + if (!(0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.createValidAbsoluteUrl)(url, "http://example.com")) { + console.error(`downloadUrl - not a valid URL: ${url}`); + return; + } + download(url + "#pdfjs.action=download", filename); + } + downloadData(data, filename, contentType) { + const blobUrl = URL.createObjectURL(new Blob([data], { + type: contentType + })); + download(blobUrl, filename); + } + openOrDownloadData(data, filename, dest = null) { + const isPdfData = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.isPdfFile)(filename); + const contentType = isPdfData ? "application/pdf" : ""; + if (isPdfData) { + let blobUrl = this.#openBlobUrls.get(data); + if (!blobUrl) { + blobUrl = URL.createObjectURL(new Blob([data], { + type: contentType + })); + this.#openBlobUrls.set(data, blobUrl); + } + let viewerUrl; + viewerUrl = "?file=" + encodeURIComponent(blobUrl + "#" + filename); + if (dest) { + viewerUrl += `#${escape(dest)}`; + } + try { + window.open(viewerUrl); + return true; + } catch (ex) { + console.error(`openOrDownloadData: ${ex}`); + URL.revokeObjectURL(blobUrl); + this.#openBlobUrls.delete(data); + } + } + this.downloadData(data, filename, contentType); + return false; + } + download(blob, url, filename, _options) { + const blobUrl = URL.createObjectURL(blob); + download(blobUrl, filename); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 758: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ DrawLayerBuilder: () => (/* binding */ DrawLayerBuilder) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +class DrawLayerBuilder { + #drawLayer = null; + constructor(options) { + this.pageIndex = options.pageIndex; + } + async render(intent = "display") { + if (intent !== "display" || this.#drawLayer || this._cancelled) { + return; + } + this.#drawLayer = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.DrawLayer({ + pageIndex: this.pageIndex + }); + } + cancel() { + this._cancelled = true; + if (!this.#drawLayer) { + return; + } + this.#drawLayer.destroy(); + this.#drawLayer = null; + } + setParent(parent) { + this.#drawLayer?.setParent(parent); + } + getDrawLayer() { + return this.#drawLayer; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 6554: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AutomationEventBus: () => (/* binding */ AutomationEventBus), +/* harmony export */ EventBus: () => (/* binding */ EventBus), +/* harmony export */ waitOnEventOrTimeout: () => (/* binding */ waitOnEventOrTimeout) +/* harmony export */ }); +/* unused harmony export WaitOnType */ +const WaitOnType = { + EVENT: "event", + TIMEOUT: "timeout" +}; +function waitOnEventOrTimeout({ + target, + name, + delay = 0 +}) { + return new Promise(function (resolve, reject) { + if (typeof target !== "object" || !(name && typeof name === "string") || !(Number.isInteger(delay) && delay >= 0)) { + throw new Error("waitOnEventOrTimeout - invalid parameters."); + } + function handler(type) { + if (target instanceof EventBus) { + target._off(name, eventHandler); + } else { + target.removeEventListener(name, eventHandler); + } + if (timeout) { + clearTimeout(timeout); + } + resolve(type); + } + const eventHandler = handler.bind(null, WaitOnType.EVENT); + if (target instanceof EventBus) { + target._on(name, eventHandler); + } else { + target.addEventListener(name, eventHandler); + } + const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT); + const timeout = setTimeout(timeoutHandler, delay); + }); +} +class EventBus { + #listeners = Object.create(null); + on(eventName, listener, options = null) { + this._on(eventName, listener, { + external: true, + once: options?.once + }); + } + off(eventName, listener, options = null) { + this._off(eventName, listener, { + external: true, + once: options?.once + }); + } + dispatch(eventName, data) { + const eventListeners = this.#listeners[eventName]; + if (!eventListeners || eventListeners.length === 0) { + return; + } + let externalListeners; + for (const { + listener, + external, + once + } of eventListeners.slice(0)) { + if (once) { + this._off(eventName, listener); + } + if (external) { + (externalListeners ||= []).push(listener); + continue; + } + listener(data); + } + if (externalListeners) { + for (const listener of externalListeners) { + listener(data); + } + externalListeners = null; + } + } + _on(eventName, listener, options = null) { + const eventListeners = this.#listeners[eventName] ||= []; + eventListeners.push({ + listener, + external: options?.external === true, + once: options?.once === true + }); + } + _off(eventName, listener, options = null) { + const eventListeners = this.#listeners[eventName]; + if (!eventListeners) { + return; + } + for (let i = 0, ii = eventListeners.length; i < ii; i++) { + if (eventListeners[i].listener === listener) { + eventListeners.splice(i, 1); + return; + } + } + } +} +class AutomationEventBus extends EventBus { + dispatch(eventName, data) { + throw new Error("Not implemented: AutomationEventBus.dispatch"); + } +} + + +/***/ }), + +/***/ 9170: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GenericScripting: () => (/* binding */ GenericScripting) +/* harmony export */ }); +/* unused harmony export docProperties */ +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +async function docProperties(pdfDocument) { + const url = "", + baseUrl = url.split("#")[0]; + let { + info, + metadata, + contentDispositionFilename, + contentLength + } = await pdfDocument.getMetadata(); + if (!contentLength) { + const { + length + } = await pdfDocument.getDownloadInfo(); + contentLength = length; + } + return { + ...info, + baseURL: baseUrl, + filesize: contentLength, + filename: contentDispositionFilename || getPdfFilenameFromUrl(url), + metadata: metadata?.getRaw(), + authors: metadata?.get("dc:creator"), + numPages: pdfDocument.numPages, + URL: url + }; +} +class GenericScripting { + constructor(sandboxBundleSrc) { + this._ready = new Promise((resolve, reject) => { + const sandbox = import(/* webpackIgnore: true */ sandboxBundleSrc); + sandbox.then(pdfjsSandbox => { + resolve(pdfjsSandbox.QuickJSSandbox()); + }).catch(reject); + }); + } + async createSandbox(data) { + const sandbox = await this._ready; + sandbox.create(data); + } + async dispatchEventInSandbox(event) { + const sandbox = await this._ready; + setTimeout(() => sandbox.dispatchEvent(event), 0); + } + async destroySandbox() { + const sandbox = await this._ready; + sandbox.nukeSandbox(); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1546: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* unused harmony export GenericCom */ +/* harmony import */ var _app_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(39); +/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8961); +/* harmony import */ var _preferences_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(216); +/* harmony import */ var _download_manager_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4397); +/* harmony import */ var _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(450); +/* harmony import */ var _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9170); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_app_js__WEBPACK_IMPORTED_MODULE_0__, _download_manager_js__WEBPACK_IMPORTED_MODULE_3__, _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__, _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__]); +([_app_js__WEBPACK_IMPORTED_MODULE_0__, _download_manager_js__WEBPACK_IMPORTED_MODULE_3__, _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__, _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + + + + +; +const GenericCom = {}; +class GenericPreferences extends _preferences_js__WEBPACK_IMPORTED_MODULE_2__.BasePreferences { + async _writeToStorage(prefObj) { + localStorage.setItem("pdfjs.preferences", JSON.stringify(prefObj)); + } + async _readFromStorage(prefObj) { + return { + prefs: JSON.parse(localStorage.getItem("pdfjs.preferences")) + }; + } +} +class GenericExternalServices extends _app_js__WEBPACK_IMPORTED_MODULE_0__.DefaultExternalServices { + static createDownloadManager() { + return new _download_manager_js__WEBPACK_IMPORTED_MODULE_3__.DownloadManager(); + } + static createPreferences() { + return new GenericPreferences(); + } + static async createL10n() { + return new _genericl10n_js__WEBPACK_IMPORTED_MODULE_4__.GenericL10n(_app_options_js__WEBPACK_IMPORTED_MODULE_1__.AppOptions.get("locale")); + } + static createScripting() { + return new _generic_scripting_js__WEBPACK_IMPORTED_MODULE_5__.GenericScripting(_app_options_js__WEBPACK_IMPORTED_MODULE_1__.AppOptions.get("sandboxBundleSrc")); + } +} +_app_js__WEBPACK_IMPORTED_MODULE_0__.PDFViewerApplication.externalServices = GenericExternalServices; + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 450: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GenericL10n: () => (/* binding */ GenericL10n) +/* harmony export */ }); +/* harmony import */ var fluent_bundle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8759); +/* harmony import */ var fluent_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8275); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1869); +/* harmony import */ var _l10n_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4065); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + + + +class GenericL10n extends _l10n_js__WEBPACK_IMPORTED_MODULE_3__.L10n { + constructor(lang) { + super({ + lang + }); + this._setL10n(new fluent_dom__WEBPACK_IMPORTED_MODULE_1__.DOMLocalization([], GenericL10n.#generateBundles.bind(GenericL10n, "en-us", this.getLanguage()))); + } + static async *#generateBundles(defaultLang, baseLang) { + const { + baseURL, + paths + } = await this.#getPaths(); + const langs = [baseLang]; + if (defaultLang !== baseLang) { + const shortLang = baseLang.split("-", 1)[0]; + if (shortLang !== baseLang) { + langs.push(shortLang); + } + langs.push(defaultLang); + } + for (const lang of langs) { + const bundle = await this.#createBundle(lang, baseURL, paths); + if (bundle) { + yield bundle; + } + } + } + static async #createBundle(lang, baseURL, paths) { + const path = paths[lang]; + if (!path) { + return null; + } + const url = new URL(path, baseURL); + const text = await (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.fetchData)(url, "text"); + const resource = new fluent_bundle__WEBPACK_IMPORTED_MODULE_0__.FluentResource(text); + const bundle = new fluent_bundle__WEBPACK_IMPORTED_MODULE_0__.FluentBundle(lang); + const errors = bundle.addResource(resource); + if (errors.length) { + console.error("L10n errors", errors); + } + return bundle; + } + static async #getPaths() { + const { + href + } = document.querySelector(`link[type="application/l10n"]`); + const paths = await (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.fetchData)(href, "json"); + return { + baseURL: href.replace(/[^/]*$/, "") || "./", + paths + }; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 6143: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ GrabToPan: () => (/* binding */ GrabToPan) +/* harmony export */ }); +const CSS_CLASS_GRAB = "grab-to-pan-grab"; +class GrabToPan { + constructor({ + element + }) { + this.element = element; + this.document = element.ownerDocument; + this.activate = this.activate.bind(this); + this.deactivate = this.deactivate.bind(this); + this.toggle = this.toggle.bind(this); + this._onMouseDown = this.#onMouseDown.bind(this); + this._onMouseMove = this.#onMouseMove.bind(this); + this._endPan = this.#endPan.bind(this); + const overlay = this.overlay = document.createElement("div"); + overlay.className = "grab-to-pan-grabbing"; + } + activate() { + if (!this.active) { + this.active = true; + this.element.addEventListener("mousedown", this._onMouseDown, true); + this.element.classList.add(CSS_CLASS_GRAB); + } + } + deactivate() { + if (this.active) { + this.active = false; + this.element.removeEventListener("mousedown", this._onMouseDown, true); + this._endPan(); + this.element.classList.remove(CSS_CLASS_GRAB); + } + } + toggle() { + if (this.active) { + this.deactivate(); + } else { + this.activate(); + } + } + ignoreTarget(node) { + return node.matches("a[href], a[href] *, input, textarea, button, button *, select, option"); + } + #onMouseDown(event) { + if (event.button !== 0 || this.ignoreTarget(event.target)) { + return; + } + if (event.originalTarget) { + try { + event.originalTarget.tagName; + } catch { + return; + } + } + this.scrollLeftStart = this.element.scrollLeft; + this.scrollTopStart = this.element.scrollTop; + this.clientXStart = event.clientX; + this.clientYStart = event.clientY; + this.document.addEventListener("mousemove", this._onMouseMove, true); + this.document.addEventListener("mouseup", this._endPan, true); + this.element.addEventListener("scroll", this._endPan, true); + event.preventDefault(); + event.stopPropagation(); + const focusedElement = document.activeElement; + if (focusedElement && !focusedElement.contains(event.target)) { + focusedElement.blur(); + } + } + #onMouseMove(event) { + this.element.removeEventListener("scroll", this._endPan, true); + if (!(event.buttons & 1)) { + this._endPan(); + return; + } + const xDiff = event.clientX - this.clientXStart; + const yDiff = event.clientY - this.clientYStart; + this.element.scrollTo({ + top: this.scrollTopStart - yDiff, + left: this.scrollLeftStart - xDiff, + behavior: "instant" + }); + if (!this.overlay.parentNode) { + document.body.append(this.overlay); + } + } + #endPan() { + this.element.removeEventListener("scroll", this._endPan, true); + this.document.removeEventListener("mousemove", this._onMouseMove, true); + this.document.removeEventListener("mouseup", this._endPan, true); + this.overlay.remove(); + } +} + + +/***/ }), + +/***/ 4065: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ L10n: () => (/* binding */ L10n) +/* harmony export */ }); +class L10n { + #dir; + #lang; + #l10n; + constructor({ + lang, + isRTL + }, l10n = null) { + this.#lang = L10n.#fixupLangCode(lang); + this.#l10n = l10n; + this.#dir = isRTL ?? L10n.#isRTL(this.#lang) ? "rtl" : "ltr"; + } + _setL10n(l10n) { + this.#l10n = l10n; + } + getLanguage() { + return this.#lang; + } + getDirection() { + return this.#dir; + } + async get(ids, args = null, fallback) { + if (Array.isArray(ids)) { + ids = ids.map(id => ({ + id + })); + const messages = await this.#l10n.formatMessages(ids); + return messages.map(message => message.value); + } + const messages = await this.#l10n.formatMessages([{ + id: ids, + args + }]); + return messages?.[0].value || fallback; + } + async translate(element) { + try { + this.#l10n.connectRoot(element); + await this.#l10n.translateRoots(); + } catch {} + } + pause() { + this.#l10n.pauseObserving(); + } + resume() { + this.#l10n.resumeObserving(); + } + static #fixupLangCode(langCode) { + langCode = langCode?.toLowerCase() || "en-us"; + const PARTIAL_LANG_CODES = { + en: "en-us", + es: "es-es", + fy: "fy-nl", + ga: "ga-ie", + gu: "gu-in", + hi: "hi-in", + hy: "hy-am", + nb: "nb-no", + ne: "ne-np", + nn: "nn-no", + pa: "pa-in", + pt: "pt-pt", + sv: "sv-se", + zh: "zh-cn" + }; + return PARTIAL_LANG_CODES[langCode] || langCode; + } + static #isRTL(lang) { + const shortCode = lang.split("-", 1)[0]; + return ["ar", "he", "fa", "ps", "ur"].includes(shortCode); + } +} + + +/***/ }), + +/***/ 7910: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ NullL10n: () => (/* binding */ NullL10n) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var fluent_bundle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8759); +/* harmony import */ var fluent_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8275); +/* harmony import */ var _l10n_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4065); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + + + +class ConstL10n extends _l10n_js__WEBPACK_IMPORTED_MODULE_3__.L10n { + constructor(lang) { + super({ + lang + }); + this._setL10n(new fluent_dom__WEBPACK_IMPORTED_MODULE_2__.DOMLocalization([], ConstL10n.#generateBundles.bind(ConstL10n, lang))); + } + static async *#generateBundles(lang) { + const text = 'pdfjs-previous-button =\n .title = Previous Page\npdfjs-previous-button-label = Previous\npdfjs-next-button =\n .title = Next Page\npdfjs-next-button-label = Next\npdfjs-page-input =\n .title = Page\npdfjs-of-pages = of { $pagesCount }\npdfjs-page-of-pages = ({ $pageNumber } of { $pagesCount })\npdfjs-zoom-out-button =\n .title = Zoom Out\npdfjs-zoom-out-button-label = Zoom Out\npdfjs-zoom-in-button =\n .title = Zoom In\npdfjs-zoom-in-button-label = Zoom In\npdfjs-zoom-select =\n .title = Zoom\npdfjs-presentation-mode-button =\n .title = Switch to Presentation Mode\npdfjs-presentation-mode-button-label = Presentation Mode\npdfjs-open-file-button =\n .title = Open File\npdfjs-open-file-button-label = Open\npdfjs-print-button =\n .title = Print\npdfjs-print-button-label = Print\npdfjs-save-button =\n .title = Save\npdfjs-save-button-label = Save\npdfjs-download-button =\n .title = Download\npdfjs-download-button-label = Download\npdfjs-bookmark-button =\n .title = Current Page (View URL from Current Page)\npdfjs-bookmark-button-label = Current Page\npdfjs-open-in-app-button =\n .title = Open in app\npdfjs-open-in-app-button-label = Open in app\npdfjs-tools-button =\n .title = Tools\npdfjs-tools-button-label = Tools\npdfjs-first-page-button =\n .title = Go to First Page\npdfjs-first-page-button-label = Go to First Page\npdfjs-last-page-button =\n .title = Go to Last Page\npdfjs-last-page-button-label = Go to Last Page\npdfjs-page-rotate-cw-button =\n .title = Rotate Clockwise\npdfjs-page-rotate-cw-button-label = Rotate Clockwise\npdfjs-page-rotate-ccw-button =\n .title = Rotate Counterclockwise\npdfjs-page-rotate-ccw-button-label = Rotate Counterclockwise\npdfjs-cursor-text-select-tool-button =\n .title = Enable Text Selection Tool\npdfjs-cursor-text-select-tool-button-label = Text Selection Tool\npdfjs-cursor-hand-tool-button =\n .title = Enable Hand Tool\npdfjs-cursor-hand-tool-button-label = Hand Tool\npdfjs-scroll-page-button =\n .title = Use Page Scrolling\npdfjs-scroll-page-button-label = Page Scrolling\npdfjs-scroll-vertical-button =\n .title = Use Vertical Scrolling\npdfjs-scroll-vertical-button-label = Vertical Scrolling\npdfjs-scroll-horizontal-button =\n .title = Use Horizontal Scrolling\npdfjs-scroll-horizontal-button-label = Horizontal Scrolling\npdfjs-scroll-wrapped-button =\n .title = Use Wrapped Scrolling\npdfjs-scroll-wrapped-button-label = Wrapped Scrolling\npdfjs-spread-none-button =\n .title = Do not join page spreads\npdfjs-spread-none-button-label = No Spreads\npdfjs-spread-odd-button =\n .title = Join page spreads starting with odd-numbered pages\npdfjs-spread-odd-button-label = Odd Spreads\npdfjs-spread-even-button =\n .title = Join page spreads starting with even-numbered pages\npdfjs-spread-even-button-label = Even Spreads\npdfjs-document-properties-button =\n .title = Document Properties\u2026\npdfjs-document-properties-button-label = Document Properties\u2026\npdfjs-document-properties-file-name = File name:\npdfjs-document-properties-file-size = File size:\npdfjs-document-properties-kb = { $size_kb } KB ({ $size_b } bytes)\npdfjs-document-properties-mb = { $size_mb } MB ({ $size_b } bytes)\npdfjs-document-properties-title = Title:\npdfjs-document-properties-author = Author:\npdfjs-document-properties-subject = Subject:\npdfjs-document-properties-keywords = Keywords:\npdfjs-document-properties-creation-date = Creation Date:\npdfjs-document-properties-modification-date = Modification Date:\npdfjs-document-properties-date-string = { $date }, { $time }\npdfjs-document-properties-creator = Creator:\npdfjs-document-properties-producer = PDF Producer:\npdfjs-document-properties-version = PDF Version:\npdfjs-document-properties-page-count = Page Count:\npdfjs-document-properties-page-size = Page Size:\npdfjs-document-properties-page-size-unit-inches = in\npdfjs-document-properties-page-size-unit-millimeters = mm\npdfjs-document-properties-page-size-orientation-portrait = portrait\npdfjs-document-properties-page-size-orientation-landscape = landscape\npdfjs-document-properties-page-size-name-a-three = A3\npdfjs-document-properties-page-size-name-a-four = A4\npdfjs-document-properties-page-size-name-letter = Letter\npdfjs-document-properties-page-size-name-legal = Legal\npdfjs-document-properties-page-size-dimension-string = { $width } \xD7 { $height } { $unit } ({ $orientation })\npdfjs-document-properties-page-size-dimension-name-string = { $width } \xD7 { $height } { $unit } ({ $name }, { $orientation })\npdfjs-document-properties-linearized = Fast Web View:\npdfjs-document-properties-linearized-yes = Yes\npdfjs-document-properties-linearized-no = No\npdfjs-document-properties-close-button = Close\npdfjs-print-progress-message = Preparing document for printing\u2026\npdfjs-print-progress-percent = { $progress }%\npdfjs-print-progress-close-button = Cancel\npdfjs-printing-not-supported = Warning: Printing is not fully supported by this browser.\npdfjs-printing-not-ready = Warning: The PDF is not fully loaded for printing.\npdfjs-toggle-sidebar-button =\n .title = Toggle Sidebar\npdfjs-toggle-sidebar-notification-button =\n .title = Toggle Sidebar (document contains outline/attachments/layers)\npdfjs-toggle-sidebar-button-label = Toggle Sidebar\npdfjs-document-outline-button =\n .title = Show Document Outline (double-click to expand/collapse all items)\npdfjs-document-outline-button-label = Document Outline\npdfjs-attachments-button =\n .title = Show Attachments\npdfjs-attachments-button-label = Attachments\npdfjs-layers-button =\n .title = Show Layers (double-click to reset all layers to the default state)\npdfjs-layers-button-label = Layers\npdfjs-thumbs-button =\n .title = Show Thumbnails\npdfjs-thumbs-button-label = Thumbnails\npdfjs-current-outline-item-button =\n .title = Find Current Outline Item\npdfjs-current-outline-item-button-label = Current Outline Item\npdfjs-findbar-button =\n .title = Find in Document\npdfjs-findbar-button-label = Find\npdfjs-additional-layers = Additional Layers\npdfjs-thumb-page-title =\n .title = Page { $page }\npdfjs-thumb-page-canvas =\n .aria-label = Thumbnail of Page { $page }\npdfjs-find-input =\n .title = Find\n .placeholder = Find in document\u2026\npdfjs-find-previous-button =\n .title = Find the previous occurrence of the phrase\npdfjs-find-previous-button-label = Previous\npdfjs-find-next-button =\n .title = Find the next occurrence of the phrase\npdfjs-find-next-button-label = Next\npdfjs-find-highlight-checkbox = Highlight All\npdfjs-find-match-case-checkbox-label = Match Case\npdfjs-find-match-diacritics-checkbox-label = Match Diacritics\npdfjs-find-entire-word-checkbox-label = Whole Words\npdfjs-find-reached-top = Reached top of document, continued from bottom\npdfjs-find-reached-bottom = Reached end of document, continued from top\npdfjs-find-match-count =\n { $total ->\n [one] { $current } of { $total } match\n *[other] { $current } of { $total } matches\n }\npdfjs-find-match-count-limit =\n { $limit ->\n [one] More than { $limit } match\n *[other] More than { $limit } matches\n }\npdfjs-find-not-found = Phrase not found\npdfjs-page-scale-width = Page Width\npdfjs-page-scale-fit = Page Fit\npdfjs-page-scale-auto = Automatic Zoom\npdfjs-page-scale-actual = Actual Size\npdfjs-page-scale-percent = { $scale }%\npdfjs-page-landmark =\n .aria-label = Page { $page }\npdfjs-loading-error = An error occurred while loading the PDF.\npdfjs-invalid-file-error = Invalid or corrupted PDF file.\npdfjs-missing-file-error = Missing PDF file.\npdfjs-unexpected-response-error = Unexpected server response.\npdfjs-rendering-error = An error occurred while rendering the page.\npdfjs-annotation-date-string = { $date }, { $time }\npdfjs-text-annotation-type =\n .alt = [{ $type } Annotation]\npdfjs-password-label = Enter the password to open this PDF file.\npdfjs-password-invalid = Invalid password. Please try again.\npdfjs-password-ok-button = OK\npdfjs-password-cancel-button = Cancel\npdfjs-web-fonts-disabled = Web fonts are disabled: unable to use embedded PDF fonts.\npdfjs-editor-free-text-button =\n .title = Text\npdfjs-editor-free-text-button-label = Text\npdfjs-editor-ink-button =\n .title = Draw\npdfjs-editor-ink-button-label = Draw\npdfjs-editor-stamp-button =\n .title = Add or edit images\npdfjs-editor-stamp-button-label = Add or edit images\npdfjs-editor-highlight-button =\n .title = Highlight\npdfjs-editor-highlight-button-label = Highlight\npdfjs-editor-remove-ink-button =\n .title = Remove drawing\npdfjs-editor-remove-freetext-button =\n .title = Remove text\npdfjs-editor-remove-stamp-button =\n .title = Remove image\npdfjs-editor-remove-highlight-button =\n .title = Remove highlight\npdfjs-editor-free-text-color-input = Color\npdfjs-editor-free-text-size-input = Size\npdfjs-editor-ink-color-input = Color\npdfjs-editor-ink-thickness-input = Thickness\npdfjs-editor-ink-opacity-input = Opacity\npdfjs-editor-stamp-add-image-button =\n .title = Add image\npdfjs-editor-stamp-add-image-button-label = Add image\npdfjs-free-text =\n .aria-label = Text Editor\npdfjs-free-text-default-content = Start typing\u2026\npdfjs-ink =\n .aria-label = Draw Editor\npdfjs-ink-canvas =\n .aria-label = User-created image\npdfjs-editor-alt-text-button-label = Alt text\npdfjs-editor-alt-text-edit-button-label = Edit alt text\npdfjs-editor-alt-text-dialog-label = Choose an option\npdfjs-editor-alt-text-dialog-description = Alt text (alternative text) helps when people can\u2019t see the image or when it doesn\u2019t load.\npdfjs-editor-alt-text-add-description-label = Add a description\npdfjs-editor-alt-text-add-description-description = Aim for 1-2 sentences that describe the subject, setting, or actions.\npdfjs-editor-alt-text-mark-decorative-label = Mark as decorative\npdfjs-editor-alt-text-mark-decorative-description = This is used for ornamental images, like borders or watermarks.\npdfjs-editor-alt-text-cancel-button = Cancel\npdfjs-editor-alt-text-save-button = Save\npdfjs-editor-alt-text-decorative-tooltip = Marked as decorative\npdfjs-editor-alt-text-textarea =\n .placeholder = For example, \u201CA young man sits down at a table to eat a meal\u201D\npdfjs-editor-resizer-label-top-left = Top left corner \u2014 resize\npdfjs-editor-resizer-label-top-middle = Top middle \u2014 resize\npdfjs-editor-resizer-label-top-right = Top right corner \u2014 resize\npdfjs-editor-resizer-label-middle-right = Middle right \u2014 resize\npdfjs-editor-resizer-label-bottom-right = Bottom right corner \u2014 resize\npdfjs-editor-resizer-label-bottom-middle = Bottom middle \u2014 resize\npdfjs-editor-resizer-label-bottom-left = Bottom left corner \u2014 resize\npdfjs-editor-resizer-label-middle-left = Middle left \u2014 resize\npdfjs-editor-highlight-colorpicker-label = Highlight color\npdfjs-editor-colorpicker-button =\n .title = Change color\npdfjs-editor-colorpicker-dropdown =\n .aria-label = Color choices\npdfjs-editor-colorpicker-yellow =\n .title = Yellow\npdfjs-editor-colorpicker-green =\n .title = Green\npdfjs-editor-colorpicker-blue =\n .title = Blue\npdfjs-editor-colorpicker-pink =\n .title = Pink\npdfjs-editor-colorpicker-red =\n .title = Red'; + const resource = new fluent_bundle__WEBPACK_IMPORTED_MODULE_1__.FluentResource(text); + const bundle = new fluent_bundle__WEBPACK_IMPORTED_MODULE_1__.FluentBundle(lang); + const errors = bundle.addResource(resource); + if (errors.length) { + console.error("L10n errors", errors); + } + yield bundle; + } + static get instance() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "instance", new ConstL10n("en-us")); + } +} +const NullL10n = { + getLanguage() { + return ConstL10n.instance.getLanguage(); + }, + getDirection() { + return ConstL10n.instance.getDirection(); + }, + async get(ids, args = null, fallback) { + return ConstL10n.instance.get(ids, args, fallback); + }, + async translate(element) { + return ConstL10n.instance.translate(element); + }, + pause() { + return ConstL10n.instance.pause(); + }, + resume() { + return ConstL10n.instance.resume(); + } +}; + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1996: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ OverlayManager: () => (/* binding */ OverlayManager) +/* harmony export */ }); +class OverlayManager { + #overlays = new WeakMap(); + #active = null; + get active() { + return this.#active; + } + async register(dialog, canForceClose = false) { + if (typeof dialog !== "object") { + throw new Error("Not enough parameters."); + } else if (this.#overlays.has(dialog)) { + throw new Error("The overlay is already registered."); + } + this.#overlays.set(dialog, { + canForceClose + }); + dialog.addEventListener("cancel", evt => { + this.#active = null; + }); + } + async open(dialog) { + if (!this.#overlays.has(dialog)) { + throw new Error("The overlay does not exist."); + } else if (this.#active) { + if (this.#active === dialog) { + throw new Error("The overlay is already active."); + } else if (this.#overlays.get(dialog).canForceClose) { + await this.close(); + } else { + throw new Error("Another overlay is currently active."); + } + } + this.#active = dialog; + dialog.showModal(); + } + async close(dialog = this.#active) { + if (!this.#overlays.has(dialog)) { + throw new Error("The overlay does not exist."); + } else if (!this.#active) { + throw new Error("The overlay is currently not active."); + } else if (this.#active !== dialog) { + throw new Error("Another overlay is currently active."); + } + dialog.close(); + this.#active = null; + } +} + + +/***/ }), + +/***/ 6329: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PasswordPrompt: () => (/* binding */ PasswordPrompt) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +class PasswordPrompt { + #activeCapability = null; + #updateCallback = null; + #reason = null; + constructor(options, overlayManager, isViewerEmbedded = false) { + this.dialog = options.dialog; + this.label = options.label; + this.input = options.input; + this.submitButton = options.submitButton; + this.cancelButton = options.cancelButton; + this.overlayManager = overlayManager; + this._isViewerEmbedded = isViewerEmbedded; + this.submitButton.addEventListener("click", this.#verify.bind(this)); + this.cancelButton.addEventListener("click", this.close.bind(this)); + this.input.addEventListener("keydown", e => { + if (e.keyCode === 13) { + this.#verify(); + } + }); + this.overlayManager.register(this.dialog, true); + this.dialog.addEventListener("close", this.#cancel.bind(this)); + } + async open() { + if (this.#activeCapability) { + await this.#activeCapability.promise; + } + this.#activeCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(); + try { + await this.overlayManager.open(this.dialog); + } catch (ex) { + this.#activeCapability.resolve(); + throw ex; + } + const passwordIncorrect = this.#reason === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PasswordResponses.INCORRECT_PASSWORD; + if (!this._isViewerEmbedded || passwordIncorrect) { + this.input.focus(); + } + this.label.setAttribute("data-l10n-id", `pdfjs-password-${passwordIncorrect ? "invalid" : "label"}`); + } + async close() { + if (this.overlayManager.active === this.dialog) { + this.overlayManager.close(this.dialog); + } + } + #verify() { + const password = this.input.value; + if (password?.length > 0) { + this.#invokeCallback(password); + } + } + #cancel() { + this.#invokeCallback(new Error("PasswordPrompt cancelled.")); + this.#activeCapability.resolve(); + } + #invokeCallback(password) { + if (!this.#updateCallback) { + return; + } + this.close(); + this.input.value = ""; + this.#updateCallback(password); + this.#updateCallback = null; + } + async setUpdateCallback(updateCallback, reason) { + if (this.#activeCapability) { + await this.#activeCapability.promise; + } + this.#updateCallback = updateCallback; + this.#reason = reason; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 716: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFAttachmentViewer: () => (/* binding */ PDFAttachmentViewer) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9415); +/* harmony import */ var _event_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6554); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + + +class PDFAttachmentViewer extends _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_1__.BaseTreeViewer { + constructor(options) { + super(options); + this.downloadManager = options.downloadManager; + this.eventBus._on("fileattachmentannotation", this.#appendAttachment.bind(this)); + } + reset(keepRenderedCapability = false) { + super.reset(); + this._attachments = null; + if (!keepRenderedCapability) { + this._renderedCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(); + } + this._pendingDispatchEvent = false; + } + async _dispatchEvent(attachmentsCount) { + this._renderedCapability.resolve(); + if (attachmentsCount === 0 && !this._pendingDispatchEvent) { + this._pendingDispatchEvent = true; + await (0,_event_utils_js__WEBPACK_IMPORTED_MODULE_2__.waitOnEventOrTimeout)({ + target: this.eventBus, + name: "annotationlayerrendered", + delay: 1000 + }); + if (!this._pendingDispatchEvent) { + return; + } + } + this._pendingDispatchEvent = false; + this.eventBus.dispatch("attachmentsloaded", { + source: this, + attachmentsCount + }); + } + _bindLink(element, { + content, + filename + }) { + element.onclick = () => { + this.downloadManager.openOrDownloadData(content, filename); + return false; + }; + } + render({ + attachments, + keepRenderedCapability = false + }) { + if (this._attachments) { + this.reset(keepRenderedCapability); + } + this._attachments = attachments || null; + if (!attachments) { + this._dispatchEvent(0); + return; + } + const fragment = document.createDocumentFragment(); + let attachmentsCount = 0; + for (const name in attachments) { + const item = attachments[name]; + const content = item.content, + filename = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.getFilenameFromUrl)(item.filename, true); + const div = document.createElement("div"); + div.className = "treeItem"; + const element = document.createElement("a"); + this._bindLink(element, { + content, + filename + }); + element.textContent = this._normalizeTextContent(filename); + div.append(element); + fragment.append(div); + attachmentsCount++; + } + this._finishRendering(fragment, attachmentsCount); + } + #appendAttachment({ + filename, + content + }) { + const renderedPromise = this._renderedCapability.promise; + renderedPromise.then(() => { + if (renderedPromise !== this._renderedCapability.promise) { + return; + } + const attachments = this._attachments || Object.create(null); + for (const name in attachments) { + if (filename === name) { + return; + } + } + attachments[filename] = { + filename, + content + }; + this.render({ + attachments, + keepRenderedCapability: true + }); + }); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 3611: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFCursorTools: () => (/* binding */ PDFCursorTools) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +/* harmony import */ var _grab_to_pan_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6143); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + + +class PDFCursorTools { + #active = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT; + #prevActive = null; + constructor({ + container, + eventBus, + cursorToolOnLoad = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT + }) { + this.container = container; + this.eventBus = eventBus; + this.#addEventListeners(); + Promise.resolve().then(() => { + this.switchTool(cursorToolOnLoad); + }); + } + get activeTool() { + return this.#active; + } + switchTool(tool) { + if (this.#prevActive !== null) { + return; + } + if (tool === this.#active) { + return; + } + const disableActiveTool = () => { + switch (this.#active) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT: + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.HAND: + this._handTool.deactivate(); + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.ZOOM: + } + }; + switch (tool) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT: + disableActiveTool(); + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.HAND: + disableActiveTool(); + this._handTool.activate(); + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.ZOOM: + default: + console.error(`switchTool: "${tool}" is an unsupported value.`); + return; + } + this.#active = tool; + this.eventBus.dispatch("cursortoolchanged", { + source: this, + tool + }); + } + #addEventListeners() { + this.eventBus._on("switchcursortool", evt => { + this.switchTool(evt.tool); + }); + let annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE, + presentationModeState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL; + const disableActive = () => { + const prevActive = this.#active; + this.switchTool(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.CursorTool.SELECT); + this.#prevActive ??= prevActive; + }; + const enableActive = () => { + const prevActive = this.#prevActive; + if (prevActive !== null && annotationEditorMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE && presentationModeState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL) { + this.#prevActive = null; + this.switchTool(prevActive); + } + }; + this.eventBus._on("secondarytoolbarreset", evt => { + if (this.#prevActive !== null) { + annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE; + presentationModeState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL; + enableActive(); + } + }); + this.eventBus._on("annotationeditormodechanged", ({ + mode + }) => { + annotationEditorMode = mode; + if (mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) { + enableActive(); + } else { + disableActive(); + } + }); + this.eventBus._on("presentationmodechanged", ({ + state + }) => { + presentationModeState = state; + if (state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.NORMAL) { + enableActive(); + } else if (state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN) { + disableActive(); + } + }); + } + get _handTool() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_handTool", new _grab_to_pan_js__WEBPACK_IMPORTED_MODULE_2__.GrabToPan({ + element: this.container + })); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 6312: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFDocumentProperties: () => (/* binding */ PDFDocumentProperties) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +const DEFAULT_FIELD_CONTENT = "-"; +const NON_METRIC_LOCALES = ["en-us", "en-lr", "my"]; +const US_PAGE_NAMES = { + "8.5x11": "letter", + "8.5x14": "legal" +}; +const METRIC_PAGE_NAMES = { + "297x420": "a-three", + "210x297": "a-four" +}; +function getPageName(size, isPortrait, pageNames) { + const width = isPortrait ? size.width : size.height; + const height = isPortrait ? size.height : size.width; + return pageNames[`${width}x${height}`]; +} +class PDFDocumentProperties { + #fieldData = null; + constructor({ + dialog, + fields, + closeButton + }, overlayManager, eventBus, l10n, fileNameLookup) { + this.dialog = dialog; + this.fields = fields; + this.overlayManager = overlayManager; + this.l10n = l10n; + this._fileNameLookup = fileNameLookup; + this.#reset(); + closeButton.addEventListener("click", this.close.bind(this)); + this.overlayManager.register(this.dialog); + eventBus._on("pagechanging", evt => { + this._currentPageNumber = evt.pageNumber; + }); + eventBus._on("rotationchanging", evt => { + this._pagesRotation = evt.pagesRotation; + }); + this._isNonMetricLocale = NON_METRIC_LOCALES.includes(l10n.getLanguage()); + } + async open() { + await Promise.all([this.overlayManager.open(this.dialog), this._dataAvailableCapability.promise]); + const currentPageNumber = this._currentPageNumber; + const pagesRotation = this._pagesRotation; + if (this.#fieldData && currentPageNumber === this.#fieldData._currentPageNumber && pagesRotation === this.#fieldData._pagesRotation) { + this.#updateUI(); + return; + } + const { + info, + contentLength + } = await this.pdfDocument.getMetadata(); + const [fileName, fileSize, creationDate, modificationDate, pageSize, isLinearized] = await Promise.all([this._fileNameLookup(), this.#parseFileSize(contentLength), this.#parseDate(info.CreationDate), this.#parseDate(info.ModDate), this.pdfDocument.getPage(currentPageNumber).then(pdfPage => { + return this.#parsePageSize((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.getPageSizeInches)(pdfPage), pagesRotation); + }), this.#parseLinearization(info.IsLinearized)]); + this.#fieldData = Object.freeze({ + fileName, + fileSize, + title: info.Title, + author: info.Author, + subject: info.Subject, + keywords: info.Keywords, + creationDate, + modificationDate, + creator: info.Creator, + producer: info.Producer, + version: info.PDFFormatVersion, + pageCount: this.pdfDocument.numPages, + pageSize, + linearized: isLinearized, + _currentPageNumber: currentPageNumber, + _pagesRotation: pagesRotation + }); + this.#updateUI(); + const { + length + } = await this.pdfDocument.getDownloadInfo(); + if (contentLength === length) { + return; + } + const data = Object.assign(Object.create(null), this.#fieldData); + data.fileSize = await this.#parseFileSize(length); + this.#fieldData = Object.freeze(data); + this.#updateUI(); + } + async close() { + this.overlayManager.close(this.dialog); + } + setDocument(pdfDocument) { + if (this.pdfDocument) { + this.#reset(); + this.#updateUI(true); + } + if (!pdfDocument) { + return; + } + this.pdfDocument = pdfDocument; + this._dataAvailableCapability.resolve(); + } + #reset() { + this.pdfDocument = null; + this.#fieldData = null; + this._dataAvailableCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(); + this._currentPageNumber = 1; + this._pagesRotation = 0; + } + #updateUI(reset = false) { + if (reset || !this.#fieldData) { + for (const id in this.fields) { + this.fields[id].textContent = DEFAULT_FIELD_CONTENT; + } + return; + } + if (this.overlayManager.active !== this.dialog) { + return; + } + for (const id in this.fields) { + const content = this.#fieldData[id]; + this.fields[id].textContent = content || content === 0 ? content : DEFAULT_FIELD_CONTENT; + } + } + async #parseFileSize(fileSize = 0) { + const kb = fileSize / 1024, + mb = kb / 1024; + if (!kb) { + return undefined; + } + return this.l10n.get(`pdfjs-document-properties-${mb >= 1 ? "mb" : "kb"}`, { + size_mb: mb >= 1 && (+mb.toPrecision(3)).toLocaleString(), + size_kb: mb < 1 && (+kb.toPrecision(3)).toLocaleString(), + size_b: fileSize.toLocaleString() + }); + } + async #parsePageSize(pageSizeInches, pagesRotation) { + if (!pageSizeInches) { + return undefined; + } + if (pagesRotation % 180 !== 0) { + pageSizeInches = { + width: pageSizeInches.height, + height: pageSizeInches.width + }; + } + const isPortrait = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isPortraitOrientation)(pageSizeInches); + let sizeInches = { + width: Math.round(pageSizeInches.width * 100) / 100, + height: Math.round(pageSizeInches.height * 100) / 100 + }; + let sizeMillimeters = { + width: Math.round(pageSizeInches.width * 25.4 * 10) / 10, + height: Math.round(pageSizeInches.height * 25.4 * 10) / 10 + }; + let rawName = getPageName(sizeInches, isPortrait, US_PAGE_NAMES) || getPageName(sizeMillimeters, isPortrait, METRIC_PAGE_NAMES); + if (!rawName && !(Number.isInteger(sizeMillimeters.width) && Number.isInteger(sizeMillimeters.height))) { + const exactMillimeters = { + width: pageSizeInches.width * 25.4, + height: pageSizeInches.height * 25.4 + }; + const intMillimeters = { + width: Math.round(sizeMillimeters.width), + height: Math.round(sizeMillimeters.height) + }; + if (Math.abs(exactMillimeters.width - intMillimeters.width) < 0.1 && Math.abs(exactMillimeters.height - intMillimeters.height) < 0.1) { + rawName = getPageName(intMillimeters, isPortrait, METRIC_PAGE_NAMES); + if (rawName) { + sizeInches = { + width: Math.round(intMillimeters.width / 25.4 * 100) / 100, + height: Math.round(intMillimeters.height / 25.4 * 100) / 100 + }; + sizeMillimeters = intMillimeters; + } + } + } + const [{ + width, + height + }, unit, name, orientation] = await Promise.all([this._isNonMetricLocale ? sizeInches : sizeMillimeters, this.l10n.get(`pdfjs-document-properties-page-size-unit-${this._isNonMetricLocale ? "inches" : "millimeters"}`), rawName && this.l10n.get(`pdfjs-document-properties-page-size-name-${rawName}`), this.l10n.get(`pdfjs-document-properties-page-size-orientation-${isPortrait ? "portrait" : "landscape"}`)]); + return this.l10n.get(`pdfjs-document-properties-page-size-dimension-${name ? "name-" : ""}string`, { + width: width.toLocaleString(), + height: height.toLocaleString(), + unit, + name, + orientation + }); + } + async #parseDate(inputDate) { + const dateObject = pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PDFDateString.toDateObject(inputDate); + if (!dateObject) { + return undefined; + } + return this.l10n.get("pdfjs-document-properties-date-string", { + date: dateObject.toLocaleDateString(), + time: dateObject.toLocaleTimeString() + }); + } + #parseLinearization(isLinearized) { + return this.l10n.get(`pdfjs-document-properties-linearized-${isLinearized ? "yes" : "no"}`); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1795: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFFindBar: () => (/* binding */ PDFFindBar) +/* harmony export */ }); +/* harmony import */ var _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3557); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__]); +_pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +const MATCHES_COUNT_LIMIT = 1000; +class PDFFindBar { + #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this)); + constructor(options, eventBus) { + this.opened = false; + this.bar = options.bar; + this.toggleButton = options.toggleButton; + this.findField = options.findField; + this.highlightAll = options.highlightAllCheckbox; + this.caseSensitive = options.caseSensitiveCheckbox; + this.matchDiacritics = options.matchDiacriticsCheckbox; + this.entireWord = options.entireWordCheckbox; + this.findMsg = options.findMsg; + this.findResultsCount = options.findResultsCount; + this.findPreviousButton = options.findPreviousButton; + this.findNextButton = options.findNextButton; + this.eventBus = eventBus; + this.toggleButton.addEventListener("click", () => { + this.toggle(); + }); + this.findField.addEventListener("input", () => { + this.dispatchEvent(""); + }); + this.bar.addEventListener("keydown", e => { + switch (e.keyCode) { + case 13: + if (e.target === this.findField) { + this.dispatchEvent("again", e.shiftKey); + } + break; + case 27: + this.close(); + break; + } + }); + this.findPreviousButton.addEventListener("click", () => { + this.dispatchEvent("again", true); + }); + this.findNextButton.addEventListener("click", () => { + this.dispatchEvent("again", false); + }); + this.highlightAll.addEventListener("click", () => { + this.dispatchEvent("highlightallchange"); + }); + this.caseSensitive.addEventListener("click", () => { + this.dispatchEvent("casesensitivitychange"); + }); + this.entireWord.addEventListener("click", () => { + this.dispatchEvent("entirewordchange"); + }); + this.matchDiacritics.addEventListener("click", () => { + this.dispatchEvent("diacriticmatchingchange"); + }); + } + reset() { + this.updateUIState(); + } + dispatchEvent(type, findPrev = false) { + this.eventBus.dispatch("find", { + source: this, + type, + query: this.findField.value, + caseSensitive: this.caseSensitive.checked, + entireWord: this.entireWord.checked, + highlightAll: this.highlightAll.checked, + findPrevious: findPrev, + matchDiacritics: this.matchDiacritics.checked + }); + } + updateUIState(state, previous, matchesCount) { + const { + findField, + findMsg + } = this; + let findMsgId = "", + status = ""; + switch (state) { + case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.FOUND: + break; + case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.PENDING: + status = "pending"; + break; + case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.NOT_FOUND: + findMsgId = "pdfjs-find-not-found"; + status = "notFound"; + break; + case _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.WRAPPED: + findMsgId = `pdfjs-find-reached-${previous ? "top" : "bottom"}`; + break; + } + findField.setAttribute("data-status", status); + findField.setAttribute("aria-invalid", state === _pdf_find_controller_js__WEBPACK_IMPORTED_MODULE_0__.FindState.NOT_FOUND); + findMsg.setAttribute("data-status", status); + if (findMsgId) { + findMsg.setAttribute("data-l10n-id", findMsgId); + } else { + findMsg.removeAttribute("data-l10n-id"); + findMsg.textContent = ""; + } + this.updateResultsCount(matchesCount); + } + updateResultsCount({ + current = 0, + total = 0 + } = {}) { + const { + findResultsCount + } = this; + if (total > 0) { + const limit = MATCHES_COUNT_LIMIT; + findResultsCount.setAttribute("data-l10n-id", `pdfjs-find-match-count${total > limit ? "-limit" : ""}`); + findResultsCount.setAttribute("data-l10n-args", JSON.stringify({ + limit, + current, + total + })); + } else { + findResultsCount.removeAttribute("data-l10n-id"); + findResultsCount.textContent = ""; + } + } + open() { + if (!this.opened) { + this.#resizeObserver.observe(this.bar.parentNode); + this.#resizeObserver.observe(this.bar); + this.opened = true; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleExpandedBtn)(this.toggleButton, true, this.bar); + } + this.findField.select(); + this.findField.focus(); + } + close() { + if (!this.opened) { + return; + } + this.#resizeObserver.disconnect(); + this.opened = false; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleExpandedBtn)(this.toggleButton, false, this.bar); + this.eventBus.dispatch("findbarclose", { + source: this + }); + } + toggle() { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } + #resizeObserverCallback(entries) { + const { + bar + } = this; + bar.classList.remove("wrapContainers"); + const findbarHeight = bar.clientHeight; + const inputContainerHeight = bar.firstElementChild.clientHeight; + if (findbarHeight > inputContainerHeight) { + bar.classList.add("wrapContainers"); + } + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 3557: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ FindState: () => (/* binding */ FindState), +/* harmony export */ PDFFindController: () => (/* binding */ PDFFindController) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var _pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6839); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + + +const FindState = { + FOUND: 0, + NOT_FOUND: 1, + WRAPPED: 2, + PENDING: 3 +}; +const FIND_TIMEOUT = 250; +const MATCH_SCROLL_OFFSET_TOP = -50; +const MATCH_SCROLL_OFFSET_LEFT = -400; +const CHARACTERS_TO_NORMALIZE = { + "\u2010": "-", + "\u2018": "'", + "\u2019": "'", + "\u201A": "'", + "\u201B": "'", + "\u201C": '"', + "\u201D": '"', + "\u201E": '"', + "\u201F": '"', + "\u00BC": "1/4", + "\u00BD": "1/2", + "\u00BE": "3/4" +}; +const DIACRITICS_EXCEPTION = new Set([0x3099, 0x309a, 0x094d, 0x09cd, 0x0a4d, 0x0acd, 0x0b4d, 0x0bcd, 0x0c4d, 0x0ccd, 0x0d3b, 0x0d3c, 0x0d4d, 0x0dca, 0x0e3a, 0x0eba, 0x0f84, 0x1039, 0x103a, 0x1714, 0x1734, 0x17d2, 0x1a60, 0x1b44, 0x1baa, 0x1bab, 0x1bf2, 0x1bf3, 0x2d7f, 0xa806, 0xa82c, 0xa8c4, 0xa953, 0xa9c0, 0xaaf6, 0xabed, 0x0c56, 0x0f71, 0x0f72, 0x0f7a, 0x0f7b, 0x0f7c, 0x0f7d, 0x0f80, 0x0f74]); +let DIACRITICS_EXCEPTION_STR; +const DIACRITICS_REG_EXP = /\p{M}+/gu; +const SPECIAL_CHARS_REG_EXP = /([.*+?^${}()|[\]\\])|(\p{P})|(\s+)|(\p{M})|(\p{L})/gu; +const NOT_DIACRITIC_FROM_END_REG_EXP = /([^\p{M}])\p{M}*$/u; +const NOT_DIACRITIC_FROM_START_REG_EXP = /^\p{M}*([^\p{M}])/u; +const SYLLABLES_REG_EXP = /[\uAC00-\uD7AF\uFA6C\uFACF-\uFAD1\uFAD5-\uFAD7]+/g; +const SYLLABLES_LENGTHS = new Map(); +const FIRST_CHAR_SYLLABLES_REG_EXP = "[\\u1100-\\u1112\\ud7a4-\\ud7af\\ud84a\\ud84c\\ud850\\ud854\\ud857\\ud85f]"; +const NFKC_CHARS_TO_NORMALIZE = new Map(); +let noSyllablesRegExp = null; +let withSyllablesRegExp = null; +function normalize(text) { + const syllablePositions = []; + let m; + while ((m = SYLLABLES_REG_EXP.exec(text)) !== null) { + let { + index + } = m; + for (const char of m[0]) { + let len = SYLLABLES_LENGTHS.get(char); + if (!len) { + len = char.normalize("NFD").length; + SYLLABLES_LENGTHS.set(char, len); + } + syllablePositions.push([len, index++]); + } + } + let normalizationRegex; + if (syllablePositions.length === 0 && noSyllablesRegExp) { + normalizationRegex = noSyllablesRegExp; + } else if (syllablePositions.length > 0 && withSyllablesRegExp) { + normalizationRegex = withSyllablesRegExp; + } else { + const replace = Object.keys(CHARACTERS_TO_NORMALIZE).join(""); + const toNormalizeWithNFKC = (0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getNormalizeWithNFKC)(); + const CJK = "(?:\\p{Ideographic}|[\u3040-\u30FF])"; + const HKDiacritics = "(?:\u3099|\u309A)"; + const regexp = `([${replace}])|([${toNormalizeWithNFKC}])|(${HKDiacritics}\\n)|(\\p{M}+(?:-\\n)?)|(\\S-\\n)|(${CJK}\\n)|(\\n)`; + if (syllablePositions.length === 0) { + normalizationRegex = noSyllablesRegExp = new RegExp(regexp + "|(\\u0000)", "gum"); + } else { + normalizationRegex = withSyllablesRegExp = new RegExp(regexp + `|(${FIRST_CHAR_SYLLABLES_REG_EXP})`, "gum"); + } + } + const rawDiacriticsPositions = []; + while ((m = DIACRITICS_REG_EXP.exec(text)) !== null) { + rawDiacriticsPositions.push([m[0].length, m.index]); + } + let normalized = text.normalize("NFD"); + const positions = [[0, 0]]; + let rawDiacriticsIndex = 0; + let syllableIndex = 0; + let shift = 0; + let shiftOrigin = 0; + let eol = 0; + let hasDiacritics = false; + normalized = normalized.replace(normalizationRegex, (match, p1, p2, p3, p4, p5, p6, p7, p8, i) => { + i -= shiftOrigin; + if (p1) { + const replacement = CHARACTERS_TO_NORMALIZE[p1]; + const jj = replacement.length; + for (let j = 1; j < jj; j++) { + positions.push([i - shift + j, shift - j]); + } + shift -= jj - 1; + return replacement; + } + if (p2) { + let replacement = NFKC_CHARS_TO_NORMALIZE.get(p2); + if (!replacement) { + replacement = p2.normalize("NFKC"); + NFKC_CHARS_TO_NORMALIZE.set(p2, replacement); + } + const jj = replacement.length; + for (let j = 1; j < jj; j++) { + positions.push([i - shift + j, shift - j]); + } + shift -= jj - 1; + return replacement; + } + if (p3) { + hasDiacritics = true; + if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) { + ++rawDiacriticsIndex; + } else { + positions.push([i - 1 - shift + 1, shift - 1]); + shift -= 1; + shiftOrigin += 1; + } + positions.push([i - shift + 1, shift]); + shiftOrigin += 1; + eol += 1; + return p3.charAt(0); + } + if (p4) { + const hasTrailingDashEOL = p4.endsWith("\n"); + const len = hasTrailingDashEOL ? p4.length - 2 : p4.length; + hasDiacritics = true; + let jj = len; + if (i + eol === rawDiacriticsPositions[rawDiacriticsIndex]?.[1]) { + jj -= rawDiacriticsPositions[rawDiacriticsIndex][0]; + ++rawDiacriticsIndex; + } + for (let j = 1; j <= jj; j++) { + positions.push([i - 1 - shift + j, shift - j]); + } + shift -= jj; + shiftOrigin += jj; + if (hasTrailingDashEOL) { + i += len - 1; + positions.push([i - shift + 1, 1 + shift]); + shift += 1; + shiftOrigin += 1; + eol += 1; + return p4.slice(0, len); + } + return p4; + } + if (p5) { + const len = p5.length - 2; + positions.push([i - shift + len, 1 + shift]); + shift += 1; + shiftOrigin += 1; + eol += 1; + return p5.slice(0, -2); + } + if (p6) { + const len = p6.length - 1; + positions.push([i - shift + len, shift]); + shiftOrigin += 1; + eol += 1; + return p6.slice(0, -1); + } + if (p7) { + positions.push([i - shift + 1, shift - 1]); + shift -= 1; + shiftOrigin += 1; + eol += 1; + return " "; + } + if (i + eol === syllablePositions[syllableIndex]?.[1]) { + const newCharLen = syllablePositions[syllableIndex][0] - 1; + ++syllableIndex; + for (let j = 1; j <= newCharLen; j++) { + positions.push([i - (shift - j), shift - j]); + } + shift -= newCharLen; + shiftOrigin += newCharLen; + } + return p8; + }); + positions.push([normalized.length, shift]); + return [normalized, positions, hasDiacritics]; +} +function getOriginalIndex(diffs, pos, len) { + if (!diffs) { + return [pos, len]; + } + const start = pos; + const end = pos + len - 1; + let i = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(diffs, x => x[0] >= start); + if (diffs[i][0] > start) { + --i; + } + let j = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(diffs, x => x[0] >= end, i); + if (diffs[j][0] > end) { + --j; + } + const oldStart = start + diffs[i][1]; + const oldEnd = end + diffs[j][1]; + const oldLen = oldEnd + 1 - oldStart; + return [oldStart, oldLen]; +} +class PDFFindController { + #state = null; + #updateMatchesCountOnProgress = true; + #visitedPagesCount = 0; + constructor({ + linkService, + eventBus, + updateMatchesCountOnProgress = true + }) { + this._linkService = linkService; + this._eventBus = eventBus; + this.#updateMatchesCountOnProgress = updateMatchesCountOnProgress; + this.onIsPageVisible = null; + this.#reset(); + eventBus._on("find", this.#onFind.bind(this)); + eventBus._on("findbarclose", this.#onFindBarClose.bind(this)); + } + get highlightMatches() { + return this._highlightMatches; + } + get pageMatches() { + return this._pageMatches; + } + get pageMatchesLength() { + return this._pageMatchesLength; + } + get selected() { + return this._selected; + } + get state() { + return this.#state; + } + setDocument(pdfDocument) { + if (this._pdfDocument) { + this.#reset(); + } + if (!pdfDocument) { + return; + } + this._pdfDocument = pdfDocument; + this._firstPageCapability.resolve(); + } + #onFind(state) { + if (!state) { + return; + } + const pdfDocument = this._pdfDocument; + const { + type + } = state; + if (this.#state === null || this.#shouldDirtyMatch(state)) { + this._dirtyMatch = true; + } + this.#state = state; + if (type !== "highlightallchange") { + this.#updateUIState(FindState.PENDING); + } + this._firstPageCapability.promise.then(() => { + if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) { + return; + } + this.#extractText(); + const findbarClosed = !this._highlightMatches; + const pendingTimeout = !!this._findTimeout; + if (this._findTimeout) { + clearTimeout(this._findTimeout); + this._findTimeout = null; + } + if (!type) { + this._findTimeout = setTimeout(() => { + this.#nextMatch(); + this._findTimeout = null; + }, FIND_TIMEOUT); + } else if (this._dirtyMatch) { + this.#nextMatch(); + } else if (type === "again") { + this.#nextMatch(); + if (findbarClosed && this.#state.highlightAll) { + this.#updateAllPages(); + } + } else if (type === "highlightallchange") { + if (pendingTimeout) { + this.#nextMatch(); + } else { + this._highlightMatches = true; + } + this.#updateAllPages(); + } else { + this.#nextMatch(); + } + }); + } + scrollMatchIntoView({ + element = null, + selectedLeft = 0, + pageIndex = -1, + matchIndex = -1 + }) { + if (!this._scrollMatches || !element) { + return; + } else if (matchIndex === -1 || matchIndex !== this._selected.matchIdx) { + return; + } else if (pageIndex === -1 || pageIndex !== this._selected.pageIdx) { + return; + } + this._scrollMatches = false; + const spot = { + top: MATCH_SCROLL_OFFSET_TOP, + left: selectedLeft + MATCH_SCROLL_OFFSET_LEFT + }; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.scrollIntoView)(element, spot, true); + } + #reset() { + this._highlightMatches = false; + this._scrollMatches = false; + this._pdfDocument = null; + this._pageMatches = []; + this._pageMatchesLength = []; + this.#visitedPagesCount = 0; + this.#state = null; + this._selected = { + pageIdx: -1, + matchIdx: -1 + }; + this._offset = { + pageIdx: null, + matchIdx: null, + wrapped: false + }; + this._extractTextPromises = []; + this._pageContents = []; + this._pageDiffs = []; + this._hasDiacritics = []; + this._matchesCountTotal = 0; + this._pagesToSearch = null; + this._pendingFindMatches = new Set(); + this._resumePageIdx = null; + this._dirtyMatch = false; + clearTimeout(this._findTimeout); + this._findTimeout = null; + this._firstPageCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.PromiseCapability(); + } + get #query() { + const { + query + } = this.#state; + if (typeof query === "string") { + if (query !== this._rawQuery) { + this._rawQuery = query; + [this._normalizedQuery] = normalize(query); + } + return this._normalizedQuery; + } + return (query || []).filter(q => !!q).map(q => normalize(q)[0]); + } + #shouldDirtyMatch(state) { + const newQuery = state.query, + prevQuery = this.#state.query; + const newType = typeof newQuery, + prevType = typeof prevQuery; + if (newType !== prevType) { + return true; + } + if (newType === "string") { + if (newQuery !== prevQuery) { + return true; + } + } else if (JSON.stringify(newQuery) !== JSON.stringify(prevQuery)) { + return true; + } + switch (state.type) { + case "again": + const pageNumber = this._selected.pageIdx + 1; + const linkService = this._linkService; + return pageNumber >= 1 && pageNumber <= linkService.pagesCount && pageNumber !== linkService.page && !(this.onIsPageVisible?.(pageNumber) ?? true); + case "highlightallchange": + return false; + } + return true; + } + #isEntireWord(content, startIdx, length) { + let match = content.slice(0, startIdx).match(NOT_DIACRITIC_FROM_END_REG_EXP); + if (match) { + const first = content.charCodeAt(startIdx); + const limit = match[1].charCodeAt(0); + if ((0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(first) === (0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(limit)) { + return false; + } + } + match = content.slice(startIdx + length).match(NOT_DIACRITIC_FROM_START_REG_EXP); + if (match) { + const last = content.charCodeAt(startIdx + length - 1); + const limit = match[1].charCodeAt(0); + if ((0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(last) === (0,_pdf_find_utils_js__WEBPACK_IMPORTED_MODULE_1__.getCharacterType)(limit)) { + return false; + } + } + return true; + } + #calculateRegExpMatch(query, entireWord, pageIndex, pageContent) { + const matches = this._pageMatches[pageIndex] = []; + const matchesLength = this._pageMatchesLength[pageIndex] = []; + if (!query) { + return; + } + const diffs = this._pageDiffs[pageIndex]; + let match; + while ((match = query.exec(pageContent)) !== null) { + if (entireWord && !this.#isEntireWord(pageContent, match.index, match[0].length)) { + continue; + } + const [matchPos, matchLen] = getOriginalIndex(diffs, match.index, match[0].length); + if (matchLen) { + matches.push(matchPos); + matchesLength.push(matchLen); + } + } + } + #convertToRegExpString(query, hasDiacritics) { + const { + matchDiacritics + } = this.#state; + let isUnicode = false; + query = query.replaceAll(SPECIAL_CHARS_REG_EXP, (match, p1, p2, p3, p4, p5) => { + if (p1) { + return `[ ]*\\${p1}[ ]*`; + } + if (p2) { + return `[ ]*${p2}[ ]*`; + } + if (p3) { + return "[ ]+"; + } + if (matchDiacritics) { + return p4 || p5; + } + if (p4) { + return DIACRITICS_EXCEPTION.has(p4.charCodeAt(0)) ? p4 : ""; + } + if (hasDiacritics) { + isUnicode = true; + return `${p5}\\p{M}*`; + } + return p5; + }); + const trailingSpaces = "[ ]*"; + if (query.endsWith(trailingSpaces)) { + query = query.slice(0, query.length - trailingSpaces.length); + } + if (matchDiacritics) { + if (hasDiacritics) { + DIACRITICS_EXCEPTION_STR ||= String.fromCharCode(...DIACRITICS_EXCEPTION); + isUnicode = true; + query = `${query}(?=[${DIACRITICS_EXCEPTION_STR}]|[^\\p{M}]|$)`; + } + } + return [isUnicode, query]; + } + #calculateMatch(pageIndex) { + let query = this.#query; + if (query.length === 0) { + return; + } + const { + caseSensitive, + entireWord + } = this.#state; + const pageContent = this._pageContents[pageIndex]; + const hasDiacritics = this._hasDiacritics[pageIndex]; + let isUnicode = false; + if (typeof query === "string") { + [isUnicode, query] = this.#convertToRegExpString(query, hasDiacritics); + } else { + query = query.sort().reverse().map(q => { + const [isUnicodePart, queryPart] = this.#convertToRegExpString(q, hasDiacritics); + isUnicode ||= isUnicodePart; + return `(${queryPart})`; + }).join("|"); + } + const flags = `g${isUnicode ? "u" : ""}${caseSensitive ? "" : "i"}`; + query = query ? new RegExp(query, flags) : null; + this.#calculateRegExpMatch(query, entireWord, pageIndex, pageContent); + if (this.#state.highlightAll) { + this.#updatePage(pageIndex); + } + if (this._resumePageIdx === pageIndex) { + this._resumePageIdx = null; + this.#nextPageMatch(); + } + const pageMatchesCount = this._pageMatches[pageIndex].length; + this._matchesCountTotal += pageMatchesCount; + if (this.#updateMatchesCountOnProgress) { + if (pageMatchesCount > 0) { + this.#updateUIResultsCount(); + } + } else if (++this.#visitedPagesCount === this._linkService.pagesCount) { + this.#updateUIResultsCount(); + } + } + #extractText() { + if (this._extractTextPromises.length > 0) { + return; + } + let promise = Promise.resolve(); + const textOptions = { + disableNormalization: true + }; + for (let i = 0, ii = this._linkService.pagesCount; i < ii; i++) { + const extractTextCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_2__.PromiseCapability(); + this._extractTextPromises[i] = extractTextCapability.promise; + promise = promise.then(() => { + return this._pdfDocument.getPage(i + 1).then(pdfPage => { + return pdfPage.getTextContent(textOptions); + }).then(textContent => { + const strBuf = []; + for (const textItem of textContent.items) { + strBuf.push(textItem.str); + if (textItem.hasEOL) { + strBuf.push("\n"); + } + } + [this._pageContents[i], this._pageDiffs[i], this._hasDiacritics[i]] = normalize(strBuf.join("")); + extractTextCapability.resolve(); + }, reason => { + console.error(`Unable to get text content for page ${i + 1}`, reason); + this._pageContents[i] = ""; + this._pageDiffs[i] = null; + this._hasDiacritics[i] = false; + extractTextCapability.resolve(); + }); + }); + } + } + #updatePage(index) { + if (this._scrollMatches && this._selected.pageIdx === index) { + this._linkService.page = index + 1; + } + this._eventBus.dispatch("updatetextlayermatches", { + source: this, + pageIndex: index + }); + } + #updateAllPages() { + this._eventBus.dispatch("updatetextlayermatches", { + source: this, + pageIndex: -1 + }); + } + #nextMatch() { + const previous = this.#state.findPrevious; + const currentPageIndex = this._linkService.page - 1; + const numPages = this._linkService.pagesCount; + this._highlightMatches = true; + if (this._dirtyMatch) { + this._dirtyMatch = false; + this._selected.pageIdx = this._selected.matchIdx = -1; + this._offset.pageIdx = currentPageIndex; + this._offset.matchIdx = null; + this._offset.wrapped = false; + this._resumePageIdx = null; + this._pageMatches.length = 0; + this._pageMatchesLength.length = 0; + this.#visitedPagesCount = 0; + this._matchesCountTotal = 0; + this.#updateAllPages(); + for (let i = 0; i < numPages; i++) { + if (this._pendingFindMatches.has(i)) { + continue; + } + this._pendingFindMatches.add(i); + this._extractTextPromises[i].then(() => { + this._pendingFindMatches.delete(i); + this.#calculateMatch(i); + }); + } + } + const query = this.#query; + if (query.length === 0) { + this.#updateUIState(FindState.FOUND); + return; + } + if (this._resumePageIdx) { + return; + } + const offset = this._offset; + this._pagesToSearch = numPages; + if (offset.matchIdx !== null) { + const numPageMatches = this._pageMatches[offset.pageIdx].length; + if (!previous && offset.matchIdx + 1 < numPageMatches || previous && offset.matchIdx > 0) { + offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1; + this.#updateMatch(true); + return; + } + this.#advanceOffsetPage(previous); + } + this.#nextPageMatch(); + } + #matchesReady(matches) { + const offset = this._offset; + const numMatches = matches.length; + const previous = this.#state.findPrevious; + if (numMatches) { + offset.matchIdx = previous ? numMatches - 1 : 0; + this.#updateMatch(true); + return true; + } + this.#advanceOffsetPage(previous); + if (offset.wrapped) { + offset.matchIdx = null; + if (this._pagesToSearch < 0) { + this.#updateMatch(false); + return true; + } + } + return false; + } + #nextPageMatch() { + if (this._resumePageIdx !== null) { + console.error("There can only be one pending page."); + } + let matches = null; + do { + const pageIdx = this._offset.pageIdx; + matches = this._pageMatches[pageIdx]; + if (!matches) { + this._resumePageIdx = pageIdx; + break; + } + } while (!this.#matchesReady(matches)); + } + #advanceOffsetPage(previous) { + const offset = this._offset; + const numPages = this._linkService.pagesCount; + offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1; + offset.matchIdx = null; + this._pagesToSearch--; + if (offset.pageIdx >= numPages || offset.pageIdx < 0) { + offset.pageIdx = previous ? numPages - 1 : 0; + offset.wrapped = true; + } + } + #updateMatch(found = false) { + let state = FindState.NOT_FOUND; + const wrapped = this._offset.wrapped; + this._offset.wrapped = false; + if (found) { + const previousPage = this._selected.pageIdx; + this._selected.pageIdx = this._offset.pageIdx; + this._selected.matchIdx = this._offset.matchIdx; + state = wrapped ? FindState.WRAPPED : FindState.FOUND; + if (previousPage !== -1 && previousPage !== this._selected.pageIdx) { + this.#updatePage(previousPage); + } + } + this.#updateUIState(state, this.#state.findPrevious); + if (this._selected.pageIdx !== -1) { + this._scrollMatches = true; + this.#updatePage(this._selected.pageIdx); + } + } + #onFindBarClose(evt) { + const pdfDocument = this._pdfDocument; + this._firstPageCapability.promise.then(() => { + if (!this._pdfDocument || pdfDocument && this._pdfDocument !== pdfDocument) { + return; + } + if (this._findTimeout) { + clearTimeout(this._findTimeout); + this._findTimeout = null; + } + if (this._resumePageIdx) { + this._resumePageIdx = null; + this._dirtyMatch = true; + } + this.#updateUIState(FindState.FOUND); + this._highlightMatches = false; + this.#updateAllPages(); + }); + } + #requestMatchesCount() { + const { + pageIdx, + matchIdx + } = this._selected; + let current = 0, + total = this._matchesCountTotal; + if (matchIdx !== -1) { + for (let i = 0; i < pageIdx; i++) { + current += this._pageMatches[i]?.length || 0; + } + current += matchIdx + 1; + } + if (current < 1 || current > total) { + current = total = 0; + } + return { + current, + total + }; + } + #updateUIResultsCount() { + this._eventBus.dispatch("updatefindmatchescount", { + source: this, + matchesCount: this.#requestMatchesCount() + }); + } + #updateUIState(state, previous = false) { + if (!this.#updateMatchesCountOnProgress && (this.#visitedPagesCount !== this._linkService.pagesCount || state === FindState.PENDING)) { + return; + } + this._eventBus.dispatch("updatefindcontrolstate", { + source: this, + state, + previous, + matchesCount: this.#requestMatchesCount(), + rawQuery: this.#state?.query ?? null + }); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 6839: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ getCharacterType: () => (/* binding */ getCharacterType), +/* harmony export */ getNormalizeWithNFKC: () => (/* binding */ getNormalizeWithNFKC) +/* harmony export */ }); +/* unused harmony export CharacterType */ +const CharacterType = { + SPACE: 0, + ALPHA_LETTER: 1, + PUNCT: 2, + HAN_LETTER: 3, + KATAKANA_LETTER: 4, + HIRAGANA_LETTER: 5, + HALFWIDTH_KATAKANA_LETTER: 6, + THAI_LETTER: 7 +}; +function isAlphabeticalScript(charCode) { + return charCode < 0x2e80; +} +function isAscii(charCode) { + return (charCode & 0xff80) === 0; +} +function isAsciiAlpha(charCode) { + return charCode >= 0x61 && charCode <= 0x7a || charCode >= 0x41 && charCode <= 0x5a; +} +function isAsciiDigit(charCode) { + return charCode >= 0x30 && charCode <= 0x39; +} +function isAsciiSpace(charCode) { + return charCode === 0x20 || charCode === 0x09 || charCode === 0x0d || charCode === 0x0a; +} +function isHan(charCode) { + return charCode >= 0x3400 && charCode <= 0x9fff || charCode >= 0xf900 && charCode <= 0xfaff; +} +function isKatakana(charCode) { + return charCode >= 0x30a0 && charCode <= 0x30ff; +} +function isHiragana(charCode) { + return charCode >= 0x3040 && charCode <= 0x309f; +} +function isHalfwidthKatakana(charCode) { + return charCode >= 0xff60 && charCode <= 0xff9f; +} +function isThai(charCode) { + return (charCode & 0xff80) === 0x0e00; +} +function getCharacterType(charCode) { + if (isAlphabeticalScript(charCode)) { + if (isAscii(charCode)) { + if (isAsciiSpace(charCode)) { + return CharacterType.SPACE; + } else if (isAsciiAlpha(charCode) || isAsciiDigit(charCode) || charCode === 0x5f) { + return CharacterType.ALPHA_LETTER; + } + return CharacterType.PUNCT; + } else if (isThai(charCode)) { + return CharacterType.THAI_LETTER; + } else if (charCode === 0xa0) { + return CharacterType.SPACE; + } + return CharacterType.ALPHA_LETTER; + } + if (isHan(charCode)) { + return CharacterType.HAN_LETTER; + } else if (isKatakana(charCode)) { + return CharacterType.KATAKANA_LETTER; + } else if (isHiragana(charCode)) { + return CharacterType.HIRAGANA_LETTER; + } else if (isHalfwidthKatakana(charCode)) { + return CharacterType.HALFWIDTH_KATAKANA_LETTER; + } + return CharacterType.ALPHA_LETTER; +} +let NormalizeWithNFKC; +function getNormalizeWithNFKC() { + NormalizeWithNFKC ||= ` ¨ª¯²-µ¸-º¼-¾IJ-ijĿ-ŀʼnſDŽ-njDZ-dzʰ-ʸ˘-˝ˠ-ˤʹͺ;΄-΅·ϐ-ϖϰ-ϲϴ-ϵϹևٵ-ٸक़-य़ড়-ঢ়য়ਲ਼ਸ਼ਖ਼-ਜ਼ਫ਼ଡ଼-ଢ଼ำຳໜ-ໝ༌གྷཌྷདྷབྷཛྷཀྵჼᴬ-ᴮᴰ-ᴺᴼ-ᵍᵏ-ᵪᵸᶛ-ᶿẚ-ẛάέήίόύώΆ᾽-῁ΈΉ῍-῏ΐΊ῝-῟ΰΎ῭-`ΌΏ´-῾ - ‑‗․-… ″-‴‶-‷‼‾⁇-⁉⁗ ⁰-ⁱ⁴-₎ₐ-ₜ₨℀-℃℅-ℇ℉-ℓℕ-№ℙ-ℝ℠-™ℤΩℨK-ℭℯ-ℱℳ-ℹ℻-⅀ⅅ-ⅉ⅐-ⅿ↉∬-∭∯-∰〈-〉①-⓪⨌⩴-⩶⫝̸ⱼ-ⱽⵯ⺟⻳⼀-⿕ 〶〸-〺゛-゜ゟヿㄱ-ㆎ㆒-㆟㈀-㈞㈠-㉇㉐-㉾㊀-㏿ꚜ-ꚝꝰꟲ-ꟴꟸ-ꟹꭜ-ꭟꭩ豈-嗀塚晴凞-羽蘒諸逸-都飯-舘並-龎ff-stﬓ-ﬗיִײַ-זּטּ-לּמּנּ-סּףּ-פּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-﷼︐-︙︰-﹄﹇-﹒﹔-﹦﹨-﹫ﹰ-ﹲﹴﹶ-ﻼ!-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ¢-₩`; + return NormalizeWithNFKC; +} + + +/***/ }), + +/***/ 6418: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFHistory: () => (/* binding */ PDFHistory) +/* harmony export */ }); +/* unused harmony exports isDestArraysEqual, isDestHashesEqual */ +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var _event_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6554); + + +const HASH_CHANGE_TIMEOUT = 1000; +const POSITION_UPDATED_THRESHOLD = 50; +const UPDATE_VIEWAREA_TIMEOUT = 1000; +function getCurrentHash() { + return document.location.hash; +} +class PDFHistory { + constructor({ + linkService, + eventBus + }) { + this.linkService = linkService; + this.eventBus = eventBus; + this._initialized = false; + this._fingerprint = ""; + this.reset(); + this._boundEvents = null; + this.eventBus._on("pagesinit", () => { + this._isPagesLoaded = false; + this.eventBus._on("pagesloaded", evt => { + this._isPagesLoaded = !!evt.pagesCount; + }, { + once: true + }); + }); + } + initialize({ + fingerprint, + resetHistory = false, + updateUrl = false + }) { + if (!fingerprint || typeof fingerprint !== "string") { + console.error('PDFHistory.initialize: The "fingerprint" must be a non-empty string.'); + return; + } + if (this._initialized) { + this.reset(); + } + const reInitialized = this._fingerprint !== "" && this._fingerprint !== fingerprint; + this._fingerprint = fingerprint; + this._updateUrl = updateUrl === true; + this._initialized = true; + this._bindEvents(); + const state = window.history.state; + this._popStateInProgress = false; + this._blockHashChange = 0; + this._currentHash = getCurrentHash(); + this._numPositionUpdates = 0; + this._uid = this._maxUid = 0; + this._destination = null; + this._position = null; + if (!this._isValidState(state, true) || resetHistory) { + const { + hash, + page, + rotation + } = this._parseCurrentHash(true); + if (!hash || reInitialized || resetHistory) { + this._pushOrReplaceState(null, true); + return; + } + this._pushOrReplaceState({ + hash, + page, + rotation + }, true); + return; + } + const destination = state.destination; + this._updateInternalState(destination, state.uid, true); + if (destination.rotation !== undefined) { + this._initialRotation = destination.rotation; + } + if (destination.dest) { + this._initialBookmark = JSON.stringify(destination.dest); + this._destination.page = null; + } else if (destination.hash) { + this._initialBookmark = destination.hash; + } else if (destination.page) { + this._initialBookmark = `page=${destination.page}`; + } + } + reset() { + if (this._initialized) { + this._pageHide(); + this._initialized = false; + this._unbindEvents(); + } + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + this._initialBookmark = null; + this._initialRotation = null; + } + push({ + namedDest = null, + explicitDest, + pageNumber + }) { + if (!this._initialized) { + return; + } + if (namedDest && typeof namedDest !== "string") { + console.error("PDFHistory.push: " + `"${namedDest}" is not a valid namedDest parameter.`); + return; + } else if (!Array.isArray(explicitDest)) { + console.error("PDFHistory.push: " + `"${explicitDest}" is not a valid explicitDest parameter.`); + return; + } else if (!this._isValidPage(pageNumber)) { + if (pageNumber !== null || this._destination) { + console.error("PDFHistory.push: " + `"${pageNumber}" is not a valid pageNumber parameter.`); + return; + } + } + const hash = namedDest || JSON.stringify(explicitDest); + if (!hash) { + return; + } + let forceReplace = false; + if (this._destination && (isDestHashesEqual(this._destination.hash, hash) || isDestArraysEqual(this._destination.dest, explicitDest))) { + if (this._destination.page) { + return; + } + forceReplace = true; + } + if (this._popStateInProgress && !forceReplace) { + return; + } + this._pushOrReplaceState({ + dest: explicitDest, + hash, + page: pageNumber, + rotation: this.linkService.rotation + }, forceReplace); + if (!this._popStateInProgress) { + this._popStateInProgress = true; + Promise.resolve().then(() => { + this._popStateInProgress = false; + }); + } + } + pushPage(pageNumber) { + if (!this._initialized) { + return; + } + if (!this._isValidPage(pageNumber)) { + console.error(`PDFHistory.pushPage: "${pageNumber}" is not a valid page number.`); + return; + } + if (this._destination?.page === pageNumber) { + return; + } + if (this._popStateInProgress) { + return; + } + this._pushOrReplaceState({ + dest: null, + hash: `page=${pageNumber}`, + page: pageNumber, + rotation: this.linkService.rotation + }); + if (!this._popStateInProgress) { + this._popStateInProgress = true; + Promise.resolve().then(() => { + this._popStateInProgress = false; + }); + } + } + pushCurrentPosition() { + if (!this._initialized || this._popStateInProgress) { + return; + } + this._tryPushCurrentPosition(); + } + back() { + if (!this._initialized || this._popStateInProgress) { + return; + } + const state = window.history.state; + if (this._isValidState(state) && state.uid > 0) { + window.history.back(); + } + } + forward() { + if (!this._initialized || this._popStateInProgress) { + return; + } + const state = window.history.state; + if (this._isValidState(state) && state.uid < this._maxUid) { + window.history.forward(); + } + } + get popStateInProgress() { + return this._initialized && (this._popStateInProgress || this._blockHashChange > 0); + } + get initialBookmark() { + return this._initialized ? this._initialBookmark : null; + } + get initialRotation() { + return this._initialized ? this._initialRotation : null; + } + _pushOrReplaceState(destination, forceReplace = false) { + const shouldReplace = forceReplace || !this._destination; + const newState = { + fingerprint: this._fingerprint, + uid: shouldReplace ? this._uid : this._uid + 1, + destination + }; + this._updateInternalState(destination, newState.uid); + let newUrl; + if (this._updateUrl && destination?.hash) { + const baseUrl = document.location.href.split("#")[0]; + if (!baseUrl.startsWith("file://")) { + newUrl = `${baseUrl}#${destination.hash}`; + } + } + if (shouldReplace) { + window.history.replaceState(newState, "", newUrl); + } else { + window.history.pushState(newState, "", newUrl); + } + } + _tryPushCurrentPosition(temporary = false) { + if (!this._position) { + return; + } + let position = this._position; + if (temporary) { + position = Object.assign(Object.create(null), this._position); + position.temporary = true; + } + if (!this._destination) { + this._pushOrReplaceState(position); + return; + } + if (this._destination.temporary) { + this._pushOrReplaceState(position, true); + return; + } + if (this._destination.hash === position.hash) { + return; + } + if (!this._destination.page && (POSITION_UPDATED_THRESHOLD <= 0 || this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) { + return; + } + let forceReplace = false; + if (this._destination.page >= position.first && this._destination.page <= position.page) { + if (this._destination.dest !== undefined || !this._destination.first) { + return; + } + forceReplace = true; + } + this._pushOrReplaceState(position, forceReplace); + } + _isValidPage(val) { + return Number.isInteger(val) && val > 0 && val <= this.linkService.pagesCount; + } + _isValidState(state, checkReload = false) { + if (!state) { + return false; + } + if (state.fingerprint !== this._fingerprint) { + if (checkReload) { + if (typeof state.fingerprint !== "string" || state.fingerprint.length !== this._fingerprint.length) { + return false; + } + const [perfEntry] = performance.getEntriesByType("navigation"); + if (perfEntry?.type !== "reload") { + return false; + } + } else { + return false; + } + } + if (!Number.isInteger(state.uid) || state.uid < 0) { + return false; + } + if (state.destination === null || typeof state.destination !== "object") { + return false; + } + return true; + } + _updateInternalState(destination, uid, removeTemporary = false) { + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + if (removeTemporary && destination?.temporary) { + delete destination.temporary; + } + this._destination = destination; + this._uid = uid; + this._maxUid = Math.max(this._maxUid, uid); + this._numPositionUpdates = 0; + } + _parseCurrentHash(checkNameddest = false) { + const hash = unescape(getCurrentHash()).substring(1); + const params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(hash); + const nameddest = params.get("nameddest") || ""; + let page = params.get("page") | 0; + if (!this._isValidPage(page) || checkNameddest && nameddest.length > 0) { + page = null; + } + return { + hash, + page, + rotation: this.linkService.rotation + }; + } + _updateViewarea({ + location + }) { + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + this._position = { + hash: location.pdfOpenParams.substring(1), + page: this.linkService.page, + first: location.pageNumber, + rotation: location.rotation + }; + if (this._popStateInProgress) { + return; + } + if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded && this._destination && !this._destination.page) { + this._numPositionUpdates++; + } + if (UPDATE_VIEWAREA_TIMEOUT > 0) { + this._updateViewareaTimeout = setTimeout(() => { + if (!this._popStateInProgress) { + this._tryPushCurrentPosition(true); + } + this._updateViewareaTimeout = null; + }, UPDATE_VIEWAREA_TIMEOUT); + } + } + _popState({ + state + }) { + const newHash = getCurrentHash(), + hashChanged = this._currentHash !== newHash; + this._currentHash = newHash; + if (!state) { + this._uid++; + const { + hash, + page, + rotation + } = this._parseCurrentHash(); + this._pushOrReplaceState({ + hash, + page, + rotation + }, true); + return; + } + if (!this._isValidState(state)) { + return; + } + this._popStateInProgress = true; + if (hashChanged) { + this._blockHashChange++; + (0,_event_utils_js__WEBPACK_IMPORTED_MODULE_1__.waitOnEventOrTimeout)({ + target: window, + name: "hashchange", + delay: HASH_CHANGE_TIMEOUT + }).then(() => { + this._blockHashChange--; + }); + } + const destination = state.destination; + this._updateInternalState(destination, state.uid, true); + if ((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidRotation)(destination.rotation)) { + this.linkService.rotation = destination.rotation; + } + if (destination.dest) { + this.linkService.goToDestination(destination.dest); + } else if (destination.hash) { + this.linkService.setHash(destination.hash); + } else if (destination.page) { + this.linkService.page = destination.page; + } + Promise.resolve().then(() => { + this._popStateInProgress = false; + }); + } + _pageHide() { + if (!this._destination || this._destination.temporary) { + this._tryPushCurrentPosition(); + } + } + _bindEvents() { + if (this._boundEvents) { + return; + } + this._boundEvents = { + updateViewarea: this._updateViewarea.bind(this), + popState: this._popState.bind(this), + pageHide: this._pageHide.bind(this) + }; + this.eventBus._on("updateviewarea", this._boundEvents.updateViewarea); + window.addEventListener("popstate", this._boundEvents.popState); + window.addEventListener("pagehide", this._boundEvents.pageHide); + } + _unbindEvents() { + if (!this._boundEvents) { + return; + } + this.eventBus._off("updateviewarea", this._boundEvents.updateViewarea); + window.removeEventListener("popstate", this._boundEvents.popState); + window.removeEventListener("pagehide", this._boundEvents.pageHide); + this._boundEvents = null; + } +} +function isDestHashesEqual(destHash, pushHash) { + if (typeof destHash !== "string" || typeof pushHash !== "string") { + return false; + } + if (destHash === pushHash) { + return true; + } + const nameddest = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(destHash).get("nameddest"); + if (nameddest === pushHash) { + return true; + } + return false; +} +function isDestArraysEqual(firstDest, secondDest) { + function isEntryEqual(first, second) { + if (typeof first !== typeof second) { + return false; + } + if (Array.isArray(first) || Array.isArray(second)) { + return false; + } + if (first !== null && typeof first === "object" && second !== null) { + if (Object.keys(first).length !== Object.keys(second).length) { + return false; + } + for (const key in first) { + if (!isEntryEqual(first[key], second[key])) { + return false; + } + } + return true; + } + return first === second || Number.isNaN(first) && Number.isNaN(second); + } + if (!(Array.isArray(firstDest) && Array.isArray(secondDest))) { + return false; + } + if (firstDest.length !== secondDest.length) { + return false; + } + for (let i = 0, ii = firstDest.length; i < ii; i++) { + if (!isEntryEqual(firstDest[i], secondDest[i])) { + return false; + } + } + return true; +} + + +/***/ }), + +/***/ 3706: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFLayerViewer: () => (/* binding */ PDFLayerViewer) +/* harmony export */ }); +/* harmony import */ var _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9415); + +class PDFLayerViewer extends _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__.BaseTreeViewer { + constructor(options) { + super(options); + this.eventBus._on("optionalcontentconfigchanged", evt => { + this.#updateLayers(evt.promise); + }); + this.eventBus._on("resetlayers", () => { + this.#updateLayers(); + }); + this.eventBus._on("togglelayerstree", this._toggleAllTreeItems.bind(this)); + } + reset() { + super.reset(); + this._optionalContentConfig = null; + this._optionalContentHash = null; + } + _dispatchEvent(layersCount) { + this.eventBus.dispatch("layersloaded", { + source: this, + layersCount + }); + } + _bindLink(element, { + groupId, + input + }) { + const setVisibility = () => { + this._optionalContentConfig.setVisibility(groupId, input.checked); + this._optionalContentHash = this._optionalContentConfig.getHash(); + this.eventBus.dispatch("optionalcontentconfig", { + source: this, + promise: Promise.resolve(this._optionalContentConfig) + }); + }; + element.onclick = evt => { + if (evt.target === input) { + setVisibility(); + return true; + } else if (evt.target !== element) { + return true; + } + input.checked = !input.checked; + setVisibility(); + return false; + }; + } + async _setNestedName(element, { + name = null + }) { + if (typeof name === "string") { + element.textContent = this._normalizeTextContent(name); + return; + } + element.textContent = await this._l10n.get("pdfjs-additional-layers"); + element.style.fontStyle = "italic"; + } + _addToggleButton(div, { + name = null + }) { + super._addToggleButton(div, name === null); + } + _toggleAllTreeItems() { + if (!this._optionalContentConfig) { + return; + } + super._toggleAllTreeItems(); + } + render({ + optionalContentConfig, + pdfDocument + }) { + if (this._optionalContentConfig) { + this.reset(); + } + this._optionalContentConfig = optionalContentConfig || null; + this._pdfDocument = pdfDocument || null; + const groups = optionalContentConfig?.getOrder(); + if (!groups) { + this._dispatchEvent(0); + return; + } + this._optionalContentHash = optionalContentConfig.getHash(); + const fragment = document.createDocumentFragment(), + queue = [{ + parent: fragment, + groups + }]; + let layersCount = 0, + hasAnyNesting = false; + while (queue.length > 0) { + const levelData = queue.shift(); + for (const groupId of levelData.groups) { + const div = document.createElement("div"); + div.className = "treeItem"; + const element = document.createElement("a"); + div.append(element); + if (typeof groupId === "object") { + hasAnyNesting = true; + this._addToggleButton(div, groupId); + this._setNestedName(element, groupId); + const itemsDiv = document.createElement("div"); + itemsDiv.className = "treeItems"; + div.append(itemsDiv); + queue.push({ + parent: itemsDiv, + groups: groupId.order + }); + } else { + const group = optionalContentConfig.getGroup(groupId); + const input = document.createElement("input"); + this._bindLink(element, { + groupId, + input + }); + input.type = "checkbox"; + input.checked = group.visible; + const label = document.createElement("label"); + label.textContent = this._normalizeTextContent(group.name); + label.append(input); + element.append(label); + layersCount++; + } + levelData.parent.append(div); + } + } + this._finishRendering(fragment, layersCount, hasAnyNesting); + } + async #updateLayers(promise = null) { + if (!this._optionalContentConfig) { + return; + } + const pdfDocument = this._pdfDocument; + const optionalContentConfig = await (promise || pdfDocument.getOptionalContentConfig()); + if (pdfDocument !== this._pdfDocument) { + return; + } + if (promise) { + if (optionalContentConfig.getHash() === this._optionalContentHash) { + return; + } + } else { + this.eventBus.dispatch("optionalcontentconfig", { + source: this, + promise: Promise.resolve(optionalContentConfig) + }); + } + this.render({ + optionalContentConfig, + pdfDocument: this._pdfDocument + }); + } +} + + +/***/ }), + +/***/ 3234: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ LinkTarget: () => (/* binding */ LinkTarget), +/* harmony export */ PDFLinkService: () => (/* binding */ PDFLinkService), +/* harmony export */ SimpleLinkService: () => (/* binding */ SimpleLinkService) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); + +const DEFAULT_LINK_REL = "noopener noreferrer nofollow"; +const LinkTarget = { + NONE: 0, + SELF: 1, + BLANK: 2, + PARENT: 3, + TOP: 4 +}; +function addLinkAttributes(link, { + url, + target, + rel, + enabled = true +} = {}) { + if (!url || typeof url !== "string") { + throw new Error('A valid "url" parameter must provided.'); + } + if (enabled) { + link.href = link.title = url; + } else { + link.href = ""; + link.title = `Disabled: ${url}`; + link.onclick = () => { + return false; + }; + } + let targetStr = ""; + switch (target) { + case LinkTarget.NONE: + break; + case LinkTarget.SELF: + targetStr = "_self"; + break; + case LinkTarget.BLANK: + targetStr = "_blank"; + break; + case LinkTarget.PARENT: + targetStr = "_parent"; + break; + case LinkTarget.TOP: + targetStr = "_top"; + break; + } + link.target = targetStr; + link.rel = typeof rel === "string" ? rel : DEFAULT_LINK_REL; +} +class PDFLinkService { + #pagesRefCache = new Map(); + constructor({ + eventBus, + externalLinkTarget = null, + externalLinkRel = null, + ignoreDestinationZoom = false + } = {}) { + this.eventBus = eventBus; + this.externalLinkTarget = externalLinkTarget; + this.externalLinkRel = externalLinkRel; + this.externalLinkEnabled = true; + this._ignoreDestinationZoom = ignoreDestinationZoom; + this.baseUrl = null; + this.pdfDocument = null; + this.pdfViewer = null; + this.pdfHistory = null; + } + setDocument(pdfDocument, baseUrl = null) { + this.baseUrl = baseUrl; + this.pdfDocument = pdfDocument; + this.#pagesRefCache.clear(); + } + setViewer(pdfViewer) { + this.pdfViewer = pdfViewer; + } + setHistory(pdfHistory) { + this.pdfHistory = pdfHistory; + } + get pagesCount() { + return this.pdfDocument ? this.pdfDocument.numPages : 0; + } + get page() { + return this.pdfViewer.currentPageNumber; + } + set page(value) { + this.pdfViewer.currentPageNumber = value; + } + get rotation() { + return this.pdfViewer.pagesRotation; + } + set rotation(value) { + this.pdfViewer.pagesRotation = value; + } + get isInPresentationMode() { + return this.pdfViewer.isInPresentationMode; + } + #goToDestinationHelper(rawDest, namedDest = null, explicitDest) { + const destRef = explicitDest[0]; + let pageNumber; + if (typeof destRef === "object" && destRef !== null) { + pageNumber = this._cachedPageNumber(destRef); + if (!pageNumber) { + this.pdfDocument.getPageIndex(destRef).then(pageIndex => { + this.cachePageRef(pageIndex + 1, destRef); + this.#goToDestinationHelper(rawDest, namedDest, explicitDest); + }).catch(() => { + console.error(`PDFLinkService.#goToDestinationHelper: "${destRef}" is not ` + `a valid page reference, for dest="${rawDest}".`); + }); + return; + } + } else if (Number.isInteger(destRef)) { + pageNumber = destRef + 1; + } else { + console.error(`PDFLinkService.#goToDestinationHelper: "${destRef}" is not ` + `a valid destination reference, for dest="${rawDest}".`); + return; + } + if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) { + console.error(`PDFLinkService.#goToDestinationHelper: "${pageNumber}" is not ` + `a valid page number, for dest="${rawDest}".`); + return; + } + if (this.pdfHistory) { + this.pdfHistory.pushCurrentPosition(); + this.pdfHistory.push({ + namedDest, + explicitDest, + pageNumber + }); + } + this.pdfViewer.scrollPageIntoView({ + pageNumber, + destArray: explicitDest, + ignoreDestinationZoom: this._ignoreDestinationZoom + }); + } + async goToDestination(dest) { + if (!this.pdfDocument) { + return; + } + let namedDest, explicitDest; + if (typeof dest === "string") { + namedDest = dest; + explicitDest = await this.pdfDocument.getDestination(dest); + } else { + namedDest = null; + explicitDest = await dest; + } + if (!Array.isArray(explicitDest)) { + console.error(`PDFLinkService.goToDestination: "${explicitDest}" is not ` + `a valid destination array, for dest="${dest}".`); + return; + } + this.#goToDestinationHelper(dest, namedDest, explicitDest); + } + goToPage(val) { + if (!this.pdfDocument) { + return; + } + const pageNumber = typeof val === "string" && this.pdfViewer.pageLabelToPageNumber(val) || val | 0; + if (!(Number.isInteger(pageNumber) && pageNumber > 0 && pageNumber <= this.pagesCount)) { + console.error(`PDFLinkService.goToPage: "${val}" is not a valid page.`); + return; + } + if (this.pdfHistory) { + this.pdfHistory.pushCurrentPosition(); + this.pdfHistory.pushPage(pageNumber); + } + this.pdfViewer.scrollPageIntoView({ + pageNumber + }); + } + addLinkAttributes(link, url, newWindow = false) { + addLinkAttributes(link, { + url, + target: newWindow ? LinkTarget.BLANK : this.externalLinkTarget, + rel: this.externalLinkRel, + enabled: this.externalLinkEnabled + }); + } + getDestinationHash(dest) { + if (typeof dest === "string") { + if (dest.length > 0) { + return this.getAnchorUrl("#" + escape(dest)); + } + } else if (Array.isArray(dest)) { + const str = JSON.stringify(dest); + if (str.length > 0) { + return this.getAnchorUrl("#" + escape(str)); + } + } + return this.getAnchorUrl(""); + } + getAnchorUrl(anchor) { + return this.baseUrl ? this.baseUrl + anchor : anchor; + } + setHash(hash) { + if (!this.pdfDocument) { + return; + } + let pageNumber, dest; + if (hash.includes("=")) { + const params = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.parseQueryString)(hash); + if (params.has("search")) { + const query = params.get("search").replaceAll('"', ""), + phrase = params.get("phrase") === "true"; + this.eventBus.dispatch("findfromurlhash", { + source: this, + query: phrase ? query : query.match(/\S+/g) + }); + } + if (params.has("page")) { + pageNumber = params.get("page") | 0 || 1; + } + if (params.has("zoom")) { + const zoomArgs = params.get("zoom").split(","); + const zoomArg = zoomArgs[0]; + const zoomArgNumber = parseFloat(zoomArg); + if (!zoomArg.includes("Fit")) { + dest = [null, { + name: "XYZ" + }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null, zoomArgs.length > 2 ? zoomArgs[2] | 0 : null, zoomArgNumber ? zoomArgNumber / 100 : zoomArg]; + } else if (zoomArg === "Fit" || zoomArg === "FitB") { + dest = [null, { + name: zoomArg + }]; + } else if (zoomArg === "FitH" || zoomArg === "FitBH" || zoomArg === "FitV" || zoomArg === "FitBV") { + dest = [null, { + name: zoomArg + }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null]; + } else if (zoomArg === "FitR") { + if (zoomArgs.length !== 5) { + console.error('PDFLinkService.setHash: Not enough parameters for "FitR".'); + } else { + dest = [null, { + name: zoomArg + }, zoomArgs[1] | 0, zoomArgs[2] | 0, zoomArgs[3] | 0, zoomArgs[4] | 0]; + } + } else { + console.error(`PDFLinkService.setHash: "${zoomArg}" is not a valid zoom value.`); + } + } + if (dest) { + this.pdfViewer.scrollPageIntoView({ + pageNumber: pageNumber || this.page, + destArray: dest, + allowNegativeOffset: true + }); + } else if (pageNumber) { + this.page = pageNumber; + } + if (params.has("pagemode")) { + this.eventBus.dispatch("pagemode", { + source: this, + mode: params.get("pagemode") + }); + } + if (params.has("nameddest")) { + this.goToDestination(params.get("nameddest")); + } + return; + } + dest = unescape(hash); + try { + dest = JSON.parse(dest); + if (!Array.isArray(dest)) { + dest = dest.toString(); + } + } catch {} + if (typeof dest === "string" || PDFLinkService.#isValidExplicitDestination(dest)) { + this.goToDestination(dest); + return; + } + console.error(`PDFLinkService.setHash: "${unescape(hash)}" is not a valid destination.`); + } + executeNamedAction(action) { + switch (action) { + case "GoBack": + this.pdfHistory?.back(); + break; + case "GoForward": + this.pdfHistory?.forward(); + break; + case "NextPage": + this.pdfViewer.nextPage(); + break; + case "PrevPage": + this.pdfViewer.previousPage(); + break; + case "LastPage": + this.page = this.pagesCount; + break; + case "FirstPage": + this.page = 1; + break; + default: + break; + } + this.eventBus.dispatch("namedaction", { + source: this, + action + }); + } + async executeSetOCGState(action) { + const pdfDocument = this.pdfDocument; + const optionalContentConfig = await this.pdfViewer.optionalContentConfigPromise; + if (pdfDocument !== this.pdfDocument) { + return; + } + let operator; + for (const elem of action.state) { + switch (elem) { + case "ON": + case "OFF": + case "Toggle": + operator = elem; + continue; + } + switch (operator) { + case "ON": + optionalContentConfig.setVisibility(elem, true); + break; + case "OFF": + optionalContentConfig.setVisibility(elem, false); + break; + case "Toggle": + const group = optionalContentConfig.getGroup(elem); + if (group) { + optionalContentConfig.setVisibility(elem, !group.visible); + } + break; + } + } + this.pdfViewer.optionalContentConfigPromise = Promise.resolve(optionalContentConfig); + } + cachePageRef(pageNum, pageRef) { + if (!pageRef) { + return; + } + const refStr = pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`; + this.#pagesRefCache.set(refStr, pageNum); + } + _cachedPageNumber(pageRef) { + if (!pageRef) { + return null; + } + const refStr = pageRef.gen === 0 ? `${pageRef.num}R` : `${pageRef.num}R${pageRef.gen}`; + return this.#pagesRefCache.get(refStr) || null; + } + static #isValidExplicitDestination(dest) { + if (!Array.isArray(dest)) { + return false; + } + const destLength = dest.length; + if (destLength < 2) { + return false; + } + const page = dest[0]; + if (!(typeof page === "object" && Number.isInteger(page.num) && Number.isInteger(page.gen)) && !(Number.isInteger(page) && page >= 0)) { + return false; + } + const zoom = dest[1]; + if (!(typeof zoom === "object" && typeof zoom.name === "string")) { + return false; + } + let allowNull = true; + switch (zoom.name) { + case "XYZ": + if (destLength !== 5) { + return false; + } + break; + case "Fit": + case "FitB": + return destLength === 2; + case "FitH": + case "FitBH": + case "FitV": + case "FitBV": + if (destLength !== 3) { + return false; + } + break; + case "FitR": + if (destLength !== 6) { + return false; + } + allowNull = false; + break; + default: + return false; + } + for (let i = 2; i < destLength; i++) { + const param = dest[i]; + if (!(typeof param === "number" || allowNull && param === null)) { + return false; + } + } + return true; + } +} +class SimpleLinkService { + constructor() { + this.externalLinkEnabled = true; + } + get pagesCount() { + return 0; + } + get page() { + return 0; + } + set page(value) {} + get rotation() { + return 0; + } + set rotation(value) {} + get isInPresentationMode() { + return false; + } + async goToDestination(dest) {} + goToPage(val) {} + addLinkAttributes(link, url, newWindow = false) { + addLinkAttributes(link, { + url, + enabled: this.externalLinkEnabled + }); + } + getDestinationHash(dest) { + return "#"; + } + getAnchorUrl(hash) { + return "#"; + } + setHash(hash) {} + executeNamedAction(action) {} + executeSetOCGState(action) {} + cachePageRef(pageNum, pageRef) {} +} + + +/***/ }), + +/***/ 1141: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFOutlineViewer: () => (/* binding */ PDFOutlineViewer) +/* harmony export */ }); +/* harmony import */ var _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9415); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4927); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + + +class PDFOutlineViewer extends _base_tree_viewer_js__WEBPACK_IMPORTED_MODULE_0__.BaseTreeViewer { + constructor(options) { + super(options); + this.linkService = options.linkService; + this.downloadManager = options.downloadManager; + this.eventBus._on("toggleoutlinetree", this._toggleAllTreeItems.bind(this)); + this.eventBus._on("currentoutlineitem", this._currentOutlineItem.bind(this)); + this.eventBus._on("pagechanging", evt => { + this._currentPageNumber = evt.pageNumber; + }); + this.eventBus._on("pagesloaded", evt => { + this._isPagesLoaded = !!evt.pagesCount; + if (this._currentOutlineItemCapability && !this._currentOutlineItemCapability.settled) { + this._currentOutlineItemCapability.resolve(this._isPagesLoaded); + } + }); + this.eventBus._on("sidebarviewchanged", evt => { + this._sidebarView = evt.view; + }); + } + reset() { + super.reset(); + this._outline = null; + this._pageNumberToDestHashCapability = null; + this._currentPageNumber = 1; + this._isPagesLoaded = null; + if (this._currentOutlineItemCapability && !this._currentOutlineItemCapability.settled) { + this._currentOutlineItemCapability.resolve(false); + } + this._currentOutlineItemCapability = null; + } + _dispatchEvent(outlineCount) { + this._currentOutlineItemCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(); + if (outlineCount === 0 || this._pdfDocument?.loadingParams.disableAutoFetch) { + this._currentOutlineItemCapability.resolve(false); + } else if (this._isPagesLoaded !== null) { + this._currentOutlineItemCapability.resolve(this._isPagesLoaded); + } + this.eventBus.dispatch("outlineloaded", { + source: this, + outlineCount, + currentOutlineItemPromise: this._currentOutlineItemCapability.promise + }); + } + _bindLink(element, { + url, + newWindow, + action, + attachment, + dest, + setOCGState + }) { + const { + linkService + } = this; + if (url) { + linkService.addLinkAttributes(element, url, newWindow); + return; + } + if (action) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + linkService.executeNamedAction(action); + return false; + }; + return; + } + if (attachment) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + this.downloadManager.openOrDownloadData(attachment.content, attachment.filename); + return false; + }; + return; + } + if (setOCGState) { + element.href = linkService.getAnchorUrl(""); + element.onclick = () => { + linkService.executeSetOCGState(setOCGState); + return false; + }; + return; + } + element.href = linkService.getDestinationHash(dest); + element.onclick = evt => { + this._updateCurrentTreeItem(evt.target.parentNode); + if (dest) { + linkService.goToDestination(dest); + } + return false; + }; + } + _setStyles(element, { + bold, + italic + }) { + if (bold) { + element.style.fontWeight = "bold"; + } + if (italic) { + element.style.fontStyle = "italic"; + } + } + _addToggleButton(div, { + count, + items + }) { + let hidden = false; + if (count < 0) { + let totalCount = items.length; + if (totalCount > 0) { + const queue = [...items]; + while (queue.length > 0) { + const { + count: nestedCount, + items: nestedItems + } = queue.shift(); + if (nestedCount > 0 && nestedItems.length > 0) { + totalCount += nestedItems.length; + queue.push(...nestedItems); + } + } + } + if (Math.abs(count) === totalCount) { + hidden = true; + } + } + super._addToggleButton(div, hidden); + } + _toggleAllTreeItems() { + if (!this._outline) { + return; + } + super._toggleAllTreeItems(); + } + render({ + outline, + pdfDocument + }) { + if (this._outline) { + this.reset(); + } + this._outline = outline || null; + this._pdfDocument = pdfDocument || null; + if (!outline) { + this._dispatchEvent(0); + return; + } + const fragment = document.createDocumentFragment(); + const queue = [{ + parent: fragment, + items: outline + }]; + let outlineCount = 0, + hasAnyNesting = false; + while (queue.length > 0) { + const levelData = queue.shift(); + for (const item of levelData.items) { + const div = document.createElement("div"); + div.className = "treeItem"; + const element = document.createElement("a"); + this._bindLink(element, item); + this._setStyles(element, item); + element.textContent = this._normalizeTextContent(item.title); + div.append(element); + if (item.items.length > 0) { + hasAnyNesting = true; + this._addToggleButton(div, item); + const itemsDiv = document.createElement("div"); + itemsDiv.className = "treeItems"; + div.append(itemsDiv); + queue.push({ + parent: itemsDiv, + items: item.items + }); + } + levelData.parent.append(div); + outlineCount++; + } + } + this._finishRendering(fragment, outlineCount, hasAnyNesting); + } + async _currentOutlineItem() { + if (!this._isPagesLoaded) { + throw new Error("_currentOutlineItem: All pages have not been loaded."); + } + if (!this._outline || !this._pdfDocument) { + return; + } + const pageNumberToDestHash = await this._getPageNumberToDestHash(this._pdfDocument); + if (!pageNumberToDestHash) { + return; + } + this._updateCurrentTreeItem(null); + if (this._sidebarView !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.SidebarView.OUTLINE) { + return; + } + for (let i = this._currentPageNumber; i > 0; i--) { + const destHash = pageNumberToDestHash.get(i); + if (!destHash) { + continue; + } + const linkElement = this.container.querySelector(`a[href="${destHash}"]`); + if (!linkElement) { + continue; + } + this._scrollToCurrentTreeItem(linkElement.parentNode); + break; + } + } + async _getPageNumberToDestHash(pdfDocument) { + if (this._pageNumberToDestHashCapability) { + return this._pageNumberToDestHashCapability.promise; + } + this._pageNumberToDestHashCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(); + const pageNumberToDestHash = new Map(), + pageNumberNesting = new Map(); + const queue = [{ + nesting: 0, + items: this._outline + }]; + while (queue.length > 0) { + const levelData = queue.shift(), + currentNesting = levelData.nesting; + for (const { + dest, + items + } of levelData.items) { + let explicitDest, pageNumber; + if (typeof dest === "string") { + explicitDest = await pdfDocument.getDestination(dest); + if (pdfDocument !== this._pdfDocument) { + return null; + } + } else { + explicitDest = dest; + } + if (Array.isArray(explicitDest)) { + const [destRef] = explicitDest; + if (typeof destRef === "object" && destRef !== null) { + pageNumber = this.linkService._cachedPageNumber(destRef); + if (!pageNumber) { + try { + pageNumber = (await pdfDocument.getPageIndex(destRef)) + 1; + if (pdfDocument !== this._pdfDocument) { + return null; + } + this.linkService.cachePageRef(pageNumber, destRef); + } catch {} + } + } else if (Number.isInteger(destRef)) { + pageNumber = destRef + 1; + } + if (Number.isInteger(pageNumber) && (!pageNumberToDestHash.has(pageNumber) || currentNesting > pageNumberNesting.get(pageNumber))) { + const destHash = this.linkService.getDestinationHash(dest); + pageNumberToDestHash.set(pageNumber, destHash); + pageNumberNesting.set(pageNumber, currentNesting); + } + } + if (items.length > 0) { + queue.push({ + nesting: currentNesting + 1, + items + }); + } + } + } + this._pageNumberToDestHashCapability.resolve(pageNumberToDestHash.size > 0 ? pageNumberToDestHash : null); + return this._pageNumberToDestHashCapability.promise; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 6732: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFPageView: () => (/* binding */ PDFPageView) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +/* harmony import */ var _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2640); +/* harmony import */ var _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6735); +/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8961); +/* harmony import */ var _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(758); +/* harmony import */ var web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7910); +/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(3234); +/* harmony import */ var _struct_tree_layer_builder_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(7498); +/* harmony import */ var _text_accessibility_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(4630); +/* harmony import */ var _text_highlighter_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(4274); +/* harmony import */ var _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(1013); +/* harmony import */ var _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(8012); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__, _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__, _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__, _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__]); +([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__, _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__, _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__, _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + + + + + + + + + + + +const MAX_CANVAS_PIXELS = _app_options_js__WEBPACK_IMPORTED_MODULE_4__.compatibilityParams.maxCanvasPixels || 16777216; +const DEFAULT_LAYER_PROPERTIES = null; +class PDFPageView { + #annotationMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS; + #hasRestrictedScaling = false; + #layerProperties = null; + #loadingId = null; + #previousRotation = null; + #renderError = null; + #renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL; + #textLayerMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE; + #useThumbnailCanvas = { + directDrawing: true, + initialOptionalContent: true, + regularAnnotations: true + }; + #viewportMap = new WeakMap(); + constructor(options) { + const container = options.container; + const defaultViewport = options.defaultViewport; + this.id = options.id; + this.renderingId = "page" + this.id; + this.#layerProperties = options.layerProperties || DEFAULT_LAYER_PROPERTIES; + this.pdfPage = null; + this.pageLabel = null; + this.rotation = 0; + this.scale = options.scale || _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + this._optionalContentConfigPromise = options.optionalContentConfigPromise || null; + this.#textLayerMode = options.textLayerMode ?? _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE; + this.#annotationMode = options.annotationMode ?? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS; + this.imageResourcesPath = options.imageResourcesPath || ""; + this.isOffscreenCanvasSupported = options.isOffscreenCanvasSupported ?? true; + this.maxCanvasPixels = options.maxCanvasPixels ?? MAX_CANVAS_PIXELS; + this.pageColors = options.pageColors || null; + this.eventBus = options.eventBus; + this.renderingQueue = options.renderingQueue; + this.l10n = options.l10n || web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__.NullL10n; + this.renderTask = null; + this.resume = null; + this._isStandalone = !this.renderingQueue?.hasViewer(); + this._container = container; + this._annotationCanvasMap = null; + this.annotationLayer = null; + this.annotationEditorLayer = null; + this.textLayer = null; + this.zoomLayer = null; + this.xfaLayer = null; + this.structTreeLayer = null; + this.drawLayer = null; + const div = document.createElement("div"); + div.className = "page"; + div.setAttribute("data-page-number", this.id); + div.setAttribute("role", "region"); + div.setAttribute("data-l10n-id", "pdfjs-page-landmark"); + div.setAttribute("data-l10n-args", JSON.stringify({ + page: this.id + })); + this.div = div; + this.#setDimensions(); + container?.append(div); + if (this._isStandalone) { + container?.style.setProperty("--scale-factor", this.scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS); + const { + optionalContentConfigPromise + } = options; + if (optionalContentConfigPromise) { + optionalContentConfigPromise.then(optionalContentConfig => { + if (optionalContentConfigPromise !== this._optionalContentConfigPromise) { + return; + } + this.#useThumbnailCanvas.initialOptionalContent = optionalContentConfig.hasInitialVisibility; + }); + } + if (this.l10n === web_l10n_utils__WEBPACK_IMPORTED_MODULE_6__.NullL10n) { + this.l10n.translate(this.div); + } + } + } + get renderingState() { + return this.#renderingState; + } + set renderingState(state) { + if (state === this.#renderingState) { + return; + } + this.#renderingState = state; + if (this.#loadingId) { + clearTimeout(this.#loadingId); + this.#loadingId = null; + } + switch (state) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.PAUSED: + this.div.classList.remove("loading"); + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING: + this.div.classList.add("loadingIcon"); + this.#loadingId = setTimeout(() => { + this.div.classList.add("loading"); + this.#loadingId = null; + }, 0); + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL: + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED: + this.div.classList.remove("loadingIcon", "loading"); + break; + } + } + #setDimensions() { + const { + viewport + } = this; + if (this.pdfPage) { + if (this.#previousRotation === viewport.rotation) { + return; + } + this.#previousRotation = viewport.rotation; + } + (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.setLayerDimensions)(this.div, viewport, true, false); + } + setPdfPage(pdfPage) { + if (this._isStandalone && (this.pageColors?.foreground === "CanvasText" || this.pageColors?.background === "Canvas")) { + this._container?.style.setProperty("--hcm-highlight-filter", pdfPage.filterFactory.addHighlightHCMFilter("CanvasText", "Canvas", "HighlightText", "Highlight")); + } + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport({ + scale: this.scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS, + rotation: totalRotation + }); + this.#setDimensions(); + this.reset(); + } + destroy() { + this.reset(); + this.pdfPage?.cleanup(); + } + get _textHighlighter() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_textHighlighter", new _text_highlighter_js__WEBPACK_IMPORTED_MODULE_12__.TextHighlighter({ + pageIndex: this.id - 1, + eventBus: this.eventBus, + findController: this.#layerProperties.findController + })); + } + async #renderAnnotationLayer() { + let error = null; + try { + await this.annotationLayer.render(this.viewport, "display"); + } catch (ex) { + console.error(`#renderAnnotationLayer: "${ex}".`); + error = ex; + } finally { + this.eventBus.dispatch("annotationlayerrendered", { + source: this, + pageNumber: this.id, + error + }); + } + } + async #renderAnnotationEditorLayer() { + let error = null; + try { + await this.annotationEditorLayer.render(this.viewport, "display"); + } catch (ex) { + console.error(`#renderAnnotationEditorLayer: "${ex}".`); + error = ex; + } finally { + this.eventBus.dispatch("annotationeditorlayerrendered", { + source: this, + pageNumber: this.id, + error + }); + } + } + async #renderDrawLayer() { + try { + await this.drawLayer.render("display"); + } catch (ex) { + console.error(`#renderDrawLayer: "${ex}".`); + } + } + async #renderXfaLayer() { + let error = null; + try { + const result = await this.xfaLayer.render(this.viewport, "display"); + if (result?.textDivs && this._textHighlighter) { + this.#buildXfaTextContentItems(result.textDivs); + } + } catch (ex) { + console.error(`#renderXfaLayer: "${ex}".`); + error = ex; + } finally { + if (this.xfaLayer?.div) { + this.l10n.pause(); + this.div.append(this.xfaLayer.div); + this.l10n.resume(); + } + this.eventBus.dispatch("xfalayerrendered", { + source: this, + pageNumber: this.id, + error + }); + } + } + async #renderTextLayer() { + const { + pdfPage, + textLayer, + viewport + } = this; + if (!textLayer) { + return; + } + let error = null; + try { + if (!textLayer.renderingDone) { + const readableStream = pdfPage.streamTextContent({ + includeMarkedContent: true, + disableNormalization: true + }); + textLayer.setTextContentSource(readableStream); + } + await textLayer.render(viewport); + } catch (ex) { + if (ex instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AbortException) { + return; + } + console.error(`#renderTextLayer: "${ex}".`); + error = ex; + } + this.eventBus.dispatch("textlayerrendered", { + source: this, + pageNumber: this.id, + numTextDivs: textLayer.numTextDivs, + error + }); + this.#renderStructTreeLayer(); + } + async #renderStructTreeLayer() { + if (!this.textLayer) { + return; + } + this.structTreeLayer ||= new _struct_tree_layer_builder_js__WEBPACK_IMPORTED_MODULE_8__.StructTreeLayerBuilder(); + const tree = await (!this.structTreeLayer.renderingDone ? this.pdfPage.getStructTree() : null); + const treeDom = this.structTreeLayer?.render(tree); + if (treeDom) { + this.l10n.pause(); + this.canvas?.append(treeDom); + this.l10n.resume(); + } + this.structTreeLayer?.show(); + } + async #buildXfaTextContentItems(textDivs) { + const text = await this.pdfPage.getTextContent(); + const items = []; + for (const item of text.items) { + items.push(item.str); + } + this._textHighlighter.setTextMapping(textDivs, items); + this._textHighlighter.enable(); + } + _resetZoomLayer(removeFromDOM = false) { + if (!this.zoomLayer) { + return; + } + const zoomLayerCanvas = this.zoomLayer.firstChild; + this.#viewportMap.delete(zoomLayerCanvas); + zoomLayerCanvas.width = 0; + zoomLayerCanvas.height = 0; + if (removeFromDOM) { + this.zoomLayer.remove(); + } + this.zoomLayer = null; + } + reset({ + keepZoomLayer = false, + keepAnnotationLayer = false, + keepAnnotationEditorLayer = false, + keepXfaLayer = false, + keepTextLayer = false + } = {}) { + this.cancelRendering({ + keepAnnotationLayer, + keepAnnotationEditorLayer, + keepXfaLayer, + keepTextLayer + }); + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL; + const div = this.div; + const childNodes = div.childNodes, + zoomLayerNode = keepZoomLayer && this.zoomLayer || null, + annotationLayerNode = keepAnnotationLayer && this.annotationLayer?.div || null, + annotationEditorLayerNode = keepAnnotationEditorLayer && this.annotationEditorLayer?.div || null, + xfaLayerNode = keepXfaLayer && this.xfaLayer?.div || null, + textLayerNode = keepTextLayer && this.textLayer?.div || null; + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + switch (node) { + case zoomLayerNode: + case annotationLayerNode: + case annotationEditorLayerNode: + case xfaLayerNode: + case textLayerNode: + continue; + } + node.remove(); + } + div.removeAttribute("data-loaded"); + if (annotationLayerNode) { + this.annotationLayer.hide(); + } + if (annotationEditorLayerNode) { + this.annotationEditorLayer.hide(); + } + if (xfaLayerNode) { + this.xfaLayer.hide(); + } + if (textLayerNode) { + this.textLayer.hide(); + } + this.structTreeLayer?.hide(); + if (!zoomLayerNode) { + if (this.canvas) { + this.#viewportMap.delete(this.canvas); + this.canvas.width = 0; + this.canvas.height = 0; + delete this.canvas; + } + this._resetZoomLayer(); + } + } + update({ + scale = 0, + rotation = null, + optionalContentConfigPromise = null, + drawingDelay = -1 + }) { + this.scale = scale || this.scale; + if (typeof rotation === "number") { + this.rotation = rotation; + } + if (optionalContentConfigPromise instanceof Promise) { + this._optionalContentConfigPromise = optionalContentConfigPromise; + optionalContentConfigPromise.then(optionalContentConfig => { + if (optionalContentConfigPromise !== this._optionalContentConfigPromise) { + return; + } + this.#useThumbnailCanvas.initialOptionalContent = optionalContentConfig.hasInitialVisibility; + }); + } + this.#useThumbnailCanvas.directDrawing = true; + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: this.scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS, + rotation: totalRotation + }); + this.#setDimensions(); + if (this._isStandalone) { + this._container?.style.setProperty("--scale-factor", this.viewport.scale); + } + if (this.canvas) { + let onlyCssZoom = false; + if (this.#hasRestrictedScaling) { + if (this.maxCanvasPixels === 0) { + onlyCssZoom = true; + } else if (this.maxCanvasPixels > 0) { + const { + width, + height + } = this.viewport; + const { + sx, + sy + } = this.outputScale; + onlyCssZoom = (Math.floor(width) * sx | 0) * (Math.floor(height) * sy | 0) > this.maxCanvasPixels; + } + } + const postponeDrawing = !onlyCssZoom && drawingDelay >= 0 && drawingDelay < 1000; + if (postponeDrawing || onlyCssZoom) { + if (postponeDrawing && this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED) { + this.cancelRendering({ + keepZoomLayer: true, + keepAnnotationLayer: true, + keepAnnotationEditorLayer: true, + keepXfaLayer: true, + keepTextLayer: true, + cancelExtraDelay: drawingDelay + }); + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED; + this.#useThumbnailCanvas.directDrawing = false; + } + this.cssTransform({ + target: this.canvas, + redrawAnnotationLayer: true, + redrawAnnotationEditorLayer: true, + redrawXfaLayer: true, + redrawTextLayer: !postponeDrawing, + hideTextLayer: postponeDrawing + }); + if (postponeDrawing) { + return; + } + this.eventBus.dispatch("pagerendered", { + source: this, + pageNumber: this.id, + cssTransform: true, + timestamp: performance.now(), + error: this.#renderError + }); + return; + } + if (!this.zoomLayer && !this.canvas.hidden) { + this.zoomLayer = this.canvas.parentNode; + this.zoomLayer.style.position = "absolute"; + } + } + if (this.zoomLayer) { + this.cssTransform({ + target: this.zoomLayer.firstChild + }); + } + this.reset({ + keepZoomLayer: true, + keepAnnotationLayer: true, + keepAnnotationEditorLayer: true, + keepXfaLayer: true, + keepTextLayer: true + }); + } + cancelRendering({ + keepAnnotationLayer = false, + keepAnnotationEditorLayer = false, + keepXfaLayer = false, + keepTextLayer = false, + cancelExtraDelay = 0 + } = {}) { + if (this.renderTask) { + this.renderTask.cancel(cancelExtraDelay); + this.renderTask = null; + } + this.resume = null; + if (this.textLayer && (!keepTextLayer || !this.textLayer.div)) { + this.textLayer.cancel(); + this.textLayer = null; + } + if (this.structTreeLayer && !this.textLayer) { + this.structTreeLayer = null; + } + if (this.annotationLayer && (!keepAnnotationLayer || !this.annotationLayer.div)) { + this.annotationLayer.cancel(); + this.annotationLayer = null; + this._annotationCanvasMap = null; + } + if (this.annotationEditorLayer && (!keepAnnotationEditorLayer || !this.annotationEditorLayer.div)) { + if (this.drawLayer) { + this.drawLayer.cancel(); + this.drawLayer = null; + } + this.annotationEditorLayer.cancel(); + this.annotationEditorLayer = null; + } + if (this.xfaLayer && (!keepXfaLayer || !this.xfaLayer.div)) { + this.xfaLayer.cancel(); + this.xfaLayer = null; + this._textHighlighter?.disable(); + } + } + cssTransform({ + target, + redrawAnnotationLayer = false, + redrawAnnotationEditorLayer = false, + redrawXfaLayer = false, + redrawTextLayer = false, + hideTextLayer = false + }) { + if (!target.hasAttribute("zooming")) { + target.setAttribute("zooming", true); + const { + style + } = target; + style.width = style.height = ""; + } + const originalViewport = this.#viewportMap.get(target); + if (this.viewport !== originalViewport) { + const relativeRotation = this.viewport.rotation - originalViewport.rotation; + const absRotation = Math.abs(relativeRotation); + let scaleX = 1, + scaleY = 1; + if (absRotation === 90 || absRotation === 270) { + const { + width, + height + } = this.viewport; + scaleX = height / width; + scaleY = width / height; + } + target.style.transform = `rotate(${relativeRotation}deg) scale(${scaleX}, ${scaleY})`; + } + if (redrawAnnotationLayer && this.annotationLayer) { + this.#renderAnnotationLayer(); + } + if (redrawAnnotationEditorLayer && this.annotationEditorLayer) { + if (this.drawLayer) { + this.#renderDrawLayer(); + } + this.#renderAnnotationEditorLayer(); + } + if (redrawXfaLayer && this.xfaLayer) { + this.#renderXfaLayer(); + } + if (this.textLayer) { + if (hideTextLayer) { + this.textLayer.hide(); + this.structTreeLayer?.hide(); + } else if (redrawTextLayer) { + this.#renderTextLayer(); + } + } + } + get width() { + return this.viewport.width; + } + get height() { + return this.viewport.height; + } + getPagePoint(x, y) { + return this.viewport.convertToPdfPoint(x, y); + } + async #finishRenderTask(renderTask, error = null) { + if (renderTask === this.renderTask) { + this.renderTask = null; + } + if (error instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.RenderingCancelledException) { + this.#renderError = null; + return; + } + this.#renderError = error; + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED; + this._resetZoomLayer(true); + this.#useThumbnailCanvas.regularAnnotations = !renderTask.separateAnnots; + this.eventBus.dispatch("pagerendered", { + source: this, + pageNumber: this.id, + cssTransform: false, + timestamp: performance.now(), + error: this.#renderError + }); + if (error) { + throw error; + } + } + async draw() { + if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL) { + console.error("Must be in new state before drawing"); + this.reset(); + } + const { + div, + l10n, + pageColors, + pdfPage, + viewport + } = this; + if (!pdfPage) { + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED; + throw new Error("pdfPage is not loaded"); + } + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING; + const canvasWrapper = document.createElement("div"); + canvasWrapper.classList.add("canvasWrapper"); + div.append(canvasWrapper); + if (!this.textLayer && this.#textLayerMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.DISABLE && !pdfPage.isPureXfa) { + this._accessibilityManager ||= new _text_accessibility_js__WEBPACK_IMPORTED_MODULE_9__.TextAccessibilityManager(); + this.textLayer = new _text_layer_builder_js__WEBPACK_IMPORTED_MODULE_10__.TextLayerBuilder({ + highlighter: this._textHighlighter, + accessibilityManager: this._accessibilityManager, + isOffscreenCanvasSupported: this.isOffscreenCanvasSupported, + enablePermissions: this.#textLayerMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE_PERMISSIONS + }); + this.textLayer.onAppend = textLayerDiv => { + this.l10n.pause(); + this.div.append(textLayerDiv); + this.l10n.resume(); + }; + } + if (!this.annotationLayer && this.#annotationMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.DISABLE) { + const { + annotationStorage, + downloadManager, + enableScripting, + fieldObjectsPromise, + hasJSActionsPromise, + linkService + } = this.#layerProperties; + this._annotationCanvasMap ||= new Map(); + this.annotationLayer = new _annotation_layer_builder_js__WEBPACK_IMPORTED_MODULE_3__.AnnotationLayerBuilder({ + pageDiv: div, + pdfPage, + annotationStorage, + imageResourcesPath: this.imageResourcesPath, + renderForms: this.#annotationMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS, + linkService, + downloadManager, + enableScripting, + hasJSActionsPromise, + fieldObjectsPromise, + annotationCanvasMap: this._annotationCanvasMap, + accessibilityManager: this._accessibilityManager + }); + } + const renderContinueCallback = cont => { + showCanvas?.(false); + if (this.renderingQueue && !this.renderingQueue.isHighestPriority(this)) { + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.PAUSED; + this.resume = () => { + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + const { + width, + height + } = viewport; + const canvas = document.createElement("canvas"); + canvas.setAttribute("role", "presentation"); + canvas.hidden = true; + const hasHCM = !!(pageColors?.background && pageColors?.foreground); + let showCanvas = isLastShow => { + if (!hasHCM || isLastShow) { + canvas.hidden = false; + showCanvas = null; + } + }; + canvasWrapper.append(canvas); + this.canvas = canvas; + const ctx = canvas.getContext("2d", { + alpha: false + }); + const outputScale = this.outputScale = new _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.OutputScale(); + if (this.maxCanvasPixels === 0) { + const invScale = 1 / this.scale; + outputScale.sx *= invScale; + outputScale.sy *= invScale; + this.#hasRestrictedScaling = true; + } else if (this.maxCanvasPixels > 0) { + const pixelsInViewport = width * height; + const maxScale = Math.sqrt(this.maxCanvasPixels / pixelsInViewport); + if (outputScale.sx > maxScale || outputScale.sy > maxScale) { + outputScale.sx = maxScale; + outputScale.sy = maxScale; + this.#hasRestrictedScaling = true; + } else { + this.#hasRestrictedScaling = false; + } + } + const sfx = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.approximateFraction)(outputScale.sx); + const sfy = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.approximateFraction)(outputScale.sy); + canvas.width = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(width * outputScale.sx, sfx[0]); + canvas.height = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(height * outputScale.sy, sfy[0]); + const { + style + } = canvas; + style.width = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(width, sfx[1]) + "px"; + style.height = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.roundToDivide)(height, sfy[1]) + "px"; + this.#viewportMap.set(canvas, viewport); + const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null; + const renderContext = { + canvasContext: ctx, + transform, + viewport, + annotationMode: this.#annotationMode, + optionalContentConfigPromise: this._optionalContentConfigPromise, + annotationCanvasMap: this._annotationCanvasMap, + pageColors + }; + const renderTask = this.renderTask = this.pdfPage.render(renderContext); + renderTask.onContinue = renderContinueCallback; + const resultPromise = renderTask.promise.then(async () => { + showCanvas?.(true); + await this.#finishRenderTask(renderTask); + this.#renderTextLayer(); + if (this.annotationLayer) { + await this.#renderAnnotationLayer(); + } + const { + annotationEditorUIManager + } = this.#layerProperties; + if (!annotationEditorUIManager) { + return; + } + this.drawLayer ||= new _draw_layer_builder_js__WEBPACK_IMPORTED_MODULE_5__.DrawLayerBuilder({ + pageIndex: this.id + }); + await this.#renderDrawLayer(); + this.drawLayer.setParent(canvasWrapper); + if (!this.annotationEditorLayer) { + this.annotationEditorLayer = new _annotation_editor_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__.AnnotationEditorLayerBuilder({ + uiManager: annotationEditorUIManager, + pageDiv: div, + pdfPage, + l10n, + accessibilityManager: this._accessibilityManager, + annotationLayer: this.annotationLayer?.annotationLayer, + textLayer: this.textLayer, + drawLayer: this.drawLayer.getDrawLayer() + }); + } + this.#renderAnnotationEditorLayer(); + }, error => { + if (!(error instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.RenderingCancelledException)) { + showCanvas?.(true); + } + return this.#finishRenderTask(renderTask, error); + }); + if (pdfPage.isPureXfa) { + if (!this.xfaLayer) { + const { + annotationStorage, + linkService + } = this.#layerProperties; + this.xfaLayer = new _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_11__.XfaLayerBuilder({ + pdfPage, + annotationStorage, + linkService + }); + } + this.#renderXfaLayer(); + } + div.setAttribute("data-loaded", true); + this.eventBus.dispatch("pagerender", { + source: this, + pageNumber: this.id + }); + return resultPromise; + } + setPageLabel(label) { + this.pageLabel = typeof label === "string" ? label : null; + this.div.setAttribute("data-l10n-args", JSON.stringify({ + page: this.pageLabel ?? this.id + })); + if (this.pageLabel !== null) { + this.div.setAttribute("data-page-label", this.pageLabel); + } else { + this.div.removeAttribute("data-page-label"); + } + } + get thumbnailCanvas() { + const { + directDrawing, + initialOptionalContent, + regularAnnotations + } = this.#useThumbnailCanvas; + return directDrawing && initialOptionalContent && regularAnnotations ? this.canvas : null; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 323: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFPresentationMode: () => (/* binding */ PDFPresentationMode) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +const DELAY_BEFORE_HIDING_CONTROLS = 3000; +const ACTIVE_SELECTOR = "pdfPresentationMode"; +const CONTROLS_SELECTOR = "pdfPresentationModeControls"; +const MOUSE_SCROLL_COOLDOWN_TIME = 50; +const PAGE_SWITCH_THRESHOLD = 0.1; +const SWIPE_MIN_DISTANCE_THRESHOLD = 50; +const SWIPE_ANGLE_THRESHOLD = Math.PI / 6; +class PDFPresentationMode { + #state = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.UNKNOWN; + #args = null; + constructor({ + container, + pdfViewer, + eventBus + }) { + this.container = container; + this.pdfViewer = pdfViewer; + this.eventBus = eventBus; + this.contextMenuOpen = false; + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + this.touchSwipeState = null; + } + async request() { + const { + container, + pdfViewer + } = this; + if (this.active || !pdfViewer.pagesCount || !container.requestFullscreen) { + return false; + } + this.#addFullscreenChangeListeners(); + this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.CHANGING); + const promise = container.requestFullscreen(); + this.#args = { + pageNumber: pdfViewer.currentPageNumber, + scaleValue: pdfViewer.currentScaleValue, + scrollMode: pdfViewer.scrollMode, + spreadMode: null, + annotationEditorMode: null + }; + if (pdfViewer.spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE && !(pdfViewer.pageViewsReady && pdfViewer.hasEqualPageSizes)) { + console.warn("Ignoring Spread modes when entering PresentationMode, " + "since the document may contain varying page sizes."); + this.#args.spreadMode = pdfViewer.spreadMode; + } + if (pdfViewer.annotationEditorMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditorType.DISABLE) { + this.#args.annotationEditorMode = pdfViewer.annotationEditorMode; + } + try { + await promise; + pdfViewer.focus(); + return true; + } catch { + this.#removeFullscreenChangeListeners(); + this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.NORMAL); + } + return false; + } + get active() { + return this.#state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.CHANGING || this.#state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.FULLSCREEN; + } + #mouseWheel(evt) { + if (!this.active) { + return; + } + evt.preventDefault(); + const delta = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.normalizeWheelEventDelta)(evt); + const currentTime = Date.now(); + const storedTime = this.mouseScrollTimeStamp; + if (currentTime > storedTime && currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) { + return; + } + if (this.mouseScrollDelta > 0 && delta < 0 || this.mouseScrollDelta < 0 && delta > 0) { + this.#resetMouseScrollState(); + } + this.mouseScrollDelta += delta; + if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) { + const totalDelta = this.mouseScrollDelta; + this.#resetMouseScrollState(); + const success = totalDelta > 0 ? this.pdfViewer.previousPage() : this.pdfViewer.nextPage(); + if (success) { + this.mouseScrollTimeStamp = currentTime; + } + } + } + #notifyStateChange(state) { + this.#state = state; + this.eventBus.dispatch("presentationmodechanged", { + source: this, + state + }); + } + #enter() { + this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.FULLSCREEN); + this.container.classList.add(ACTIVE_SELECTOR); + setTimeout(() => { + this.pdfViewer.scrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.PAGE; + if (this.#args.spreadMode !== null) { + this.pdfViewer.spreadMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE; + } + this.pdfViewer.currentPageNumber = this.#args.pageNumber; + this.pdfViewer.currentScaleValue = "page-fit"; + if (this.#args.annotationEditorMode !== null) { + this.pdfViewer.annotationEditorMode = { + mode: pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.AnnotationEditorType.NONE + }; + } + }, 0); + this.#addWindowListeners(); + this.#showControls(); + this.contextMenuOpen = false; + window.getSelection().removeAllRanges(); + } + #exit() { + const pageNumber = this.pdfViewer.currentPageNumber; + this.container.classList.remove(ACTIVE_SELECTOR); + setTimeout(() => { + this.#removeFullscreenChangeListeners(); + this.#notifyStateChange(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.NORMAL); + this.pdfViewer.scrollMode = this.#args.scrollMode; + if (this.#args.spreadMode !== null) { + this.pdfViewer.spreadMode = this.#args.spreadMode; + } + this.pdfViewer.currentScaleValue = this.#args.scaleValue; + this.pdfViewer.currentPageNumber = pageNumber; + if (this.#args.annotationEditorMode !== null) { + this.pdfViewer.annotationEditorMode = { + mode: this.#args.annotationEditorMode + }; + } + this.#args = null; + }, 0); + this.#removeWindowListeners(); + this.#hideControls(); + this.#resetMouseScrollState(); + this.contextMenuOpen = false; + } + #mouseDown(evt) { + if (this.contextMenuOpen) { + this.contextMenuOpen = false; + evt.preventDefault(); + return; + } + if (evt.button !== 0) { + return; + } + if (evt.target.href && evt.target.parentNode?.hasAttribute("data-internal-link")) { + return; + } + evt.preventDefault(); + if (evt.shiftKey) { + this.pdfViewer.previousPage(); + } else { + this.pdfViewer.nextPage(); + } + } + #contextMenu() { + this.contextMenuOpen = true; + } + #showControls() { + if (this.controlsTimeout) { + clearTimeout(this.controlsTimeout); + } else { + this.container.classList.add(CONTROLS_SELECTOR); + } + this.controlsTimeout = setTimeout(() => { + this.container.classList.remove(CONTROLS_SELECTOR); + delete this.controlsTimeout; + }, DELAY_BEFORE_HIDING_CONTROLS); + } + #hideControls() { + if (!this.controlsTimeout) { + return; + } + clearTimeout(this.controlsTimeout); + this.container.classList.remove(CONTROLS_SELECTOR); + delete this.controlsTimeout; + } + #resetMouseScrollState() { + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + } + #touchSwipe(evt) { + if (!this.active) { + return; + } + if (evt.touches.length > 1) { + this.touchSwipeState = null; + return; + } + switch (evt.type) { + case "touchstart": + this.touchSwipeState = { + startX: evt.touches[0].pageX, + startY: evt.touches[0].pageY, + endX: evt.touches[0].pageX, + endY: evt.touches[0].pageY + }; + break; + case "touchmove": + if (this.touchSwipeState === null) { + return; + } + this.touchSwipeState.endX = evt.touches[0].pageX; + this.touchSwipeState.endY = evt.touches[0].pageY; + evt.preventDefault(); + break; + case "touchend": + if (this.touchSwipeState === null) { + return; + } + let delta = 0; + const dx = this.touchSwipeState.endX - this.touchSwipeState.startX; + const dy = this.touchSwipeState.endY - this.touchSwipeState.startY; + const absAngle = Math.abs(Math.atan2(dy, dx)); + if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && (absAngle <= SWIPE_ANGLE_THRESHOLD || absAngle >= Math.PI - SWIPE_ANGLE_THRESHOLD)) { + delta = dx; + } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && Math.abs(absAngle - Math.PI / 2) <= SWIPE_ANGLE_THRESHOLD) { + delta = dy; + } + if (delta > 0) { + this.pdfViewer.previousPage(); + } else if (delta < 0) { + this.pdfViewer.nextPage(); + } + break; + } + } + #addWindowListeners() { + this.showControlsBind = this.#showControls.bind(this); + this.mouseDownBind = this.#mouseDown.bind(this); + this.mouseWheelBind = this.#mouseWheel.bind(this); + this.resetMouseScrollStateBind = this.#resetMouseScrollState.bind(this); + this.contextMenuBind = this.#contextMenu.bind(this); + this.touchSwipeBind = this.#touchSwipe.bind(this); + window.addEventListener("mousemove", this.showControlsBind); + window.addEventListener("mousedown", this.mouseDownBind); + window.addEventListener("wheel", this.mouseWheelBind, { + passive: false + }); + window.addEventListener("keydown", this.resetMouseScrollStateBind); + window.addEventListener("contextmenu", this.contextMenuBind); + window.addEventListener("touchstart", this.touchSwipeBind); + window.addEventListener("touchmove", this.touchSwipeBind); + window.addEventListener("touchend", this.touchSwipeBind); + } + #removeWindowListeners() { + window.removeEventListener("mousemove", this.showControlsBind); + window.removeEventListener("mousedown", this.mouseDownBind); + window.removeEventListener("wheel", this.mouseWheelBind, { + passive: false + }); + window.removeEventListener("keydown", this.resetMouseScrollStateBind); + window.removeEventListener("contextmenu", this.contextMenuBind); + window.removeEventListener("touchstart", this.touchSwipeBind); + window.removeEventListener("touchmove", this.touchSwipeBind); + window.removeEventListener("touchend", this.touchSwipeBind); + delete this.showControlsBind; + delete this.mouseDownBind; + delete this.mouseWheelBind; + delete this.resetMouseScrollStateBind; + delete this.contextMenuBind; + delete this.touchSwipeBind; + } + #fullscreenChange() { + if (document.fullscreenElement) { + this.#enter(); + } else { + this.#exit(); + } + } + #addFullscreenChangeListeners() { + this.fullscreenChangeBind = this.#fullscreenChange.bind(this); + window.addEventListener("fullscreenchange", this.fullscreenChangeBind); + } + #removeFullscreenChangeListeners() { + window.removeEventListener("fullscreenchange", this.fullscreenChangeBind); + delete this.fullscreenChangeBind; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1834: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* unused harmony export PDFPrintService */ +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _app_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39); +/* harmony import */ var _print_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4552); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _app_js__WEBPACK_IMPORTED_MODULE_1__, _print_utils_js__WEBPACK_IMPORTED_MODULE_2__]); +([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _app_js__WEBPACK_IMPORTED_MODULE_1__, _print_utils_js__WEBPACK_IMPORTED_MODULE_2__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + +let activeService = null; +let dialog = null; +let overlayManager = null; +function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) { + const scratchCanvas = activeService.scratchCanvas; + const PRINT_UNITS = printResolution / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF; + scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); + scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); + const ctx = scratchCanvas.getContext("2d"); + ctx.save(); + ctx.fillStyle = "rgb(255, 255, 255)"; + ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); + ctx.restore(); + return Promise.all([pdfDocument.getPage(pageNumber), printAnnotationStoragePromise]).then(function ([pdfPage, printAnnotationStorage]) { + const renderContext = { + canvasContext: ctx, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], + viewport: pdfPage.getViewport({ + scale: 1, + rotation: size.rotation + }), + intent: "print", + annotationMode: pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_STORAGE, + optionalContentConfigPromise, + printAnnotationStorage + }; + return pdfPage.render(renderContext).promise; + }); +} +class PDFPrintService { + constructor(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise = null, printAnnotationStoragePromise = null) { + this.pdfDocument = pdfDocument; + this.pagesOverview = pagesOverview; + this.printContainer = printContainer; + this._printResolution = printResolution || 150; + this._optionalContentConfigPromise = optionalContentConfigPromise || pdfDocument.getOptionalContentConfig(); + this._printAnnotationStoragePromise = printAnnotationStoragePromise || Promise.resolve(); + this.currentPage = -1; + this.scratchCanvas = document.createElement("canvas"); + } + layout() { + this.throwIfInactive(); + const body = document.querySelector("body"); + body.setAttribute("data-pdfjsprinting", true); + const { + width, + height + } = this.pagesOverview[0]; + const hasEqualPageSizes = this.pagesOverview.every(size => size.width === width && size.height === height); + if (!hasEqualPageSizes) { + console.warn("Not all pages have the same size. The printed result may be incorrect!"); + } + this.pageStyleSheet = document.createElement("style"); + this.pageStyleSheet.textContent = `@page { size: ${width}pt ${height}pt;}`; + body.append(this.pageStyleSheet); + } + destroy() { + if (activeService !== this) { + return; + } + this.printContainer.textContent = ""; + const body = document.querySelector("body"); + body.removeAttribute("data-pdfjsprinting"); + if (this.pageStyleSheet) { + this.pageStyleSheet.remove(); + this.pageStyleSheet = null; + } + this.scratchCanvas.width = this.scratchCanvas.height = 0; + this.scratchCanvas = null; + activeService = null; + ensureOverlay().then(function () { + if (overlayManager.active === dialog) { + overlayManager.close(dialog); + } + }); + } + renderPages() { + if (this.pdfDocument.isPureXfa) { + (0,_print_utils_js__WEBPACK_IMPORTED_MODULE_2__.getXfaHtmlForPrinting)(this.printContainer, this.pdfDocument); + return Promise.resolve(); + } + const pageCount = this.pagesOverview.length; + const renderNextPage = (resolve, reject) => { + this.throwIfInactive(); + if (++this.currentPage >= pageCount) { + renderProgress(pageCount, pageCount); + resolve(); + return; + } + const index = this.currentPage; + renderProgress(index, pageCount); + renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index], this._printResolution, this._optionalContentConfigPromise, this._printAnnotationStoragePromise).then(this.useRenderedPage.bind(this)).then(function () { + renderNextPage(resolve, reject); + }, reject); + }; + return new Promise(renderNextPage); + } + useRenderedPage() { + this.throwIfInactive(); + const img = document.createElement("img"); + const scratchCanvas = this.scratchCanvas; + if ("toBlob" in scratchCanvas) { + scratchCanvas.toBlob(function (blob) { + img.src = URL.createObjectURL(blob); + }); + } else { + img.src = scratchCanvas.toDataURL(); + } + const wrapper = document.createElement("div"); + wrapper.className = "printedPage"; + wrapper.append(img); + this.printContainer.append(wrapper); + return new Promise(function (resolve, reject) { + img.onload = resolve; + img.onerror = reject; + }); + } + performPrint() { + this.throwIfInactive(); + return new Promise(resolve => { + setTimeout(() => { + if (!this.active) { + resolve(); + return; + } + print.call(window); + setTimeout(resolve, 20); + }, 0); + }); + } + get active() { + return this === activeService; + } + throwIfInactive() { + if (!this.active) { + throw new Error("This print request was cancelled or completed."); + } + } +} +const print = window.print; +window.print = function () { + if (activeService) { + console.warn("Ignored window.print() because of a pending print job."); + return; + } + ensureOverlay().then(function () { + if (activeService) { + overlayManager.open(dialog); + } + }); + try { + dispatchEvent("beforeprint"); + } finally { + if (!activeService) { + console.error("Expected print service to be initialized."); + ensureOverlay().then(function () { + if (overlayManager.active === dialog) { + overlayManager.close(dialog); + } + }); + return; + } + const activeServiceOnEntry = activeService; + activeService.renderPages().then(function () { + return activeServiceOnEntry.performPrint(); + }).catch(function () {}).then(function () { + if (activeServiceOnEntry.active) { + abort(); + } + }); + } +}; +function dispatchEvent(eventType) { + const event = new CustomEvent(eventType, { + bubbles: false, + cancelable: false, + detail: "custom" + }); + window.dispatchEvent(event); +} +function abort() { + if (activeService) { + activeService.destroy(); + dispatchEvent("afterprint"); + } +} +function renderProgress(index, total) { + dialog ||= document.getElementById("printServiceDialog"); + const progress = Math.round(100 * index / total); + const progressBar = dialog.querySelector("progress"); + const progressPerc = dialog.querySelector(".relative-progress"); + progressBar.value = progress; + progressPerc.setAttribute("data-l10n-args", JSON.stringify({ + progress + })); +} +window.addEventListener("keydown", function (event) { + if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) { + window.print(); + event.preventDefault(); + event.stopImmediatePropagation(); + } +}, true); +if ("onbeforeprint" in window) { + const stopPropagationIfNeeded = function (event) { + if (event.detail !== "custom") { + event.stopImmediatePropagation(); + } + }; + window.addEventListener("beforeprint", stopPropagationIfNeeded); + window.addEventListener("afterprint", stopPropagationIfNeeded); +} +let overlayPromise; +function ensureOverlay() { + if (!overlayPromise) { + overlayManager = _app_js__WEBPACK_IMPORTED_MODULE_1__.PDFViewerApplication.overlayManager; + if (!overlayManager) { + throw new Error("The overlay manager has not yet been initialized."); + } + dialog ||= document.getElementById("printServiceDialog"); + overlayPromise = overlayManager.register(dialog, true); + document.getElementById("printCancel").onclick = abort; + dialog.addEventListener("close", abort); + } + return overlayPromise; +} +_app_js__WEBPACK_IMPORTED_MODULE_1__.PDFPrintServiceFactory.instance = { + supportsPrinting: true, + createPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise) { + if (activeService) { + throw new Error("The print service is created and active."); + } + activeService = new PDFPrintService(pdfDocument, pagesOverview, printContainer, printResolution, optionalContentConfigPromise, printAnnotationStoragePromise); + return activeService; + } +}; + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 5119: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFRenderingQueue: () => (/* binding */ PDFRenderingQueue) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +const CLEANUP_TIMEOUT = 30000; +class PDFRenderingQueue { + constructor() { + this.pdfViewer = null; + this.pdfThumbnailViewer = null; + this.onIdle = null; + this.highestPriorityPage = null; + this.idleTimeout = null; + this.printing = false; + this.isThumbnailViewEnabled = false; + Object.defineProperty(this, "hasViewer", { + value: () => !!this.pdfViewer + }); + } + setViewer(pdfViewer) { + this.pdfViewer = pdfViewer; + } + setThumbnailViewer(pdfThumbnailViewer) { + this.pdfThumbnailViewer = pdfThumbnailViewer; + } + isHighestPriority(view) { + return this.highestPriorityPage === view.renderingId; + } + renderHighestPriority(currentlyVisiblePages) { + if (this.idleTimeout) { + clearTimeout(this.idleTimeout); + this.idleTimeout = null; + } + if (this.pdfViewer.forceRendering(currentlyVisiblePages)) { + return; + } + if (this.isThumbnailViewEnabled && this.pdfThumbnailViewer?.forceRendering()) { + return; + } + if (this.printing) { + return; + } + if (this.onIdle) { + this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT); + } + } + getHighestPriority(visible, views, scrolledDown, preRenderExtra = false) { + const visibleViews = visible.views, + numVisible = visibleViews.length; + if (numVisible === 0) { + return null; + } + for (let i = 0; i < numVisible; i++) { + const view = visibleViews[i].view; + if (!this.isViewFinished(view)) { + return view; + } + } + const firstId = visible.first.id, + lastId = visible.last.id; + if (lastId - firstId + 1 > numVisible) { + const visibleIds = visible.ids; + for (let i = 1, ii = lastId - firstId; i < ii; i++) { + const holeId = scrolledDown ? firstId + i : lastId - i; + if (visibleIds.has(holeId)) { + continue; + } + const holeView = views[holeId - 1]; + if (!this.isViewFinished(holeView)) { + return holeView; + } + } + } + let preRenderIndex = scrolledDown ? lastId : firstId - 2; + let preRenderView = views[preRenderIndex]; + if (preRenderView && !this.isViewFinished(preRenderView)) { + return preRenderView; + } + if (preRenderExtra) { + preRenderIndex += scrolledDown ? 1 : -1; + preRenderView = views[preRenderIndex]; + if (preRenderView && !this.isViewFinished(preRenderView)) { + return preRenderView; + } + } + return null; + } + isViewFinished(view) { + return view.renderingState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED; + } + renderView(view) { + switch (view.renderingState) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED: + return false; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.PAUSED: + this.highestPriorityPage = view.renderingId; + view.resume(); + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.RUNNING: + this.highestPriorityPage = view.renderingId; + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.INITIAL: + this.highestPriorityPage = view.renderingId; + view.draw().finally(() => { + this.renderHighestPriority(); + }).catch(reason => { + if (reason instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.RenderingCancelledException) { + return; + } + console.error(`renderView: "${reason}"`); + }); + break; + } + return true; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 2599: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFScriptingManager: () => (/* binding */ PDFScriptingManager) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +class PDFScriptingManager { + #closeCapability = null; + #destroyCapability = null; + #docProperties = null; + #eventBus = null; + #externalServices = null; + #pdfDocument = null; + #pdfViewer = null; + #ready = false; + #scripting = null; + #willPrintCapability = null; + constructor({ + eventBus, + externalServices = null, + docProperties = null + }) { + this.#eventBus = eventBus; + this.#externalServices = externalServices; + this.#docProperties = docProperties; + } + setViewer(pdfViewer) { + this.#pdfViewer = pdfViewer; + } + async setDocument(pdfDocument) { + if (this.#pdfDocument) { + await this.#destroyScripting(); + } + this.#pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + const [objects, calculationOrder, docActions] = await Promise.all([pdfDocument.getFieldObjects(), pdfDocument.getCalculationOrderIds(), pdfDocument.getJSActions()]); + if (!objects && !docActions) { + await this.#destroyScripting(); + return; + } + if (pdfDocument !== this.#pdfDocument) { + return; + } + try { + this.#scripting = this.#initScripting(); + } catch (error) { + console.error(`setDocument: "${error.message}".`); + await this.#destroyScripting(); + return; + } + this._internalEvents.set("updatefromsandbox", event => { + if (event?.source === window) { + this.#updateFromSandbox(event.detail); + } + }); + this._internalEvents.set("dispatcheventinsandbox", event => { + this.#scripting?.dispatchEventInSandbox(event.detail); + }); + this._internalEvents.set("pagechanging", ({ + pageNumber, + previous + }) => { + if (pageNumber === previous) { + return; + } + this.#dispatchPageClose(previous); + this.#dispatchPageOpen(pageNumber); + }); + this._internalEvents.set("pagerendered", ({ + pageNumber + }) => { + if (!this._pageOpenPending.has(pageNumber)) { + return; + } + if (pageNumber !== this.#pdfViewer.currentPageNumber) { + return; + } + this.#dispatchPageOpen(pageNumber); + }); + this._internalEvents.set("pagesdestroy", async () => { + await this.#dispatchPageClose(this.#pdfViewer.currentPageNumber); + await this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "WillClose" + }); + this.#closeCapability?.resolve(); + }); + for (const [name, listener] of this._internalEvents) { + this.#eventBus._on(name, listener); + } + try { + const docProperties = await this.#docProperties(pdfDocument); + if (pdfDocument !== this.#pdfDocument) { + return; + } + await this.#scripting.createSandbox({ + objects, + calculationOrder, + appInfo: { + platform: navigator.platform, + language: navigator.language + }, + docInfo: { + ...docProperties, + actions: docActions + } + }); + this.#eventBus.dispatch("sandboxcreated", { + source: this + }); + } catch (error) { + console.error(`setDocument: "${error.message}".`); + await this.#destroyScripting(); + return; + } + await this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "Open" + }); + await this.#dispatchPageOpen(this.#pdfViewer.currentPageNumber, true); + Promise.resolve().then(() => { + if (pdfDocument === this.#pdfDocument) { + this.#ready = true; + } + }); + } + async dispatchWillSave() { + return this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "WillSave" + }); + } + async dispatchDidSave() { + return this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "DidSave" + }); + } + async dispatchWillPrint() { + if (!this.#scripting) { + return; + } + await this.#willPrintCapability?.promise; + this.#willPrintCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(); + try { + await this.#scripting.dispatchEventInSandbox({ + id: "doc", + name: "WillPrint" + }); + } catch (ex) { + this.#willPrintCapability.resolve(); + this.#willPrintCapability = null; + throw ex; + } + await this.#willPrintCapability.promise; + } + async dispatchDidPrint() { + return this.#scripting?.dispatchEventInSandbox({ + id: "doc", + name: "DidPrint" + }); + } + get destroyPromise() { + return this.#destroyCapability?.promise || null; + } + get ready() { + return this.#ready; + } + get _internalEvents() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "_internalEvents", new Map()); + } + get _pageOpenPending() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "_pageOpenPending", new Set()); + } + get _visitedPages() { + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.shadow)(this, "_visitedPages", new Map()); + } + async #updateFromSandbox(detail) { + const pdfViewer = this.#pdfViewer; + const isInPresentationMode = pdfViewer.isInPresentationMode || pdfViewer.isChangingPresentationMode; + const { + id, + siblings, + command, + value + } = detail; + if (!id) { + switch (command) { + case "clear": + console.clear(); + break; + case "error": + console.error(value); + break; + case "layout": + if (!isInPresentationMode) { + const modes = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.apiPageLayoutToViewerModes)(value); + pdfViewer.spreadMode = modes.spreadMode; + } + break; + case "page-num": + pdfViewer.currentPageNumber = value + 1; + break; + case "print": + await pdfViewer.pagesPromise; + this.#eventBus.dispatch("print", { + source: this + }); + break; + case "println": + console.log(value); + break; + case "zoom": + if (!isInPresentationMode) { + pdfViewer.currentScaleValue = value; + } + break; + case "SaveAs": + this.#eventBus.dispatch("download", { + source: this + }); + break; + case "FirstPage": + pdfViewer.currentPageNumber = 1; + break; + case "LastPage": + pdfViewer.currentPageNumber = pdfViewer.pagesCount; + break; + case "NextPage": + pdfViewer.nextPage(); + break; + case "PrevPage": + pdfViewer.previousPage(); + break; + case "ZoomViewIn": + if (!isInPresentationMode) { + pdfViewer.increaseScale(); + } + break; + case "ZoomViewOut": + if (!isInPresentationMode) { + pdfViewer.decreaseScale(); + } + break; + case "WillPrintFinished": + this.#willPrintCapability?.resolve(); + this.#willPrintCapability = null; + break; + } + return; + } + if (isInPresentationMode && detail.focus) { + return; + } + delete detail.id; + delete detail.siblings; + const ids = siblings ? [id, ...siblings] : [id]; + for (const elementId of ids) { + const element = document.querySelector(`[data-element-id="${elementId}"]`); + if (element) { + element.dispatchEvent(new CustomEvent("updatefromsandbox", { + detail + })); + } else { + this.#pdfDocument?.annotationStorage.setValue(elementId, detail); + } + } + } + async #dispatchPageOpen(pageNumber, initialize = false) { + const pdfDocument = this.#pdfDocument, + visitedPages = this._visitedPages; + if (initialize) { + this.#closeCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(); + } + if (!this.#closeCapability) { + return; + } + const pageView = this.#pdfViewer.getPageView(pageNumber - 1); + if (pageView?.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) { + this._pageOpenPending.add(pageNumber); + return; + } + this._pageOpenPending.delete(pageNumber); + const actionsPromise = (async () => { + const actions = await (!visitedPages.has(pageNumber) ? pageView.pdfPage?.getJSActions() : null); + if (pdfDocument !== this.#pdfDocument) { + return; + } + await this.#scripting?.dispatchEventInSandbox({ + id: "page", + name: "PageOpen", + pageNumber, + actions + }); + })(); + visitedPages.set(pageNumber, actionsPromise); + } + async #dispatchPageClose(pageNumber) { + const pdfDocument = this.#pdfDocument, + visitedPages = this._visitedPages; + if (!this.#closeCapability) { + return; + } + if (this._pageOpenPending.has(pageNumber)) { + return; + } + const actionsPromise = visitedPages.get(pageNumber); + if (!actionsPromise) { + return; + } + visitedPages.set(pageNumber, null); + await actionsPromise; + if (pdfDocument !== this.#pdfDocument) { + return; + } + await this.#scripting?.dispatchEventInSandbox({ + id: "page", + name: "PageClose", + pageNumber + }); + } + #initScripting() { + this.#destroyCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.PromiseCapability(); + if (this.#scripting) { + throw new Error("#initScripting: Scripting already exists."); + } + return this.#externalServices.createScripting(); + } + async #destroyScripting() { + if (!this.#scripting) { + this.#pdfDocument = null; + this.#destroyCapability?.resolve(); + return; + } + if (this.#closeCapability) { + await Promise.race([this.#closeCapability.promise, new Promise(resolve => { + setTimeout(resolve, 1000); + })]).catch(() => {}); + this.#closeCapability = null; + } + this.#pdfDocument = null; + try { + await this.#scripting.destroySandbox(); + } catch {} + this.#willPrintCapability?.reject(new Error("Scripting destroyed.")); + this.#willPrintCapability = null; + for (const [name, listener] of this._internalEvents) { + this.#eventBus._off(name, listener); + } + this._internalEvents.clear(); + this._pageOpenPending.clear(); + this._visitedPages.clear(); + this.#scripting = null; + this.#ready = false; + this.#destroyCapability?.resolve(); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 4487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFSidebar: () => (/* binding */ PDFSidebar) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); + +const SIDEBAR_WIDTH_VAR = "--sidebar-width"; +const SIDEBAR_MIN_WIDTH = 200; +const SIDEBAR_RESIZING_CLASS = "sidebarResizing"; +const UI_NOTIFICATION_CLASS = "pdfSidebarNotification"; +class PDFSidebar { + #isRTL = false; + #mouseMoveBound = this.#mouseMove.bind(this); + #mouseUpBound = this.#mouseUp.bind(this); + #outerContainerWidth = null; + #width = null; + constructor({ + elements, + eventBus, + l10n + }) { + this.isOpen = false; + this.active = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS; + this.isInitialViewSet = false; + this.isInitialEventDispatched = false; + this.onToggled = null; + this.onUpdateThumbnails = null; + this.outerContainer = elements.outerContainer; + this.sidebarContainer = elements.sidebarContainer; + this.toggleButton = elements.toggleButton; + this.resizer = elements.resizer; + this.thumbnailButton = elements.thumbnailButton; + this.outlineButton = elements.outlineButton; + this.attachmentsButton = elements.attachmentsButton; + this.layersButton = elements.layersButton; + this.thumbnailView = elements.thumbnailView; + this.outlineView = elements.outlineView; + this.attachmentsView = elements.attachmentsView; + this.layersView = elements.layersView; + this._currentOutlineItemButton = elements.currentOutlineItemButton; + this.eventBus = eventBus; + this.#isRTL = l10n.getDirection() === "rtl"; + this.#addEventListeners(); + } + reset() { + this.isInitialViewSet = false; + this.isInitialEventDispatched = false; + this.#hideUINotification(true); + this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS); + this.outlineButton.disabled = false; + this.attachmentsButton.disabled = false; + this.layersButton.disabled = false; + this._currentOutlineItemButton.disabled = true; + } + get visibleView() { + return this.isOpen ? this.active : _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE; + } + setInitialView(view = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE) { + if (this.isInitialViewSet) { + return; + } + this.isInitialViewSet = true; + if (view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE || view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.UNKNOWN) { + this.#dispatchEvent(); + return; + } + this.switchView(view, true); + if (!this.isInitialEventDispatched) { + this.#dispatchEvent(); + } + } + switchView(view, forceOpen = false) { + const isViewChanged = view !== this.active; + let forceRendering = false; + switch (view) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.NONE: + if (this.isOpen) { + this.close(); + } + return; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS: + if (this.isOpen && isViewChanged) { + forceRendering = true; + } + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE: + if (this.outlineButton.disabled) { + return; + } + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS: + if (this.attachmentsButton.disabled) { + return; + } + break; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS: + if (this.layersButton.disabled) { + return; + } + break; + default: + console.error(`PDFSidebar.switchView: "${view}" is not a valid view.`); + return; + } + this.active = view; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.thumbnailButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS, this.thumbnailView); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.outlineButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE, this.outlineView); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.attachmentsButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS, this.attachmentsView); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(this.layersButton, view === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS, this.layersView); + if (forceOpen && !this.isOpen) { + this.open(); + return; + } + if (forceRendering) { + this.onUpdateThumbnails(); + this.onToggled(); + } + if (isViewChanged) { + this.#dispatchEvent(); + } + } + open() { + if (this.isOpen) { + return; + } + this.isOpen = true; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(this.toggleButton, true); + this.outerContainer.classList.add("sidebarMoving", "sidebarOpen"); + if (this.active === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) { + this.onUpdateThumbnails(); + } + this.onToggled(); + this.#dispatchEvent(); + this.#hideUINotification(); + } + close(evt = null) { + if (!this.isOpen) { + return; + } + this.isOpen = false; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(this.toggleButton, false); + this.outerContainer.classList.add("sidebarMoving"); + this.outerContainer.classList.remove("sidebarOpen"); + this.onToggled(); + this.#dispatchEvent(); + if (evt?.detail > 0) { + this.toggleButton.blur(); + } + } + toggle(evt = null) { + if (this.isOpen) { + this.close(evt); + } else { + this.open(); + } + } + #dispatchEvent() { + if (this.isInitialViewSet) { + this.isInitialEventDispatched ||= true; + } + this.eventBus.dispatch("sidebarviewchanged", { + source: this, + view: this.visibleView + }); + } + #showUINotification() { + this.toggleButton.setAttribute("data-l10n-id", "pdfjs-toggle-sidebar-notification-button"); + if (!this.isOpen) { + this.toggleButton.classList.add(UI_NOTIFICATION_CLASS); + } + } + #hideUINotification(reset = false) { + if (this.isOpen || reset) { + this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS); + } + if (reset) { + this.toggleButton.setAttribute("data-l10n-id", "pdfjs-toggle-sidebar-button"); + } + } + #addEventListeners() { + this.sidebarContainer.addEventListener("transitionend", evt => { + if (evt.target === this.sidebarContainer) { + this.outerContainer.classList.remove("sidebarMoving"); + this.eventBus.dispatch("resize", { + source: this + }); + } + }); + this.toggleButton.addEventListener("click", evt => { + this.toggle(evt); + }); + this.thumbnailButton.addEventListener("click", () => { + this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS); + }); + this.outlineButton.addEventListener("click", () => { + this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE); + }); + this.outlineButton.addEventListener("dblclick", () => { + this.eventBus.dispatch("toggleoutlinetree", { + source: this + }); + }); + this.attachmentsButton.addEventListener("click", () => { + this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS); + }); + this.layersButton.addEventListener("click", () => { + this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS); + }); + this.layersButton.addEventListener("dblclick", () => { + this.eventBus.dispatch("resetlayers", { + source: this + }); + }); + this._currentOutlineItemButton.addEventListener("click", () => { + this.eventBus.dispatch("currentoutlineitem", { + source: this + }); + }); + const onTreeLoaded = (count, button, view) => { + button.disabled = !count; + if (count) { + this.#showUINotification(); + } else if (this.active === view) { + this.switchView(_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS); + } + }; + this.eventBus._on("outlineloaded", evt => { + onTreeLoaded(evt.outlineCount, this.outlineButton, _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.OUTLINE); + evt.currentOutlineItemPromise.then(enabled => { + if (!this.isInitialViewSet) { + return; + } + this._currentOutlineItemButton.disabled = !enabled; + }); + }); + this.eventBus._on("attachmentsloaded", evt => { + onTreeLoaded(evt.attachmentsCount, this.attachmentsButton, _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.ATTACHMENTS); + }); + this.eventBus._on("layersloaded", evt => { + onTreeLoaded(evt.layersCount, this.layersButton, _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.LAYERS); + }); + this.eventBus._on("presentationmodechanged", evt => { + if (evt.state === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.PresentationModeState.NORMAL && this.visibleView === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SidebarView.THUMBS) { + this.onUpdateThumbnails(); + } + }); + this.resizer.addEventListener("mousedown", evt => { + if (evt.button !== 0) { + return; + } + this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS); + window.addEventListener("mousemove", this.#mouseMoveBound); + window.addEventListener("mouseup", this.#mouseUpBound); + }); + this.eventBus._on("resize", evt => { + if (evt.source !== window) { + return; + } + this.#outerContainerWidth = null; + if (!this.#width) { + return; + } + if (!this.isOpen) { + this.#updateWidth(this.#width); + return; + } + this.outerContainer.classList.add(SIDEBAR_RESIZING_CLASS); + const updated = this.#updateWidth(this.#width); + Promise.resolve().then(() => { + this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS); + if (updated) { + this.eventBus.dispatch("resize", { + source: this + }); + } + }); + }); + } + get outerContainerWidth() { + return this.#outerContainerWidth ||= this.outerContainer.clientWidth; + } + #updateWidth(width = 0) { + const maxWidth = Math.floor(this.outerContainerWidth / 2); + if (width > maxWidth) { + width = maxWidth; + } + if (width < SIDEBAR_MIN_WIDTH) { + width = SIDEBAR_MIN_WIDTH; + } + if (width === this.#width) { + return false; + } + this.#width = width; + _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.docStyle.setProperty(SIDEBAR_WIDTH_VAR, `${width}px`); + return true; + } + #mouseMove(evt) { + let width = evt.clientX; + if (this.#isRTL) { + width = this.outerContainerWidth - width; + } + this.#updateWidth(width); + } + #mouseUp(evt) { + this.outerContainer.classList.remove(SIDEBAR_RESIZING_CLASS); + this.eventBus.dispatch("resize", { + source: this + }); + window.removeEventListener("mousemove", this.#mouseMoveBound); + window.removeEventListener("mouseup", this.#mouseUpBound); + } +} + + +/***/ }), + +/***/ 3346: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFThumbnailView: () => (/* binding */ PDFThumbnailView), +/* harmony export */ TempImageFactory: () => (/* binding */ TempImageFactory) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +const DRAW_UPSCALE_FACTOR = 2; +const MAX_NUM_SCALING_STEPS = 3; +const THUMBNAIL_WIDTH = 98; +class TempImageFactory { + static #tempCanvas = null; + static getCanvas(width, height) { + const tempCanvas = this.#tempCanvas ||= document.createElement("canvas"); + tempCanvas.width = width; + tempCanvas.height = height; + const ctx = tempCanvas.getContext("2d", { + alpha: false + }); + ctx.save(); + ctx.fillStyle = "rgb(255, 255, 255)"; + ctx.fillRect(0, 0, width, height); + ctx.restore(); + return [tempCanvas, tempCanvas.getContext("2d")]; + } + static destroyCanvas() { + const tempCanvas = this.#tempCanvas; + if (tempCanvas) { + tempCanvas.width = 0; + tempCanvas.height = 0; + } + this.#tempCanvas = null; + } +} +class PDFThumbnailView { + constructor({ + container, + eventBus, + id, + defaultViewport, + optionalContentConfigPromise, + linkService, + renderingQueue, + pageColors + }) { + this.id = id; + this.renderingId = "thumbnail" + id; + this.pageLabel = null; + this.pdfPage = null; + this.rotation = 0; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + this._optionalContentConfigPromise = optionalContentConfigPromise || null; + this.pageColors = pageColors || null; + this.eventBus = eventBus; + this.linkService = linkService; + this.renderingQueue = renderingQueue; + this.renderTask = null; + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL; + this.resume = null; + const anchor = document.createElement("a"); + anchor.href = linkService.getAnchorUrl("#page=" + id); + anchor.setAttribute("data-l10n-id", "pdfjs-thumb-page-title"); + anchor.setAttribute("data-l10n-args", this.#pageL10nArgs); + anchor.onclick = function () { + linkService.goToPage(id); + return false; + }; + this.anchor = anchor; + const div = document.createElement("div"); + div.className = "thumbnail"; + div.setAttribute("data-page-number", this.id); + this.div = div; + this.#updateDims(); + const img = document.createElement("div"); + img.className = "thumbnailImage"; + this._placeholderImg = img; + div.append(img); + anchor.append(div); + container.append(anchor); + } + #updateDims() { + const { + width, + height + } = this.viewport; + const ratio = width / height; + this.canvasWidth = THUMBNAIL_WIDTH; + this.canvasHeight = this.canvasWidth / ratio | 0; + this.scale = this.canvasWidth / width; + const { + style + } = this.div; + style.setProperty("--thumbnail-width", `${this.canvasWidth}px`); + style.setProperty("--thumbnail-height", `${this.canvasHeight}px`); + } + setPdfPage(pdfPage) { + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport({ + scale: 1, + rotation: totalRotation + }); + this.reset(); + } + reset() { + this.cancelRendering(); + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL; + this.div.removeAttribute("data-loaded"); + this.image?.replaceWith(this._placeholderImg); + this.#updateDims(); + if (this.image) { + this.image.removeAttribute("src"); + delete this.image; + } + } + update({ + rotation = null + }) { + if (typeof rotation === "number") { + this.rotation = rotation; + } + const totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: 1, + rotation: totalRotation + }); + this.reset(); + } + cancelRendering() { + if (this.renderTask) { + this.renderTask.cancel(); + this.renderTask = null; + } + this.resume = null; + } + _getPageDrawContext(upscaleFactor = 1) { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d", { + alpha: false + }); + const outputScale = new _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.OutputScale(); + canvas.width = upscaleFactor * this.canvasWidth * outputScale.sx | 0; + canvas.height = upscaleFactor * this.canvasHeight * outputScale.sy | 0; + const transform = outputScale.scaled ? [outputScale.sx, 0, 0, outputScale.sy, 0, 0] : null; + return { + ctx, + canvas, + transform + }; + } + _convertCanvasToImage(canvas) { + if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) { + throw new Error("_convertCanvasToImage: Rendering has not finished."); + } + const reducedCanvas = this._reduceImage(canvas); + const image = document.createElement("img"); + image.className = "thumbnailImage"; + image.setAttribute("data-l10n-id", "pdfjs-thumb-page-canvas"); + image.setAttribute("data-l10n-args", this.#pageL10nArgs); + image.src = reducedCanvas.toDataURL(); + this.image = image; + this.div.setAttribute("data-loaded", true); + this._placeholderImg.replaceWith(image); + reducedCanvas.width = 0; + reducedCanvas.height = 0; + } + async #finishRenderTask(renderTask, canvas, error = null) { + if (renderTask === this.renderTask) { + this.renderTask = null; + } + if (error instanceof pdfjs_lib__WEBPACK_IMPORTED_MODULE_1__.RenderingCancelledException) { + return; + } + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED; + this._convertCanvasToImage(canvas); + if (error) { + throw error; + } + } + async draw() { + if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL) { + console.error("Must be in new state before drawing"); + return undefined; + } + const { + pdfPage + } = this; + if (!pdfPage) { + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED; + throw new Error("pdfPage is not loaded"); + } + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.RUNNING; + const { + ctx, + canvas, + transform + } = this._getPageDrawContext(DRAW_UPSCALE_FACTOR); + const drawViewport = this.viewport.clone({ + scale: DRAW_UPSCALE_FACTOR * this.scale + }); + const renderContinueCallback = cont => { + if (!this.renderingQueue.isHighestPriority(this)) { + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.PAUSED; + this.resume = () => { + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + const renderContext = { + canvasContext: ctx, + transform, + viewport: drawViewport, + optionalContentConfigPromise: this._optionalContentConfigPromise, + pageColors: this.pageColors + }; + const renderTask = this.renderTask = pdfPage.render(renderContext); + renderTask.onContinue = renderContinueCallback; + const resultPromise = renderTask.promise.then(() => this.#finishRenderTask(renderTask, canvas), error => this.#finishRenderTask(renderTask, canvas, error)); + resultPromise.finally(() => { + canvas.width = 0; + canvas.height = 0; + this.eventBus.dispatch("thumbnailrendered", { + source: this, + pageNumber: this.id, + pdfPage: this.pdfPage + }); + }); + return resultPromise; + } + setImage(pageView) { + if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.INITIAL) { + return; + } + const { + thumbnailCanvas: canvas, + pdfPage, + scale + } = pageView; + if (!canvas) { + return; + } + if (!this.pdfPage) { + this.setPdfPage(pdfPage); + } + if (scale < this.scale) { + return; + } + this.renderingState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED; + this._convertCanvasToImage(canvas); + } + _reduceImage(img) { + const { + ctx, + canvas + } = this._getPageDrawContext(); + if (img.width <= 2 * canvas.width) { + ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); + return canvas; + } + let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS; + let reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; + const [reducedImage, reducedImageCtx] = TempImageFactory.getCanvas(reducedWidth, reducedHeight); + while (reducedWidth > img.width || reducedHeight > img.height) { + reducedWidth >>= 1; + reducedHeight >>= 1; + } + reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, reducedWidth, reducedHeight); + while (reducedWidth > 2 * canvas.width) { + reducedImageCtx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, reducedWidth >> 1, reducedHeight >> 1); + reducedWidth >>= 1; + reducedHeight >>= 1; + } + ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, canvas.width, canvas.height); + return canvas; + } + get #pageL10nArgs() { + return JSON.stringify({ + page: this.pageLabel ?? this.id + }); + } + setPageLabel(label) { + this.pageLabel = typeof label === "string" ? label : null; + this.anchor.setAttribute("data-l10n-args", this.#pageL10nArgs); + if (this.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) { + return; + } + this.image?.setAttribute("data-l10n-args", this.#pageL10nArgs); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 3510: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFThumbnailViewer: () => (/* binding */ PDFThumbnailViewer) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var _pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3346); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__]); +_pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +const THUMBNAIL_SCROLL_MARGIN = -19; +const THUMBNAIL_SELECTED_CLASS = "selected"; +class PDFThumbnailViewer { + constructor({ + container, + eventBus, + linkService, + renderingQueue, + pageColors + }) { + this.container = container; + this.eventBus = eventBus; + this.linkService = linkService; + this.renderingQueue = renderingQueue; + this.pageColors = pageColors || null; + this.scroll = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.watchScroll)(this.container, this._scrollUpdated.bind(this)); + this._resetView(); + } + _scrollUpdated() { + this.renderingQueue.renderHighestPriority(); + } + getThumbnail(index) { + return this._thumbnails[index]; + } + _getVisibleThumbs() { + return (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.getVisibleElements)({ + scrollEl: this.container, + views: this._thumbnails + }); + } + scrollThumbnailIntoView(pageNumber) { + if (!this.pdfDocument) { + return; + } + const thumbnailView = this._thumbnails[pageNumber - 1]; + if (!thumbnailView) { + console.error('scrollThumbnailIntoView: Invalid "pageNumber" parameter.'); + return; + } + if (pageNumber !== this._currentPageNumber) { + const prevThumbnailView = this._thumbnails[this._currentPageNumber - 1]; + prevThumbnailView.div.classList.remove(THUMBNAIL_SELECTED_CLASS); + thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS); + } + const { + first, + last, + views + } = this._getVisibleThumbs(); + if (views.length > 0) { + let shouldScroll = false; + if (pageNumber <= first.id || pageNumber >= last.id) { + shouldScroll = true; + } else { + for (const { + id, + percent + } of views) { + if (id !== pageNumber) { + continue; + } + shouldScroll = percent < 100; + break; + } + } + if (shouldScroll) { + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.scrollIntoView)(thumbnailView.div, { + top: THUMBNAIL_SCROLL_MARGIN + }); + } + } + this._currentPageNumber = pageNumber; + } + get pagesRotation() { + return this._pagesRotation; + } + set pagesRotation(rotation) { + if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.isValidRotation)(rotation)) { + throw new Error("Invalid thumbnails rotation angle."); + } + if (!this.pdfDocument) { + return; + } + if (this._pagesRotation === rotation) { + return; + } + this._pagesRotation = rotation; + const updateArgs = { + rotation + }; + for (const thumbnail of this._thumbnails) { + thumbnail.update(updateArgs); + } + } + cleanup() { + for (const thumbnail of this._thumbnails) { + if (thumbnail.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.RenderingStates.FINISHED) { + thumbnail.reset(); + } + } + _pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__.TempImageFactory.destroyCanvas(); + } + _resetView() { + this._thumbnails = []; + this._currentPageNumber = 1; + this._pageLabels = null; + this._pagesRotation = 0; + this.container.textContent = ""; + } + setDocument(pdfDocument) { + if (this.pdfDocument) { + this._cancelRendering(); + this._resetView(); + } + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + const firstPagePromise = pdfDocument.getPage(1); + const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig(); + firstPagePromise.then(firstPdfPage => { + const pagesCount = pdfDocument.numPages; + const viewport = firstPdfPage.getViewport({ + scale: 1 + }); + for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { + const thumbnail = new _pdf_thumbnail_view_js__WEBPACK_IMPORTED_MODULE_1__.PDFThumbnailView({ + container: this.container, + eventBus: this.eventBus, + id: pageNum, + defaultViewport: viewport.clone(), + optionalContentConfigPromise, + linkService: this.linkService, + renderingQueue: this.renderingQueue, + pageColors: this.pageColors + }); + this._thumbnails.push(thumbnail); + } + this._thumbnails[0]?.setPdfPage(firstPdfPage); + const thumbnailView = this._thumbnails[this._currentPageNumber - 1]; + thumbnailView.div.classList.add(THUMBNAIL_SELECTED_CLASS); + }).catch(reason => { + console.error("Unable to initialize thumbnail viewer", reason); + }); + } + _cancelRendering() { + for (const thumbnail of this._thumbnails) { + thumbnail.cancelRendering(); + } + } + setPageLabels(labels) { + if (!this.pdfDocument) { + return; + } + if (!labels) { + this._pageLabels = null; + } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) { + this._pageLabels = null; + console.error("PDFThumbnailViewer_setPageLabels: Invalid page labels."); + } else { + this._pageLabels = labels; + } + for (let i = 0, ii = this._thumbnails.length; i < ii; i++) { + this._thumbnails[i].setPageLabel(this._pageLabels?.[i] ?? null); + } + } + async #ensurePdfPageLoaded(thumbView) { + if (thumbView.pdfPage) { + return thumbView.pdfPage; + } + try { + const pdfPage = await this.pdfDocument.getPage(thumbView.id); + if (!thumbView.pdfPage) { + thumbView.setPdfPage(pdfPage); + } + return pdfPage; + } catch (reason) { + console.error("Unable to get page for thumb view", reason); + return null; + } + } + #getScrollAhead(visible) { + if (visible.first?.id === 1) { + return true; + } else if (visible.last?.id === this._thumbnails.length) { + return false; + } + return this.scroll.down; + } + forceRendering() { + const visibleThumbs = this._getVisibleThumbs(); + const scrollAhead = this.#getScrollAhead(visibleThumbs); + const thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this._thumbnails, scrollAhead); + if (thumbView) { + this.#ensurePdfPageLoaded(thumbView).then(() => { + this.renderingQueue.renderView(thumbView); + }); + return true; + } + return false; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 9290: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFViewer: () => (/* binding */ PDFViewer), +/* harmony export */ PagesCountLimit: () => (/* binding */ PagesCountLimit) +/* harmony export */ }); +/* unused harmony export PDFPageViewBuffer */ +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +/* harmony import */ var web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7910); +/* harmony import */ var _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6732); +/* harmony import */ var _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5119); +/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3234); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__, _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__]); +([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__, _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__, _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + + + + +const DEFAULT_CACHE_SIZE = 10; +const PagesCountLimit = { + FORCE_SCROLL_MODE_PAGE: 15000, + FORCE_LAZY_PAGE_INIT: 7500, + PAUSE_EAGER_PAGE_INIT: 250 +}; +function isValidAnnotationEditorMode(mode) { + return Object.values(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType).includes(mode) && mode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE; +} +class PDFPageViewBuffer { + #buf = new Set(); + #size = 0; + constructor(size) { + this.#size = size; + } + push(view) { + const buf = this.#buf; + if (buf.has(view)) { + buf.delete(view); + } + buf.add(view); + if (buf.size > this.#size) { + this.#destroyFirstView(); + } + } + resize(newSize, idsToKeep = null) { + this.#size = newSize; + const buf = this.#buf; + if (idsToKeep) { + const ii = buf.size; + let i = 1; + for (const view of buf) { + if (idsToKeep.has(view.id)) { + buf.delete(view); + buf.add(view); + } + if (++i > ii) { + break; + } + } + } + while (buf.size > this.#size) { + this.#destroyFirstView(); + } + } + has(view) { + return this.#buf.has(view); + } + [Symbol.iterator]() { + return this.#buf.keys(); + } + #destroyFirstView() { + const firstView = this.#buf.keys().next().value; + firstView?.destroy(); + this.#buf.delete(firstView); + } +} +class PDFViewer { + #buffer = null; + #altTextManager = null; + #annotationEditorHighlightColors = null; + #annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE; + #annotationEditorUIManager = null; + #annotationMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS; + #containerTopLeft = null; + #copyCallbackBound = null; + #enablePermissions = false; + #getAllTextInProgress = false; + #hiddenCopyElement = null; + #interruptCopyCondition = false; + #previousContainerHeight = 0; + #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this)); + #scrollModePageState = null; + #onVisibilityChange = null; + #scaleTimeoutId = null; + #textLayerMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE; + constructor(options) { + const viewerVersion = '4.0.379'; + if (pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.version !== viewerVersion) { + throw new Error(`The API version "${pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.version}" does not match the Viewer version "${viewerVersion}".`); + } + this.container = options.container; + this.viewer = options.viewer || options.container.firstElementChild; + if (this.container?.tagName !== "DIV" || this.viewer?.tagName !== "DIV") { + throw new Error("Invalid `container` and/or `viewer` option."); + } + if (this.container.offsetParent && getComputedStyle(this.container).position !== "absolute") { + throw new Error("The `container` must be absolutely positioned."); + } + this.#resizeObserver.observe(this.container); + this.eventBus = options.eventBus; + this.linkService = options.linkService || new _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_5__.SimpleLinkService(); + this.downloadManager = options.downloadManager || null; + this.findController = options.findController || null; + this.#altTextManager = options.altTextManager || null; + if (this.findController) { + this.findController.onIsPageVisible = pageNumber => this._getVisiblePages().ids.has(pageNumber); + } + this._scriptingManager = options.scriptingManager || null; + this.#textLayerMode = options.textLayerMode ?? _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE; + this.#annotationMode = options.annotationMode ?? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS; + this.#annotationEditorMode = options.annotationEditorMode ?? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE; + this.#annotationEditorHighlightColors = options.annotationEditorHighlightColors || null; + this.imageResourcesPath = options.imageResourcesPath || ""; + this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; + this.removePageBorders = options.removePageBorders || false; + this.isOffscreenCanvasSupported = options.isOffscreenCanvasSupported ?? true; + this.maxCanvasPixels = options.maxCanvasPixels; + this.l10n = options.l10n || web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__.NullL10n; + this.#enablePermissions = options.enablePermissions || false; + this.pageColors = options.pageColors || null; + this.defaultRenderingQueue = !options.renderingQueue; + if (this.defaultRenderingQueue) { + this.renderingQueue = new _pdf_rendering_queue_js__WEBPACK_IMPORTED_MODULE_4__.PDFRenderingQueue(); + this.renderingQueue.setViewer(this); + } else { + this.renderingQueue = options.renderingQueue; + } + this.scroll = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.watchScroll)(this.container, this._scrollUpdate.bind(this)); + this.presentationModeState = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.UNKNOWN; + this._onBeforeDraw = this._onAfterDraw = null; + this._resetView(); + if (this.removePageBorders) { + this.viewer.classList.add("removePageBorders"); + } + this.#updateContainerHeightCss(); + this.eventBus._on("thumbnailrendered", ({ + pageNumber, + pdfPage + }) => { + const pageView = this._pages[pageNumber - 1]; + if (!this.#buffer.has(pageView)) { + pdfPage?.cleanup(); + } + }); + if (this.l10n === web_l10n_utils__WEBPACK_IMPORTED_MODULE_2__.NullL10n) { + this.l10n.translate(this.container); + } + } + get pagesCount() { + return this._pages.length; + } + getPageView(index) { + return this._pages[index]; + } + getCachedPageViews() { + return new Set(this.#buffer); + } + get pageViewsReady() { + return this._pagesCapability.settled && this._pages.every(pageView => pageView?.pdfPage); + } + get renderForms() { + return this.#annotationMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS; + } + get enableScripting() { + return !!this._scriptingManager; + } + get currentPageNumber() { + return this._currentPageNumber; + } + set currentPageNumber(val) { + if (!Number.isInteger(val)) { + throw new Error("Invalid page number."); + } + if (!this.pdfDocument) { + return; + } + if (!this._setCurrentPageNumber(val, true)) { + console.error(`currentPageNumber: "${val}" is not a valid page.`); + } + } + _setCurrentPageNumber(val, resetCurrentPageView = false) { + if (this._currentPageNumber === val) { + if (resetCurrentPageView) { + this.#resetCurrentPageView(); + } + return true; + } + if (!(0 < val && val <= this.pagesCount)) { + return false; + } + const previous = this._currentPageNumber; + this._currentPageNumber = val; + this.eventBus.dispatch("pagechanging", { + source: this, + pageNumber: val, + pageLabel: this._pageLabels?.[val - 1] ?? null, + previous + }); + if (resetCurrentPageView) { + this.#resetCurrentPageView(); + } + return true; + } + get currentPageLabel() { + return this._pageLabels?.[this._currentPageNumber - 1] ?? null; + } + set currentPageLabel(val) { + if (!this.pdfDocument) { + return; + } + let page = val | 0; + if (this._pageLabels) { + const i = this._pageLabels.indexOf(val); + if (i >= 0) { + page = i + 1; + } + } + if (!this._setCurrentPageNumber(page, true)) { + console.error(`currentPageLabel: "${val}" is not a valid page.`); + } + } + get currentScale() { + return this._currentScale !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.UNKNOWN_SCALE ? this._currentScale : _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE; + } + set currentScale(val) { + if (isNaN(val)) { + throw new Error("Invalid numeric scale."); + } + if (!this.pdfDocument) { + return; + } + this.#setScale(val, { + noScroll: false + }); + } + get currentScaleValue() { + return this._currentScaleValue; + } + set currentScaleValue(val) { + if (!this.pdfDocument) { + return; + } + this.#setScale(val, { + noScroll: false + }); + } + get pagesRotation() { + return this._pagesRotation; + } + set pagesRotation(rotation) { + if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isValidRotation)(rotation)) { + throw new Error("Invalid pages rotation angle."); + } + if (!this.pdfDocument) { + return; + } + rotation %= 360; + if (rotation < 0) { + rotation += 360; + } + if (this._pagesRotation === rotation) { + return; + } + this._pagesRotation = rotation; + const pageNumber = this._currentPageNumber; + this.refresh(true, { + rotation + }); + if (this._currentScaleValue) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this.eventBus.dispatch("rotationchanging", { + source: this, + pagesRotation: rotation, + pageNumber + }); + if (this.defaultRenderingQueue) { + this.update(); + } + } + get firstPagePromise() { + return this.pdfDocument ? this._firstPageCapability.promise : null; + } + get onePageRendered() { + return this.pdfDocument ? this._onePageRenderedCapability.promise : null; + } + get pagesPromise() { + return this.pdfDocument ? this._pagesCapability.promise : null; + } + get _layerProperties() { + const self = this; + return (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.shadow)(this, "_layerProperties", { + get annotationEditorUIManager() { + return self.#annotationEditorUIManager; + }, + get annotationStorage() { + return self.pdfDocument?.annotationStorage; + }, + get downloadManager() { + return self.downloadManager; + }, + get enableScripting() { + return !!self._scriptingManager; + }, + get fieldObjectsPromise() { + return self.pdfDocument?.getFieldObjects(); + }, + get findController() { + return self.findController; + }, + get hasJSActionsPromise() { + return self.pdfDocument?.hasJSActions(); + }, + get linkService() { + return self.linkService; + } + }); + } + #initializePermissions(permissions) { + const params = { + annotationEditorMode: this.#annotationEditorMode, + annotationMode: this.#annotationMode, + textLayerMode: this.#textLayerMode + }; + if (!permissions) { + return params; + } + if (!permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.COPY) && this.#textLayerMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE) { + params.textLayerMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE_PERMISSIONS; + } + if (!permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.MODIFY_CONTENTS)) { + params.annotationEditorMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE; + } + if (!permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.MODIFY_ANNOTATIONS) && !permissions.includes(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PermissionFlag.FILL_INTERACTIVE_FORMS) && this.#annotationMode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE_FORMS) { + params.annotationMode = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationMode.ENABLE; + } + return params; + } + #onePageRenderedOrForceFetch() { + if (document.visibilityState === "hidden" || !this.container.offsetParent || this._getVisiblePages().views.length === 0) { + return Promise.resolve(); + } + const visibilityChangePromise = new Promise(resolve => { + this.#onVisibilityChange = () => { + if (document.visibilityState !== "hidden") { + return; + } + resolve(); + document.removeEventListener("visibilitychange", this.#onVisibilityChange); + this.#onVisibilityChange = null; + }; + document.addEventListener("visibilitychange", this.#onVisibilityChange); + }); + return Promise.race([this._onePageRenderedCapability.promise, visibilityChangePromise]); + } + async getAllText() { + const texts = []; + const buffer = []; + for (let pageNum = 1, pagesCount = this.pdfDocument.numPages; pageNum <= pagesCount; ++pageNum) { + if (this.#interruptCopyCondition) { + return null; + } + buffer.length = 0; + const page = await this.pdfDocument.getPage(pageNum); + const { + items + } = await page.getTextContent(); + for (const item of items) { + if (item.str) { + buffer.push(item.str); + } + if (item.hasEOL) { + buffer.push("\n"); + } + } + texts.push((0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.removeNullCharacters)(buffer.join(""))); + } + return texts.join("\n"); + } + #copyCallback(textLayerMode, event) { + const selection = document.getSelection(); + const { + focusNode, + anchorNode + } = selection; + if (anchorNode && focusNode && selection.containsNode(this.#hiddenCopyElement)) { + if (this.#getAllTextInProgress || textLayerMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.ENABLE_PERMISSIONS) { + event.preventDefault(); + event.stopPropagation(); + return; + } + this.#getAllTextInProgress = true; + const savedCursor = this.container.style.cursor; + this.container.style.cursor = "wait"; + const interruptCopy = ev => this.#interruptCopyCondition = ev.key === "Escape"; + window.addEventListener("keydown", interruptCopy); + this.getAllText().then(async text => { + if (text !== null) { + await navigator.clipboard.writeText(text); + } + }).catch(reason => { + console.warn(`Something goes wrong when extracting the text: ${reason.message}`); + }).finally(() => { + this.#getAllTextInProgress = false; + this.#interruptCopyCondition = false; + window.removeEventListener("keydown", interruptCopy); + this.container.style.cursor = savedCursor; + }); + event.preventDefault(); + event.stopPropagation(); + } + } + setDocument(pdfDocument) { + if (this.pdfDocument) { + this.eventBus.dispatch("pagesdestroy", { + source: this + }); + this._cancelRendering(); + this._resetView(); + this.findController?.setDocument(null); + this._scriptingManager?.setDocument(null); + if (this.#annotationEditorUIManager) { + this.#annotationEditorUIManager.destroy(); + this.#annotationEditorUIManager = null; + } + } + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + const pagesCount = pdfDocument.numPages; + const firstPagePromise = pdfDocument.getPage(1); + const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig(); + const permissionsPromise = this.#enablePermissions ? pdfDocument.getPermissions() : Promise.resolve(); + if (pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE) { + console.warn("Forcing PAGE-scrolling for performance reasons, given the length of the document."); + const mode = this._scrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE; + this.eventBus.dispatch("scrollmodechanged", { + source: this, + mode + }); + } + this._pagesCapability.promise.then(() => { + this.eventBus.dispatch("pagesloaded", { + source: this, + pagesCount + }); + }, () => {}); + this._onBeforeDraw = evt => { + const pageView = this._pages[evt.pageNumber - 1]; + if (!pageView) { + return; + } + this.#buffer.push(pageView); + }; + this.eventBus._on("pagerender", this._onBeforeDraw); + this._onAfterDraw = evt => { + if (evt.cssTransform || this._onePageRenderedCapability.settled) { + return; + } + this._onePageRenderedCapability.resolve({ + timestamp: evt.timestamp + }); + this.eventBus._off("pagerendered", this._onAfterDraw); + this._onAfterDraw = null; + if (this.#onVisibilityChange) { + document.removeEventListener("visibilitychange", this.#onVisibilityChange); + this.#onVisibilityChange = null; + } + }; + this.eventBus._on("pagerendered", this._onAfterDraw); + Promise.all([firstPagePromise, permissionsPromise]).then(([firstPdfPage, permissions]) => { + if (pdfDocument !== this.pdfDocument) { + return; + } + this._firstPageCapability.resolve(firstPdfPage); + this._optionalContentConfigPromise = optionalContentConfigPromise; + const { + annotationEditorMode, + annotationMode, + textLayerMode + } = this.#initializePermissions(permissions); + if (textLayerMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.TextLayerMode.DISABLE) { + const element = this.#hiddenCopyElement = document.createElement("div"); + element.id = "hiddenCopyElement"; + this.viewer.before(element); + } + if (annotationEditorMode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE) { + const mode = annotationEditorMode; + if (pdfDocument.isPureXfa) { + console.warn("Warning: XFA-editing is not implemented."); + } else if (isValidAnnotationEditorMode(mode)) { + this.#annotationEditorUIManager = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorUIManager(this.container, this.viewer, this.#altTextManager, this.eventBus, pdfDocument, this.pageColors, this.#annotationEditorHighlightColors); + this.eventBus.dispatch("annotationeditoruimanager", { + source: this, + uiManager: this.#annotationEditorUIManager + }); + if (mode !== pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE) { + this.#annotationEditorUIManager.updateMode(mode); + } + } else { + console.error(`Invalid AnnotationEditor mode: ${mode}`); + } + } + const viewerElement = this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE ? null : this.viewer; + const scale = this.currentScale; + const viewport = firstPdfPage.getViewport({ + scale: scale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS + }); + this.viewer.style.setProperty("--scale-factor", viewport.scale); + if (this.pageColors?.foreground === "CanvasText" || this.pageColors?.background === "Canvas") { + this.viewer.style.setProperty("--hcm-highlight-filter", pdfDocument.filterFactory.addHighlightHCMFilter("CanvasText", "Canvas", "HighlightText", "Highlight")); + } + for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) { + const pageView = new _pdf_page_view_js__WEBPACK_IMPORTED_MODULE_3__.PDFPageView({ + container: viewerElement, + eventBus: this.eventBus, + id: pageNum, + scale, + defaultViewport: viewport.clone(), + optionalContentConfigPromise, + renderingQueue: this.renderingQueue, + textLayerMode, + annotationMode, + imageResourcesPath: this.imageResourcesPath, + isOffscreenCanvasSupported: this.isOffscreenCanvasSupported, + maxCanvasPixels: this.maxCanvasPixels, + pageColors: this.pageColors, + l10n: this.l10n, + layerProperties: this._layerProperties + }); + this._pages.push(pageView); + } + const firstPageView = this._pages[0]; + if (firstPageView) { + firstPageView.setPdfPage(firstPdfPage); + this.linkService.cachePageRef(1, firstPdfPage.ref); + } + if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + } else if (this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) { + this._updateSpreadMode(); + } + this.#onePageRenderedOrForceFetch().then(async () => { + this.findController?.setDocument(pdfDocument); + this._scriptingManager?.setDocument(pdfDocument); + if (this.#hiddenCopyElement) { + this.#copyCallbackBound = this.#copyCallback.bind(this, textLayerMode); + document.addEventListener("copy", this.#copyCallbackBound); + } + if (this.#annotationEditorUIManager) { + this.eventBus.dispatch("annotationeditormodechanged", { + source: this, + mode: this.#annotationEditorMode + }); + } + if (pdfDocument.loadingParams.disableAutoFetch || pagesCount > PagesCountLimit.FORCE_LAZY_PAGE_INIT) { + this._pagesCapability.resolve(); + return; + } + let getPagesLeft = pagesCount - 1; + if (getPagesLeft <= 0) { + this._pagesCapability.resolve(); + return; + } + for (let pageNum = 2; pageNum <= pagesCount; ++pageNum) { + const promise = pdfDocument.getPage(pageNum).then(pdfPage => { + const pageView = this._pages[pageNum - 1]; + if (!pageView.pdfPage) { + pageView.setPdfPage(pdfPage); + } + this.linkService.cachePageRef(pageNum, pdfPage.ref); + if (--getPagesLeft === 0) { + this._pagesCapability.resolve(); + } + }, reason => { + console.error(`Unable to get page ${pageNum} to initialize viewer`, reason); + if (--getPagesLeft === 0) { + this._pagesCapability.resolve(); + } + }); + if (pageNum % PagesCountLimit.PAUSE_EAGER_PAGE_INIT === 0) { + await promise; + } + } + }); + this.eventBus.dispatch("pagesinit", { + source: this + }); + pdfDocument.getMetadata().then(({ + info + }) => { + if (pdfDocument !== this.pdfDocument) { + return; + } + if (info.Language) { + this.viewer.lang = info.Language; + } + }); + if (this.defaultRenderingQueue) { + this.update(); + } + }).catch(reason => { + console.error("Unable to initialize viewer", reason); + this._pagesCapability.reject(reason); + }); + } + setPageLabels(labels) { + if (!this.pdfDocument) { + return; + } + if (!labels) { + this._pageLabels = null; + } else if (!(Array.isArray(labels) && this.pdfDocument.numPages === labels.length)) { + this._pageLabels = null; + console.error(`setPageLabels: Invalid page labels.`); + } else { + this._pageLabels = labels; + } + for (let i = 0, ii = this._pages.length; i < ii; i++) { + this._pages[i].setPageLabel(this._pageLabels?.[i] ?? null); + } + } + _resetView() { + this._pages = []; + this._currentPageNumber = 1; + this._currentScale = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.UNKNOWN_SCALE; + this._currentScaleValue = null; + this._pageLabels = null; + this.#buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE); + this._location = null; + this._pagesRotation = 0; + this._optionalContentConfigPromise = null; + this._firstPageCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(); + this._onePageRenderedCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(); + this._pagesCapability = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PromiseCapability(); + this._scrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.VERTICAL; + this._previousScrollMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.UNKNOWN; + this._spreadMode = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE; + this.#scrollModePageState = { + previousPageNumber: 1, + scrollDown: true, + pages: [] + }; + if (this._onBeforeDraw) { + this.eventBus._off("pagerender", this._onBeforeDraw); + this._onBeforeDraw = null; + } + if (this._onAfterDraw) { + this.eventBus._off("pagerendered", this._onAfterDraw); + this._onAfterDraw = null; + } + if (this.#onVisibilityChange) { + document.removeEventListener("visibilitychange", this.#onVisibilityChange); + this.#onVisibilityChange = null; + } + this.viewer.textContent = ""; + this._updateScrollMode(); + this.viewer.removeAttribute("lang"); + if (this.#hiddenCopyElement) { + document.removeEventListener("copy", this.#copyCallbackBound); + this.#copyCallbackBound = null; + this.#hiddenCopyElement.remove(); + this.#hiddenCopyElement = null; + } + } + #ensurePageViewVisible() { + if (this._scrollMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) { + throw new Error("#ensurePageViewVisible: Invalid scrollMode value."); + } + const pageNumber = this._currentPageNumber, + state = this.#scrollModePageState, + viewer = this.viewer; + viewer.textContent = ""; + state.pages.length = 0; + if (this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && !this.isInPresentationMode) { + const pageView = this._pages[pageNumber - 1]; + viewer.append(pageView.div); + state.pages.push(pageView); + } else { + const pageIndexSet = new Set(), + parity = this._spreadMode - 1; + if (parity === -1) { + pageIndexSet.add(pageNumber - 1); + } else if (pageNumber % 2 !== parity) { + pageIndexSet.add(pageNumber - 1); + pageIndexSet.add(pageNumber); + } else { + pageIndexSet.add(pageNumber - 2); + pageIndexSet.add(pageNumber - 1); + } + const spread = document.createElement("div"); + spread.className = "spread"; + if (this.isInPresentationMode) { + const dummyPage = document.createElement("div"); + dummyPage.className = "dummyPage"; + spread.append(dummyPage); + } + for (const i of pageIndexSet) { + const pageView = this._pages[i]; + if (!pageView) { + continue; + } + spread.append(pageView.div); + state.pages.push(pageView); + } + viewer.append(spread); + } + state.scrollDown = pageNumber >= state.previousPageNumber; + state.previousPageNumber = pageNumber; + } + _scrollUpdate() { + if (this.pagesCount === 0) { + return; + } + this.update(); + } + #scrollIntoView(pageView, pageSpot = null) { + const { + div, + id + } = pageView; + if (this._currentPageNumber !== id) { + this._setCurrentPageNumber(id); + } + if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + this.update(); + } + if (!pageSpot && !this.isInPresentationMode) { + const left = div.offsetLeft + div.clientLeft, + right = left + div.clientWidth; + const { + scrollLeft, + clientWidth + } = this.container; + if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL || left < scrollLeft || right > scrollLeft + clientWidth) { + pageSpot = { + left: 0, + top: 0 + }; + } + } + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.scrollIntoView)(div, pageSpot); + if (!this._currentScaleValue && this._location) { + this._location = null; + } + } + #isSameScale(newScale) { + return newScale === this._currentScale || Math.abs(newScale - this._currentScale) < 1e-15; + } + #setScaleUpdatePages(newScale, newValue, { + noScroll = false, + preset = false, + drawingDelay = -1 + }) { + this._currentScaleValue = newValue.toString(); + if (this.#isSameScale(newScale)) { + if (preset) { + this.eventBus.dispatch("scalechanging", { + source: this, + scale: newScale, + presetValue: newValue + }); + } + return; + } + this.viewer.style.setProperty("--scale-factor", newScale * pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS); + const postponeDrawing = drawingDelay >= 0 && drawingDelay < 1000; + this.refresh(true, { + scale: newScale, + drawingDelay: postponeDrawing ? drawingDelay : -1 + }); + if (postponeDrawing) { + this.#scaleTimeoutId = setTimeout(() => { + this.#scaleTimeoutId = null; + this.refresh(); + }, drawingDelay); + } + this._currentScale = newScale; + if (!noScroll) { + let page = this._currentPageNumber, + dest; + if (this._location && !(this.isInPresentationMode || this.isChangingPresentationMode)) { + page = this._location.pageNumber; + dest = [null, { + name: "XYZ" + }, this._location.left, this._location.top, null]; + } + this.scrollPageIntoView({ + pageNumber: page, + destArray: dest, + allowNegativeOffset: true + }); + } + this.eventBus.dispatch("scalechanging", { + source: this, + scale: newScale, + presetValue: preset ? newValue : undefined + }); + if (this.defaultRenderingQueue) { + this.update(); + } + } + get #pageWidthScaleFactor() { + if (this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && this._scrollMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL) { + return 2; + } + return 1; + } + #setScale(value, options) { + let scale = parseFloat(value); + if (scale > 0) { + options.preset = false; + this.#setScaleUpdatePages(scale, value, options); + } else { + const currentPage = this._pages[this._currentPageNumber - 1]; + if (!currentPage) { + return; + } + let hPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SCROLLBAR_PADDING, + vPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.VERTICAL_PADDING; + if (this.isInPresentationMode) { + hPadding = vPadding = 4; + if (this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) { + hPadding *= 2; + } + } else if (this.removePageBorders) { + hPadding = vPadding = 0; + } else if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL) { + [hPadding, vPadding] = [vPadding, hPadding]; + } + const pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale / this.#pageWidthScaleFactor; + const pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale; + switch (value) { + case "page-actual": + scale = 1; + break; + case "page-width": + scale = pageWidthScale; + break; + case "page-height": + scale = pageHeightScale; + break; + case "page-fit": + scale = Math.min(pageWidthScale, pageHeightScale); + break; + case "auto": + const horizontalScale = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isPortraitOrientation)(currentPage) ? pageWidthScale : Math.min(pageHeightScale, pageWidthScale); + scale = Math.min(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_AUTO_SCALE, horizontalScale); + break; + default: + console.error(`#setScale: "${value}" is an unknown zoom value.`); + return; + } + options.preset = true; + this.#setScaleUpdatePages(scale, value, options); + } + } + #resetCurrentPageView() { + const pageView = this._pages[this._currentPageNumber - 1]; + if (this.isInPresentationMode) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this.#scrollIntoView(pageView); + } + pageLabelToPageNumber(label) { + if (!this._pageLabels) { + return null; + } + const i = this._pageLabels.indexOf(label); + if (i < 0) { + return null; + } + return i + 1; + } + scrollPageIntoView({ + pageNumber, + destArray = null, + allowNegativeOffset = false, + ignoreDestinationZoom = false + }) { + if (!this.pdfDocument) { + return; + } + const pageView = Number.isInteger(pageNumber) && this._pages[pageNumber - 1]; + if (!pageView) { + console.error(`scrollPageIntoView: "${pageNumber}" is not a valid pageNumber parameter.`); + return; + } + if (this.isInPresentationMode || !destArray) { + this._setCurrentPageNumber(pageNumber, true); + return; + } + let x = 0, + y = 0; + let width = 0, + height = 0, + widthScale, + heightScale; + const changeOrientation = pageView.rotation % 180 !== 0; + const pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS; + const pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS; + let scale = 0; + switch (destArray[1].name) { + case "XYZ": + x = destArray[2]; + y = destArray[3]; + scale = destArray[4]; + x = x !== null ? x : 0; + y = y !== null ? y : pageHeight; + break; + case "Fit": + case "FitB": + scale = "page-fit"; + break; + case "FitH": + case "FitBH": + y = destArray[2]; + scale = "page-width"; + if (y === null && this._location) { + x = this._location.left; + y = this._location.top; + } else if (typeof y !== "number" || y < 0) { + y = pageHeight; + } + break; + case "FitV": + case "FitBV": + x = destArray[2]; + width = pageWidth; + height = pageHeight; + scale = "page-height"; + break; + case "FitR": + x = destArray[2]; + y = destArray[3]; + width = destArray[4] - x; + height = destArray[5] - y; + let hPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SCROLLBAR_PADDING, + vPadding = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.VERTICAL_PADDING; + if (this.removePageBorders) { + hPadding = vPadding = 0; + } + widthScale = (this.container.clientWidth - hPadding) / width / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS; + heightScale = (this.container.clientHeight - vPadding) / height / pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS; + scale = Math.min(Math.abs(widthScale), Math.abs(heightScale)); + break; + default: + console.error(`scrollPageIntoView: "${destArray[1].name}" is not a valid destination type.`); + return; + } + if (!ignoreDestinationZoom) { + if (scale && scale !== this._currentScale) { + this.currentScaleValue = scale; + } else if (this._currentScale === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.UNKNOWN_SCALE) { + this.currentScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_VALUE; + } + } + if (scale === "page-fit" && !destArray[4]) { + this.#scrollIntoView(pageView); + return; + } + const boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)]; + let left = Math.min(boundingRect[0][0], boundingRect[1][0]); + let top = Math.min(boundingRect[0][1], boundingRect[1][1]); + if (!allowNegativeOffset) { + left = Math.max(left, 0); + top = Math.max(top, 0); + } + this.#scrollIntoView(pageView, { + left, + top + }); + } + _updateLocation(firstPage) { + const currentScale = this._currentScale; + const currentScaleValue = this._currentScaleValue; + const normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue; + const pageNumber = firstPage.id; + const currentPageView = this._pages[pageNumber - 1]; + const container = this.container; + const topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y); + const intLeft = Math.round(topLeft[0]); + const intTop = Math.round(topLeft[1]); + let pdfOpenParams = `#page=${pageNumber}`; + if (!this.isInPresentationMode) { + pdfOpenParams += `&zoom=${normalizedScaleValue},${intLeft},${intTop}`; + } + this._location = { + pageNumber, + scale: normalizedScaleValue, + top: intTop, + left: intLeft, + rotation: this._pagesRotation, + pdfOpenParams + }; + } + update() { + const visible = this._getVisiblePages(); + const visiblePages = visible.views, + numVisiblePages = visiblePages.length; + if (numVisiblePages === 0) { + return; + } + const newCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * numVisiblePages + 1); + this.#buffer.resize(newCacheSize, visible.ids); + this.renderingQueue.renderHighestPriority(visible); + const isSimpleLayout = this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE || this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.VERTICAL); + const currentId = this._currentPageNumber; + let stillFullyVisible = false; + for (const page of visiblePages) { + if (page.percent < 100) { + break; + } + if (page.id === currentId && isSimpleLayout) { + stillFullyVisible = true; + break; + } + } + this._setCurrentPageNumber(stillFullyVisible ? currentId : visiblePages[0].id); + this._updateLocation(visible.first); + this.eventBus.dispatch("updateviewarea", { + source: this, + location: this._location + }); + } + containsElement(element) { + return this.container.contains(element); + } + focus() { + this.container.focus(); + } + get _isContainerRtl() { + return getComputedStyle(this.container).direction === "rtl"; + } + get isInPresentationMode() { + return this.presentationModeState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.FULLSCREEN; + } + get isChangingPresentationMode() { + return this.presentationModeState === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.PresentationModeState.CHANGING; + } + get isHorizontalScrollbarEnabled() { + return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth; + } + get isVerticalScrollbarEnabled() { + return this.isInPresentationMode ? false : this.container.scrollHeight > this.container.clientHeight; + } + _getVisiblePages() { + const views = this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE ? this.#scrollModePageState.pages : this._pages, + horizontal = this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL, + rtl = horizontal && this._isContainerRtl; + return (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.getVisibleElements)({ + scrollEl: this.container, + views, + sortByVisibility: true, + horizontal, + rtl + }); + } + cleanup() { + for (const pageView of this._pages) { + if (pageView.renderingState !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.RenderingStates.FINISHED) { + pageView.reset(); + } + } + } + _cancelRendering() { + for (const pageView of this._pages) { + pageView.cancelRendering(); + } + } + async #ensurePdfPageLoaded(pageView) { + if (pageView.pdfPage) { + return pageView.pdfPage; + } + try { + const pdfPage = await this.pdfDocument.getPage(pageView.id); + if (!pageView.pdfPage) { + pageView.setPdfPage(pdfPage); + } + if (!this.linkService._cachedPageNumber?.(pdfPage.ref)) { + this.linkService.cachePageRef(pageView.id, pdfPage.ref); + } + return pdfPage; + } catch (reason) { + console.error("Unable to get page for page view", reason); + return null; + } + } + #getScrollAhead(visible) { + if (visible.first?.id === 1) { + return true; + } else if (visible.last?.id === this.pagesCount) { + return false; + } + switch (this._scrollMode) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE: + return this.#scrollModePageState.scrollDown; + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL: + return this.scroll.right; + } + return this.scroll.down; + } + forceRendering(currentlyVisiblePages) { + const visiblePages = currentlyVisiblePages || this._getVisiblePages(); + const scrollAhead = this.#getScrollAhead(visiblePages); + const preRenderExtra = this._spreadMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE && this._scrollMode !== _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL; + const pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, scrollAhead, preRenderExtra); + if (pageView) { + this.#ensurePdfPageLoaded(pageView).then(() => { + this.renderingQueue.renderView(pageView); + }); + return true; + } + return false; + } + get hasEqualPageSizes() { + const firstPageView = this._pages[0]; + for (let i = 1, ii = this._pages.length; i < ii; ++i) { + const pageView = this._pages[i]; + if (pageView.width !== firstPageView.width || pageView.height !== firstPageView.height) { + return false; + } + } + return true; + } + getPagesOverview() { + let initialOrientation; + return this._pages.map(pageView => { + const viewport = pageView.pdfPage.getViewport({ + scale: 1 + }); + const orientation = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isPortraitOrientation)(viewport); + if (initialOrientation === undefined) { + initialOrientation = orientation; + } else if (this.enablePrintAutoRotate && orientation !== initialOrientation) { + return { + width: viewport.height, + height: viewport.width, + rotation: (viewport.rotation - 90) % 360 + }; + } + return { + width: viewport.width, + height: viewport.height, + rotation: viewport.rotation + }; + }); + } + get optionalContentConfigPromise() { + if (!this.pdfDocument) { + return Promise.resolve(null); + } + if (!this._optionalContentConfigPromise) { + console.error("optionalContentConfigPromise: Not initialized yet."); + return this.pdfDocument.getOptionalContentConfig(); + } + return this._optionalContentConfigPromise; + } + set optionalContentConfigPromise(promise) { + if (!(promise instanceof Promise)) { + throw new Error(`Invalid optionalContentConfigPromise: ${promise}`); + } + if (!this.pdfDocument) { + return; + } + if (!this._optionalContentConfigPromise) { + return; + } + this._optionalContentConfigPromise = promise; + this.refresh(false, { + optionalContentConfigPromise: promise + }); + this.eventBus.dispatch("optionalcontentconfigchanged", { + source: this, + promise + }); + } + get scrollMode() { + return this._scrollMode; + } + set scrollMode(mode) { + if (this._scrollMode === mode) { + return; + } + if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isValidScrollMode)(mode)) { + throw new Error(`Invalid scroll mode: ${mode}`); + } + if (this.pagesCount > PagesCountLimit.FORCE_SCROLL_MODE_PAGE) { + return; + } + this._previousScrollMode = this._scrollMode; + this._scrollMode = mode; + this.eventBus.dispatch("scrollmodechanged", { + source: this, + mode + }); + this._updateScrollMode(this._currentPageNumber); + } + _updateScrollMode(pageNumber = null) { + const scrollMode = this._scrollMode, + viewer = this.viewer; + viewer.classList.toggle("scrollHorizontal", scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL); + viewer.classList.toggle("scrollWrapped", scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.WRAPPED); + if (!this.pdfDocument || !pageNumber) { + return; + } + if (scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + } else if (this._previousScrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) { + this._updateSpreadMode(); + } + if (this._currentScaleValue && isNaN(this._currentScaleValue)) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this._setCurrentPageNumber(pageNumber, true); + this.update(); + } + get spreadMode() { + return this._spreadMode; + } + set spreadMode(mode) { + if (this._spreadMode === mode) { + return; + } + if (!(0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.isValidSpreadMode)(mode)) { + throw new Error(`Invalid spread mode: ${mode}`); + } + this._spreadMode = mode; + this.eventBus.dispatch("spreadmodechanged", { + source: this, + mode + }); + this._updateSpreadMode(this._currentPageNumber); + } + _updateSpreadMode(pageNumber = null) { + if (!this.pdfDocument) { + return; + } + const viewer = this.viewer, + pages = this._pages; + if (this._scrollMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE) { + this.#ensurePageViewVisible(); + } else { + viewer.textContent = ""; + if (this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) { + for (const pageView of this._pages) { + viewer.append(pageView.div); + } + } else { + const parity = this._spreadMode - 1; + let spread = null; + for (let i = 0, ii = pages.length; i < ii; ++i) { + if (spread === null) { + spread = document.createElement("div"); + spread.className = "spread"; + viewer.append(spread); + } else if (i % 2 === parity) { + spread = spread.cloneNode(false); + viewer.append(spread); + } + spread.append(pages[i].div); + } + } + } + if (!pageNumber) { + return; + } + if (this._currentScaleValue && isNaN(this._currentScaleValue)) { + this.#setScale(this._currentScaleValue, { + noScroll: true + }); + } + this._setCurrentPageNumber(pageNumber, true); + this.update(); + } + _getPageAdvance(currentPageNumber, previous = false) { + switch (this._scrollMode) { + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.WRAPPED: + { + const { + views + } = this._getVisiblePages(), + pageLayout = new Map(); + for (const { + id, + y, + percent, + widthPercent + } of views) { + if (percent === 0 || widthPercent < 100) { + continue; + } + let yArray = pageLayout.get(y); + if (!yArray) { + pageLayout.set(y, yArray ||= []); + } + yArray.push(id); + } + for (const yArray of pageLayout.values()) { + const currentIndex = yArray.indexOf(currentPageNumber); + if (currentIndex === -1) { + continue; + } + const numPages = yArray.length; + if (numPages === 1) { + break; + } + if (previous) { + for (let i = currentIndex - 1, ii = 0; i >= ii; i--) { + const currentId = yArray[i], + expectedId = yArray[i + 1] - 1; + if (currentId < expectedId) { + return currentPageNumber - expectedId; + } + } + } else { + for (let i = currentIndex + 1, ii = numPages; i < ii; i++) { + const currentId = yArray[i], + expectedId = yArray[i - 1] + 1; + if (currentId > expectedId) { + return expectedId - currentPageNumber; + } + } + } + if (previous) { + const firstId = yArray[0]; + if (firstId < currentPageNumber) { + return currentPageNumber - firstId + 1; + } + } else { + const lastId = yArray[numPages - 1]; + if (lastId > currentPageNumber) { + return lastId - currentPageNumber + 1; + } + } + break; + } + break; + } + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.HORIZONTAL: + { + break; + } + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.PAGE: + case _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.ScrollMode.VERTICAL: + { + if (this._spreadMode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.SpreadMode.NONE) { + break; + } + const parity = this._spreadMode - 1; + if (previous && currentPageNumber % 2 !== parity) { + break; + } else if (!previous && currentPageNumber % 2 === parity) { + break; + } + const { + views + } = this._getVisiblePages(), + expectedId = previous ? currentPageNumber - 1 : currentPageNumber + 1; + for (const { + id, + percent, + widthPercent + } of views) { + if (id !== expectedId) { + continue; + } + if (percent > 0 && widthPercent === 100) { + return 2; + } + break; + } + break; + } + } + return 1; + } + nextPage() { + const currentPageNumber = this._currentPageNumber, + pagesCount = this.pagesCount; + if (currentPageNumber >= pagesCount) { + return false; + } + const advance = this._getPageAdvance(currentPageNumber, false) || 1; + this.currentPageNumber = Math.min(currentPageNumber + advance, pagesCount); + return true; + } + previousPage() { + const currentPageNumber = this._currentPageNumber; + if (currentPageNumber <= 1) { + return false; + } + const advance = this._getPageAdvance(currentPageNumber, true) || 1; + this.currentPageNumber = Math.max(currentPageNumber - advance, 1); + return true; + } + increaseScale({ + drawingDelay, + scaleFactor, + steps + } = {}) { + if (!this.pdfDocument) { + return; + } + let newScale = this._currentScale; + if (scaleFactor > 1) { + newScale = Math.round(newScale * scaleFactor * 100) / 100; + } else { + steps ??= 1; + do { + newScale = Math.ceil((newScale * _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10; + } while (--steps > 0 && newScale < _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_SCALE); + } + this.#setScale(Math.min(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_SCALE, newScale), { + noScroll: false, + drawingDelay + }); + } + decreaseScale({ + drawingDelay, + scaleFactor, + steps + } = {}) { + if (!this.pdfDocument) { + return; + } + let newScale = this._currentScale; + if (scaleFactor > 0 && scaleFactor < 1) { + newScale = Math.round(newScale * scaleFactor * 100) / 100; + } else { + steps ??= 1; + do { + newScale = Math.floor((newScale / _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_DELTA).toFixed(2) * 10) / 10; + } while (--steps > 0 && newScale > _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MIN_SCALE); + } + this.#setScale(Math.max(_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MIN_SCALE, newScale), { + noScroll: false, + drawingDelay + }); + } + #updateContainerHeightCss(height = this.container.clientHeight) { + if (height !== this.#previousContainerHeight) { + this.#previousContainerHeight = height; + _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.docStyle.setProperty("--viewer-container-height", `${height}px`); + } + } + #resizeObserverCallback(entries) { + for (const entry of entries) { + if (entry.target === this.container) { + this.#updateContainerHeightCss(Math.floor(entry.borderBoxSize[0].blockSize)); + this.#containerTopLeft = null; + break; + } + } + } + get containerTopLeft() { + return this.#containerTopLeft ||= [this.container.offsetTop, this.container.offsetLeft]; + } + get annotationEditorMode() { + return this.#annotationEditorUIManager ? this.#annotationEditorMode : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE; + } + set annotationEditorMode({ + mode, + editId = null, + isFromKeyboard = false + }) { + if (!this.#annotationEditorUIManager) { + throw new Error(`The AnnotationEditor is not enabled.`); + } + if (this.#annotationEditorMode === mode) { + return; + } + if (!isValidAnnotationEditorMode(mode)) { + throw new Error(`Invalid AnnotationEditor mode: ${mode}`); + } + if (!this.pdfDocument) { + return; + } + this.#annotationEditorMode = mode; + this.eventBus.dispatch("annotationeditormodechanged", { + source: this, + mode + }); + this.#annotationEditorUIManager.updateMode(mode, editId, isFromKeyboard); + } + set annotationEditorParams({ + type, + value + }) { + if (!this.#annotationEditorUIManager) { + throw new Error(`The AnnotationEditor is not enabled.`); + } + this.#annotationEditorUIManager.updateParams(type, value); + } + refresh(noUpdate = false, updateArgs = Object.create(null)) { + if (!this.pdfDocument) { + return; + } + for (const pageView of this._pages) { + pageView.update(updateArgs); + } + if (this.#scaleTimeoutId !== null) { + clearTimeout(this.#scaleTimeoutId); + this.#scaleTimeoutId = null; + } + if (!noUpdate) { + this.update(); + } + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1869: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AbortException: () => (/* binding */ AbortException), +/* harmony export */ AnnotationEditorLayer: () => (/* binding */ AnnotationEditorLayer), +/* harmony export */ AnnotationEditorParamsType: () => (/* binding */ AnnotationEditorParamsType), +/* harmony export */ AnnotationEditorType: () => (/* binding */ AnnotationEditorType), +/* harmony export */ AnnotationEditorUIManager: () => (/* binding */ AnnotationEditorUIManager), +/* harmony export */ AnnotationLayer: () => (/* binding */ AnnotationLayer), +/* harmony export */ AnnotationMode: () => (/* binding */ AnnotationMode), +/* harmony export */ ColorPicker: () => (/* binding */ ColorPicker), +/* harmony export */ DOMSVGFactory: () => (/* binding */ DOMSVGFactory), +/* harmony export */ DrawLayer: () => (/* binding */ DrawLayer), +/* harmony export */ FeatureTest: () => (/* binding */ FeatureTest), +/* harmony export */ GlobalWorkerOptions: () => (/* binding */ GlobalWorkerOptions), +/* harmony export */ InvalidPDFException: () => (/* binding */ InvalidPDFException), +/* harmony export */ MissingPDFException: () => (/* binding */ MissingPDFException), +/* harmony export */ PDFDateString: () => (/* binding */ PDFDateString), +/* harmony export */ PDFWorker: () => (/* binding */ PDFWorker), +/* harmony export */ PasswordResponses: () => (/* binding */ PasswordResponses), +/* harmony export */ PermissionFlag: () => (/* binding */ PermissionFlag), +/* harmony export */ PixelsPerInch: () => (/* binding */ PixelsPerInch), +/* harmony export */ PromiseCapability: () => (/* binding */ PromiseCapability), +/* harmony export */ RenderingCancelledException: () => (/* binding */ RenderingCancelledException), +/* harmony export */ UnexpectedResponseException: () => (/* binding */ UnexpectedResponseException), +/* harmony export */ XfaLayer: () => (/* binding */ XfaLayer), +/* harmony export */ build: () => (/* binding */ build), +/* harmony export */ createValidAbsoluteUrl: () => (/* binding */ createValidAbsoluteUrl), +/* harmony export */ fetchData: () => (/* binding */ fetchData), +/* harmony export */ getDocument: () => (/* binding */ getDocument), +/* harmony export */ getFilenameFromUrl: () => (/* binding */ getFilenameFromUrl), +/* harmony export */ getPdfFilenameFromUrl: () => (/* binding */ getPdfFilenameFromUrl), +/* harmony export */ getXfaPageViewport: () => (/* binding */ getXfaPageViewport), +/* harmony export */ isDataScheme: () => (/* binding */ isDataScheme), +/* harmony export */ isPdfFile: () => (/* binding */ isPdfFile), +/* harmony export */ noContextMenu: () => (/* binding */ noContextMenu), +/* harmony export */ normalizeUnicode: () => (/* binding */ normalizeUnicode), +/* harmony export */ renderTextLayer: () => (/* binding */ renderTextLayer), +/* harmony export */ setLayerDimensions: () => (/* binding */ setLayerDimensions), +/* harmony export */ shadow: () => (/* binding */ shadow), +/* harmony export */ updateTextLayer: () => (/* binding */ updateTextLayer), +/* harmony export */ version: () => (/* binding */ version) +/* harmony export */ }); +/* unused harmony exports CMapCompressionType, ImageKind, OPS, Outliner, PDFDataRangeTransport, Util, VerbosityLevel */ +if (!globalThis.pdfjsLib) { + await globalThis.pdfjsLibPromise; +} +const { + AbortException, + AnnotationEditorLayer, + AnnotationEditorParamsType, + AnnotationEditorType, + AnnotationEditorUIManager, + AnnotationLayer, + AnnotationMode, + build, + CMapCompressionType, + ColorPicker, + createValidAbsoluteUrl, + DOMSVGFactory, + DrawLayer, + FeatureTest, + fetchData, + getDocument, + getFilenameFromUrl, + getPdfFilenameFromUrl, + getXfaPageViewport, + GlobalWorkerOptions, + ImageKind, + InvalidPDFException, + isDataScheme, + isPdfFile, + MissingPDFException, + noContextMenu, + normalizeUnicode, + OPS, + Outliner, + PasswordResponses, + PDFDataRangeTransport, + PDFDateString, + PDFWorker, + PermissionFlag, + PixelsPerInch, + PromiseCapability, + RenderingCancelledException, + renderTextLayer, + setLayerDimensions, + shadow, + UnexpectedResponseException, + updateTextLayer, + Util, + VerbosityLevel, + version, + XfaLayer +} = globalThis.pdfjsLib; + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }, 1); + +/***/ }), + +/***/ 216: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ BasePreferences: () => (/* binding */ BasePreferences) +/* harmony export */ }); +/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8961); + +class BasePreferences { + #defaults = Object.freeze({ + "annotationEditorMode": 0, + "annotationMode": 2, + "cursorToolOnLoad": 0, + "defaultZoomDelay": 400, + "defaultZoomValue": "", + "disablePageLabels": false, + "enableHighlightEditor": false, + "enablePermissions": false, + "enablePrintAutoRotate": true, + "enableScripting": true, + "externalLinkTarget": 0, + "highlightEditorColors": "yellow=#FFFF98,green=#53FFBC,blue=#80EBFF,pink=#FFCBE6,red=#FF4F5F", + "historyUpdateUrl": false, + "ignoreDestinationZoom": false, + "forcePageColors": false, + "pageColorsBackground": "Canvas", + "pageColorsForeground": "CanvasText", + "pdfBugEnabled": false, + "sidebarViewOnLoad": -1, + "scrollModeOnLoad": -1, + "spreadModeOnLoad": -1, + "textLayerMode": 1, + "viewOnLoad": 0, + "disableAutoFetch": false, + "disableFontFace": false, + "disableRange": false, + "disableStream": false, + "enableXfa": true, + "viewerCssTheme": 0 + }); + #prefs = Object.create(null); + #initializedPromise = null; + constructor() { + if (this.constructor === BasePreferences) { + throw new Error("Cannot initialize BasePreferences."); + } + this.#initializedPromise = this._readFromStorage(this.#defaults).then(({ + browserPrefs, + prefs + }) => { + const BROWSER_PREFS = { + "canvasMaxAreaInBytes": -1, + "isInAutomation": false, + "supportsDocumentFonts": true, + "supportsIntegratedFind": false, + "supportsMouseWheelZoomCtrlKey": true, + "supportsMouseWheelZoomMetaKey": true, + "supportsPinchToZoom": true + }; + const options = Object.create(null); + for (const [name, defaultVal] of Object.entries(BROWSER_PREFS)) { + const prefVal = browserPrefs?.[name]; + options[name] = typeof prefVal === typeof defaultVal ? prefVal : defaultVal; + } + for (const [name, defaultVal] of Object.entries(this.#defaults)) { + const prefVal = prefs?.[name]; + options[name] = this.#prefs[name] = typeof prefVal === typeof defaultVal ? prefVal : defaultVal; + } + _app_options_js__WEBPACK_IMPORTED_MODULE_0__.AppOptions.setAll(options, true); + }); + } + async _writeToStorage(prefObj) { + throw new Error("Not implemented: _writeToStorage"); + } + async _readFromStorage(prefObj) { + throw new Error("Not implemented: _readFromStorage"); + } + async reset() { + await this.#initializedPromise; + const prefs = this.#prefs; + this.#prefs = Object.create(null); + return this._writeToStorage(this.#defaults).catch(reason => { + this.#prefs = prefs; + throw reason; + }); + } + async set(name, value) { + await this.#initializedPromise; + const defaultValue = this.#defaults[name], + prefs = this.#prefs; + if (defaultValue === undefined) { + throw new Error(`Set preference: "${name}" is undefined.`); + } else if (value === undefined) { + throw new Error("Set preference: no value is specified."); + } + const valueType = typeof value, + defaultType = typeof defaultValue; + if (valueType !== defaultType) { + if (valueType === "number" && defaultType === "string") { + value = value.toString(); + } else { + throw new Error(`Set preference: "${value}" is a ${valueType}, expected a ${defaultType}.`); + } + } else if (valueType === "number" && !Number.isInteger(value)) { + throw new Error(`Set preference: "${value}" must be an integer.`); + } + this.#prefs[name] = value; + return this._writeToStorage(this.#prefs).catch(reason => { + this.#prefs = prefs; + throw reason; + }); + } + async get(name) { + await this.#initializedPromise; + const defaultValue = this.#defaults[name]; + if (defaultValue === undefined) { + throw new Error(`Get preference: "${name}" is undefined.`); + } + return this.#prefs[name] ?? defaultValue; + } + get initializedPromise() { + return this.#initializedPromise; + } +} + + +/***/ }), + +/***/ 4552: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ getXfaHtmlForPrinting: () => (/* binding */ getXfaHtmlForPrinting) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3234); +/* harmony import */ var _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8012); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__]); +([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__, _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + +function getXfaHtmlForPrinting(printContainer, pdfDocument) { + const xfaHtml = pdfDocument.allXfaHtml; + const linkService = new _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_1__.SimpleLinkService(); + const scale = Math.round(pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.PixelsPerInch.PDF_TO_CSS_UNITS * 100) / 100; + for (const xfaPage of xfaHtml.children) { + const page = document.createElement("div"); + page.className = "xfaPrintedPage"; + printContainer.append(page); + const builder = new _xfa_layer_builder_js__WEBPACK_IMPORTED_MODULE_2__.XfaLayerBuilder({ + pdfPage: null, + annotationStorage: pdfDocument.annotationStorage, + linkService, + xfaHtml: xfaPage + }); + const viewport = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.getXfaPageViewport)(xfaPage, { + scale + }); + builder.render(viewport, "print"); + page.append(builder.div); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 1544: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ SecondaryToolbar: () => (/* binding */ SecondaryToolbar) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); +/* harmony import */ var _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9290); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([_pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__]); +_pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +class SecondaryToolbar { + #opts; + constructor(options, eventBus) { + this.#opts = options; + const buttons = [{ + element: options.presentationModeButton, + eventName: "presentationmode", + close: true + }, { + element: options.printButton, + eventName: "print", + close: true + }, { + element: options.downloadButton, + eventName: "download", + close: true + }, { + element: options.viewBookmarkButton, + eventName: null, + close: true + }, { + element: options.firstPageButton, + eventName: "firstpage", + close: true + }, { + element: options.lastPageButton, + eventName: "lastpage", + close: true + }, { + element: options.pageRotateCwButton, + eventName: "rotatecw", + close: false + }, { + element: options.pageRotateCcwButton, + eventName: "rotateccw", + close: false + }, { + element: options.cursorSelectToolButton, + eventName: "switchcursortool", + eventDetails: { + tool: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.SELECT + }, + close: true + }, { + element: options.cursorHandToolButton, + eventName: "switchcursortool", + eventDetails: { + tool: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.HAND + }, + close: true + }, { + element: options.scrollPageButton, + eventName: "switchscrollmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.PAGE + }, + close: true + }, { + element: options.scrollVerticalButton, + eventName: "switchscrollmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.VERTICAL + }, + close: true + }, { + element: options.scrollHorizontalButton, + eventName: "switchscrollmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.HORIZONTAL + }, + close: true + }, { + element: options.scrollWrappedButton, + eventName: "switchscrollmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.WRAPPED + }, + close: true + }, { + element: options.spreadNoneButton, + eventName: "switchspreadmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE + }, + close: true + }, { + element: options.spreadOddButton, + eventName: "switchspreadmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.ODD + }, + close: true + }, { + element: options.spreadEvenButton, + eventName: "switchspreadmode", + eventDetails: { + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.EVEN + }, + close: true + }, { + element: options.documentPropertiesButton, + eventName: "documentproperties", + close: true + }]; + buttons.push({ + element: options.openFileButton, + eventName: "openfile", + close: true + }); + this.eventBus = eventBus; + this.opened = false; + this.#bindListeners(buttons); + this.reset(); + } + get isOpen() { + return this.opened; + } + setPageNumber(pageNumber) { + this.pageNumber = pageNumber; + this.#updateUIState(); + } + setPagesCount(pagesCount) { + this.pagesCount = pagesCount; + this.#updateUIState(); + } + reset() { + this.pageNumber = 0; + this.pagesCount = 0; + this.#updateUIState(); + this.#scrollModeChanged({ + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.VERTICAL + }); + this.#spreadModeChanged({ + mode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE + }); + } + #updateUIState() { + const { + firstPageButton, + lastPageButton, + pageRotateCwButton, + pageRotateCcwButton + } = this.#opts; + firstPageButton.disabled = this.pageNumber <= 1; + lastPageButton.disabled = this.pageNumber >= this.pagesCount; + pageRotateCwButton.disabled = this.pagesCount === 0; + pageRotateCcwButton.disabled = this.pagesCount === 0; + } + #bindListeners(buttons) { + const { + eventBus + } = this; + const { + toggleButton + } = this.#opts; + toggleButton.addEventListener("click", this.toggle.bind(this)); + for (const { + element, + eventName, + close, + eventDetails + } of buttons) { + element.addEventListener("click", evt => { + if (eventName !== null) { + eventBus.dispatch(eventName, { + source: this, + ...eventDetails + }); + } + if (close) { + this.close(); + } + eventBus.dispatch("reporttelemetry", { + source: this, + details: { + type: "buttons", + data: { + id: element.id + } + } + }); + }); + } + eventBus._on("cursortoolchanged", this.#cursorToolChanged.bind(this)); + eventBus._on("scrollmodechanged", this.#scrollModeChanged.bind(this)); + eventBus._on("spreadmodechanged", this.#spreadModeChanged.bind(this)); + } + #cursorToolChanged({ + tool + }) { + const { + cursorSelectToolButton, + cursorHandToolButton + } = this.#opts; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(cursorSelectToolButton, tool === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.SELECT); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(cursorHandToolButton, tool === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.CursorTool.HAND); + } + #scrollModeChanged({ + mode + }) { + const { + scrollPageButton, + scrollVerticalButton, + scrollHorizontalButton, + scrollWrappedButton, + spreadNoneButton, + spreadOddButton, + spreadEvenButton + } = this.#opts; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollPageButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.PAGE); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollVerticalButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.VERTICAL); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollHorizontalButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.HORIZONTAL); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(scrollWrappedButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.WRAPPED); + const forceScrollModePage = this.pagesCount > _pdf_viewer_js__WEBPACK_IMPORTED_MODULE_1__.PagesCountLimit.FORCE_SCROLL_MODE_PAGE; + scrollPageButton.disabled = forceScrollModePage; + scrollVerticalButton.disabled = forceScrollModePage; + scrollHorizontalButton.disabled = forceScrollModePage; + scrollWrappedButton.disabled = forceScrollModePage; + const isHorizontal = mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.ScrollMode.HORIZONTAL; + spreadNoneButton.disabled = isHorizontal; + spreadOddButton.disabled = isHorizontal; + spreadEvenButton.disabled = isHorizontal; + } + #spreadModeChanged({ + mode + }) { + const { + spreadNoneButton, + spreadOddButton, + spreadEvenButton + } = this.#opts; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(spreadNoneButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.NONE); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(spreadOddButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.ODD); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleCheckedBtn)(spreadEvenButton, mode === _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.SpreadMode.EVEN); + } + open() { + if (this.opened) { + return; + } + this.opened = true; + const { + toggleButton, + toolbar + } = this.#opts; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(toggleButton, true, toolbar); + } + close() { + if (!this.opened) { + return; + } + this.opened = false; + const { + toggleButton, + toolbar + } = this.#opts; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.toggleExpandedBtn)(toggleButton, false, toolbar); + } + toggle() { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 7498: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ StructTreeLayerBuilder: () => (/* binding */ StructTreeLayerBuilder) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); + +const PDF_ROLE_TO_HTML_ROLE = { + Document: null, + DocumentFragment: null, + Part: "group", + Sect: "group", + Div: "group", + Aside: "note", + NonStruct: "none", + P: null, + H: "heading", + Title: null, + FENote: "note", + Sub: "group", + Lbl: null, + Span: null, + Em: null, + Strong: null, + Link: "link", + Annot: "note", + Form: "form", + Ruby: null, + RB: null, + RT: null, + RP: null, + Warichu: null, + WT: null, + WP: null, + L: "list", + LI: "listitem", + LBody: null, + Table: "table", + TR: "row", + TH: "columnheader", + TD: "cell", + THead: "columnheader", + TBody: null, + TFoot: null, + Caption: null, + Figure: "figure", + Formula: null, + Artifact: null +}; +const HEADING_PATTERN = /^H(\d+)$/; +class StructTreeLayerBuilder { + #treeDom = undefined; + get renderingDone() { + return this.#treeDom !== undefined; + } + render(structTree) { + if (this.#treeDom !== undefined) { + return this.#treeDom; + } + const treeDom = this.#walk(structTree); + treeDom?.classList.add("structTree"); + return this.#treeDom = treeDom; + } + hide() { + if (this.#treeDom && !this.#treeDom.hidden) { + this.#treeDom.hidden = true; + } + } + show() { + if (this.#treeDom?.hidden) { + this.#treeDom.hidden = false; + } + } + #setAttributes(structElement, htmlElement) { + const { + alt, + id, + lang + } = structElement; + if (alt !== undefined) { + htmlElement.setAttribute("aria-label", (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeNullCharacters)(alt)); + } + if (id !== undefined) { + htmlElement.setAttribute("aria-owns", id); + } + if (lang !== undefined) { + htmlElement.setAttribute("lang", (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.removeNullCharacters)(lang, true)); + } + } + #walk(node) { + if (!node) { + return null; + } + const element = document.createElement("span"); + if ("role" in node) { + const { + role + } = node; + const match = role.match(HEADING_PATTERN); + if (match) { + element.setAttribute("role", "heading"); + element.setAttribute("aria-level", match[1]); + } else if (PDF_ROLE_TO_HTML_ROLE[role]) { + element.setAttribute("role", PDF_ROLE_TO_HTML_ROLE[role]); + } + } + this.#setAttributes(node, element); + if (node.children) { + if (node.children.length === 1 && "id" in node.children[0]) { + this.#setAttributes(node.children[0], element); + } else { + for (const kid of node.children) { + element.append(this.#walk(kid)); + } + } + } + return element; + } +} + + +/***/ }), + +/***/ 4630: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ TextAccessibilityManager: () => (/* binding */ TextAccessibilityManager) +/* harmony export */ }); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4927); + +class TextAccessibilityManager { + #enabled = false; + #textChildren = null; + #textNodes = new Map(); + #waitingElements = new Map(); + setTextMapping(textDivs) { + this.#textChildren = textDivs; + } + static #compareElementPositions(e1, e2) { + const rect1 = e1.getBoundingClientRect(); + const rect2 = e2.getBoundingClientRect(); + if (rect1.width === 0 && rect1.height === 0) { + return +1; + } + if (rect2.width === 0 && rect2.height === 0) { + return -1; + } + const top1 = rect1.y; + const bot1 = rect1.y + rect1.height; + const mid1 = rect1.y + rect1.height / 2; + const top2 = rect2.y; + const bot2 = rect2.y + rect2.height; + const mid2 = rect2.y + rect2.height / 2; + if (mid1 <= top2 && mid2 >= bot1) { + return -1; + } + if (mid2 <= top1 && mid1 >= bot2) { + return +1; + } + const centerX1 = rect1.x + rect1.width / 2; + const centerX2 = rect2.x + rect2.width / 2; + return centerX1 - centerX2; + } + enable() { + if (this.#enabled) { + throw new Error("TextAccessibilityManager is already enabled."); + } + if (!this.#textChildren) { + throw new Error("Text divs and strings have not been set."); + } + this.#enabled = true; + this.#textChildren = this.#textChildren.slice(); + this.#textChildren.sort(TextAccessibilityManager.#compareElementPositions); + if (this.#textNodes.size > 0) { + const textChildren = this.#textChildren; + for (const [id, nodeIndex] of this.#textNodes) { + const element = document.getElementById(id); + if (!element) { + this.#textNodes.delete(id); + continue; + } + this.#addIdToAriaOwns(id, textChildren[nodeIndex]); + } + } + for (const [element, isRemovable] of this.#waitingElements) { + this.addPointerInTextLayer(element, isRemovable); + } + this.#waitingElements.clear(); + } + disable() { + if (!this.#enabled) { + return; + } + this.#waitingElements.clear(); + this.#textChildren = null; + this.#enabled = false; + } + removePointerInTextLayer(element) { + if (!this.#enabled) { + this.#waitingElements.delete(element); + return; + } + const children = this.#textChildren; + if (!children || children.length === 0) { + return; + } + const { + id + } = element; + const nodeIndex = this.#textNodes.get(id); + if (nodeIndex === undefined) { + return; + } + const node = children[nodeIndex]; + this.#textNodes.delete(id); + let owns = node.getAttribute("aria-owns"); + if (owns?.includes(id)) { + owns = owns.split(" ").filter(x => x !== id).join(" "); + if (owns) { + node.setAttribute("aria-owns", owns); + } else { + node.removeAttribute("aria-owns"); + node.setAttribute("role", "presentation"); + } + } + } + #addIdToAriaOwns(id, node) { + const owns = node.getAttribute("aria-owns"); + if (!owns?.includes(id)) { + node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id); + } + node.removeAttribute("role"); + } + addPointerInTextLayer(element, isRemovable) { + const { + id + } = element; + if (!id) { + return null; + } + if (!this.#enabled) { + this.#waitingElements.set(element, isRemovable); + return null; + } + if (isRemovable) { + this.removePointerInTextLayer(element); + } + const children = this.#textChildren; + if (!children || children.length === 0) { + return null; + } + const index = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(children, node => TextAccessibilityManager.#compareElementPositions(element, node) < 0); + const nodeIndex = Math.max(0, index - 1); + const child = children[nodeIndex]; + this.#addIdToAriaOwns(id, child); + this.#textNodes.set(id, nodeIndex); + const parent = child.parentNode; + return parent?.classList.contains("markedContent") ? parent.id : null; + } + moveElementInDOM(container, element, contentElement, isRemovable) { + const id = this.addPointerInTextLayer(contentElement, isRemovable); + if (!container.hasChildNodes()) { + container.append(element); + return id; + } + const children = Array.from(container.childNodes).filter(node => node !== element); + if (children.length === 0) { + return id; + } + const elementToCompare = contentElement || element; + const index = (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_0__.binarySearchFirstItem)(children, node => TextAccessibilityManager.#compareElementPositions(elementToCompare, node) < 0); + if (index === 0) { + children[0].before(element); + } else { + children[index - 1].after(element); + } + return id; + } +} + + +/***/ }), + +/***/ 4274: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ TextHighlighter: () => (/* binding */ TextHighlighter) +/* harmony export */ }); +class TextHighlighter { + constructor({ + findController, + eventBus, + pageIndex + }) { + this.findController = findController; + this.matches = []; + this.eventBus = eventBus; + this.pageIdx = pageIndex; + this._onUpdateTextLayerMatches = null; + this.textDivs = null; + this.textContentItemsStr = null; + this.enabled = false; + } + setTextMapping(divs, texts) { + this.textDivs = divs; + this.textContentItemsStr = texts; + } + enable() { + if (!this.textDivs || !this.textContentItemsStr) { + throw new Error("Text divs and strings have not been set."); + } + if (this.enabled) { + throw new Error("TextHighlighter is already enabled."); + } + this.enabled = true; + if (!this._onUpdateTextLayerMatches) { + this._onUpdateTextLayerMatches = evt => { + if (evt.pageIndex === this.pageIdx || evt.pageIndex === -1) { + this._updateMatches(); + } + }; + this.eventBus._on("updatetextlayermatches", this._onUpdateTextLayerMatches); + } + this._updateMatches(); + } + disable() { + if (!this.enabled) { + return; + } + this.enabled = false; + if (this._onUpdateTextLayerMatches) { + this.eventBus._off("updatetextlayermatches", this._onUpdateTextLayerMatches); + this._onUpdateTextLayerMatches = null; + } + this._updateMatches(true); + } + _convertMatches(matches, matchesLength) { + if (!matches) { + return []; + } + const { + textContentItemsStr + } = this; + let i = 0, + iIndex = 0; + const end = textContentItemsStr.length - 1; + const result = []; + for (let m = 0, mm = matches.length; m < mm; m++) { + let matchIdx = matches[m]; + while (i !== end && matchIdx >= iIndex + textContentItemsStr[i].length) { + iIndex += textContentItemsStr[i].length; + i++; + } + if (i === textContentItemsStr.length) { + console.error("Could not find a matching mapping"); + } + const match = { + begin: { + divIdx: i, + offset: matchIdx - iIndex + } + }; + matchIdx += matchesLength[m]; + while (i !== end && matchIdx > iIndex + textContentItemsStr[i].length) { + iIndex += textContentItemsStr[i].length; + i++; + } + match.end = { + divIdx: i, + offset: matchIdx - iIndex + }; + result.push(match); + } + return result; + } + _renderMatches(matches) { + if (matches.length === 0) { + return; + } + const { + findController, + pageIdx + } = this; + const { + textContentItemsStr, + textDivs + } = this; + const isSelectedPage = pageIdx === findController.selected.pageIdx; + const selectedMatchIdx = findController.selected.matchIdx; + const highlightAll = findController.state.highlightAll; + let prevEnd = null; + const infinity = { + divIdx: -1, + offset: undefined + }; + function beginText(begin, className) { + const divIdx = begin.divIdx; + textDivs[divIdx].textContent = ""; + return appendTextToDiv(divIdx, 0, begin.offset, className); + } + function appendTextToDiv(divIdx, fromOffset, toOffset, className) { + let div = textDivs[divIdx]; + if (div.nodeType === Node.TEXT_NODE) { + const span = document.createElement("span"); + div.before(span); + span.append(div); + textDivs[divIdx] = span; + div = span; + } + const content = textContentItemsStr[divIdx].substring(fromOffset, toOffset); + const node = document.createTextNode(content); + if (className) { + const span = document.createElement("span"); + span.className = `${className} appended`; + span.append(node); + div.append(span); + return className.includes("selected") ? span.offsetLeft : 0; + } + div.append(node); + return 0; + } + let i0 = selectedMatchIdx, + i1 = i0 + 1; + if (highlightAll) { + i0 = 0; + i1 = matches.length; + } else if (!isSelectedPage) { + return; + } + let lastDivIdx = -1; + let lastOffset = -1; + for (let i = i0; i < i1; i++) { + const match = matches[i]; + const begin = match.begin; + if (begin.divIdx === lastDivIdx && begin.offset === lastOffset) { + continue; + } + lastDivIdx = begin.divIdx; + lastOffset = begin.offset; + const end = match.end; + const isSelected = isSelectedPage && i === selectedMatchIdx; + const highlightSuffix = isSelected ? " selected" : ""; + let selectedLeft = 0; + if (!prevEnd || begin.divIdx !== prevEnd.divIdx) { + if (prevEnd !== null) { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); + } + beginText(begin); + } else { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset); + } + if (begin.divIdx === end.divIdx) { + selectedLeft = appendTextToDiv(begin.divIdx, begin.offset, end.offset, "highlight" + highlightSuffix); + } else { + selectedLeft = appendTextToDiv(begin.divIdx, begin.offset, infinity.offset, "highlight begin" + highlightSuffix); + for (let n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) { + textDivs[n0].className = "highlight middle" + highlightSuffix; + } + beginText(end, "highlight end" + highlightSuffix); + } + prevEnd = end; + if (isSelected) { + findController.scrollMatchIntoView({ + element: textDivs[begin.divIdx], + selectedLeft, + pageIndex: pageIdx, + matchIndex: selectedMatchIdx + }); + } + } + if (prevEnd) { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); + } + } + _updateMatches(reset = false) { + if (!this.enabled && !reset) { + return; + } + const { + findController, + matches, + pageIdx + } = this; + const { + textContentItemsStr, + textDivs + } = this; + let clearedUntilDivIdx = -1; + for (const match of matches) { + const begin = Math.max(clearedUntilDivIdx, match.begin.divIdx); + for (let n = begin, end = match.end.divIdx; n <= end; n++) { + const div = textDivs[n]; + div.textContent = textContentItemsStr[n]; + div.className = ""; + } + clearedUntilDivIdx = match.end.divIdx + 1; + } + if (!findController?.highlightMatches || reset) { + return; + } + const pageMatches = findController.pageMatches[pageIdx] || null; + const pageMatchesLength = findController.pageMatchesLength[pageIdx] || null; + this.matches = this._convertMatches(pageMatches, pageMatchesLength); + this._renderMatches(this.matches); + } +} + + +/***/ }), + +/***/ 1013: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ TextLayerBuilder: () => (/* binding */ TextLayerBuilder) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +class TextLayerBuilder { + #enablePermissions = false; + #rotation = 0; + #scale = 0; + #textContentSource = null; + constructor({ + highlighter = null, + accessibilityManager = null, + isOffscreenCanvasSupported = true, + enablePermissions = false + }) { + this.textContentItemsStr = []; + this.renderingDone = false; + this.textDivs = []; + this.textDivProperties = new WeakMap(); + this.textLayerRenderTask = null; + this.highlighter = highlighter; + this.accessibilityManager = accessibilityManager; + this.isOffscreenCanvasSupported = isOffscreenCanvasSupported; + this.#enablePermissions = enablePermissions === true; + this.onAppend = null; + this.div = document.createElement("div"); + this.div.className = "textLayer"; + } + #finishRendering() { + this.renderingDone = true; + const endOfContent = document.createElement("div"); + endOfContent.className = "endOfContent"; + this.div.append(endOfContent); + this.#bindMouse(); + } + get numTextDivs() { + return this.textDivs.length; + } + async render(viewport) { + if (!this.#textContentSource) { + throw new Error('No "textContentSource" parameter specified.'); + } + const scale = viewport.scale * (globalThis.devicePixelRatio || 1); + const { + rotation + } = viewport; + if (this.renderingDone) { + const mustRotate = rotation !== this.#rotation; + const mustRescale = scale !== this.#scale; + if (mustRotate || mustRescale) { + this.hide(); + (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.updateTextLayer)({ + container: this.div, + viewport, + textDivs: this.textDivs, + textDivProperties: this.textDivProperties, + isOffscreenCanvasSupported: this.isOffscreenCanvasSupported, + mustRescale, + mustRotate + }); + this.#scale = scale; + this.#rotation = rotation; + } + this.show(); + return; + } + this.cancel(); + this.highlighter?.setTextMapping(this.textDivs, this.textContentItemsStr); + this.accessibilityManager?.setTextMapping(this.textDivs); + this.textLayerRenderTask = (0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.renderTextLayer)({ + textContentSource: this.#textContentSource, + container: this.div, + viewport, + textDivs: this.textDivs, + textDivProperties: this.textDivProperties, + textContentItemsStr: this.textContentItemsStr, + isOffscreenCanvasSupported: this.isOffscreenCanvasSupported + }); + await this.textLayerRenderTask.promise; + this.#finishRendering(); + this.#scale = scale; + this.#rotation = rotation; + this.onAppend(this.div); + this.highlighter?.enable(); + this.accessibilityManager?.enable(); + } + hide() { + if (!this.div.hidden && this.renderingDone) { + this.highlighter?.disable(); + this.div.hidden = true; + } + } + show() { + if (this.div.hidden && this.renderingDone) { + this.div.hidden = false; + this.highlighter?.enable(); + } + } + cancel() { + if (this.textLayerRenderTask) { + this.textLayerRenderTask.cancel(); + this.textLayerRenderTask = null; + } + this.highlighter?.disable(); + this.accessibilityManager?.disable(); + this.textContentItemsStr.length = 0; + this.textDivs.length = 0; + this.textDivProperties = new WeakMap(); + } + setTextContentSource(source) { + this.cancel(); + this.#textContentSource = source; + } + #bindMouse() { + const { + div + } = this; + div.addEventListener("mousedown", evt => { + const end = div.querySelector(".endOfContent"); + if (!end) { + return; + } + let adjustTop = evt.target !== div; + adjustTop &&= getComputedStyle(end).getPropertyValue("-moz-user-select") !== "none"; + if (adjustTop) { + const divBounds = div.getBoundingClientRect(); + const r = Math.max(0, (evt.pageY - divBounds.top) / divBounds.height); + end.style.top = (r * 100).toFixed(2) + "%"; + } + end.classList.add("active"); + }); + div.addEventListener("mouseup", () => { + const end = div.querySelector(".endOfContent"); + if (!end) { + return; + } + end.style.top = ""; + end.classList.remove("active"); + }); + div.addEventListener("copy", event => { + if (!this.#enablePermissions) { + const selection = document.getSelection(); + event.clipboardData.setData("text/plain", (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.removeNullCharacters)((0,pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.normalizeUnicode)(selection.toString()))); + } + event.preventDefault(); + event.stopPropagation(); + }); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 276: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Toolbar: () => (/* binding */ Toolbar) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4927); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + + +class Toolbar { + #opts; + constructor(options, eventBus) { + this.#opts = options; + this.eventBus = eventBus; + const buttons = [{ + element: options.previous, + eventName: "previouspage" + }, { + element: options.next, + eventName: "nextpage" + }, { + element: options.zoomIn, + eventName: "zoomin" + }, { + element: options.zoomOut, + eventName: "zoomout" + }, { + element: options.print, + eventName: "print" + }, { + element: options.download, + eventName: "download" + }, { + element: options.editorFreeTextButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorFreeTextButton; + return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.FREETEXT; + } + } + }, { + element: options.editorHighlightButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorHighlightButton; + return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT; + } + } + }, { + element: options.editorInkButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorInkButton; + return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.INK; + } + } + }, { + element: options.editorStampButton, + eventName: "switchannotationeditormode", + eventDetails: { + get mode() { + const { + classList + } = options.editorStampButton; + return classList.contains("toggled") ? pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.NONE : pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.STAMP; + } + } + }]; + this.#bindListeners(buttons); + if (options.editorHighlightColorPicker) { + eventBus._on("annotationeditoruimanager", ({ + uiManager + }) => { + this.#setAnnotationEditorUIManager(uiManager, options.editorHighlightColorPicker); + }, { + once: true + }); + } + this.reset(); + } + #setAnnotationEditorUIManager(uiManager, parentContainer) { + const colorPicker = new pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.ColorPicker({ + uiManager + }); + uiManager.setMainHighlightColorPicker(colorPicker); + parentContainer.append(colorPicker.renderMainDropdown()); + } + setPageNumber(pageNumber, pageLabel) { + this.pageNumber = pageNumber; + this.pageLabel = pageLabel; + this.#updateUIState(false); + } + setPagesCount(pagesCount, hasPageLabels) { + this.pagesCount = pagesCount; + this.hasPageLabels = hasPageLabels; + this.#updateUIState(true); + } + setPageScale(pageScaleValue, pageScale) { + this.pageScaleValue = (pageScaleValue || pageScale).toString(); + this.pageScale = pageScale; + this.#updateUIState(false); + } + reset() { + this.pageNumber = 0; + this.pageLabel = null; + this.hasPageLabels = false; + this.pagesCount = 0; + this.pageScaleValue = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE_VALUE; + this.pageScale = _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.DEFAULT_SCALE; + this.#updateUIState(true); + this.updateLoadingIndicatorState(); + this.#editorModeChanged({ + mode: pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE + }); + } + #bindListeners(buttons) { + const { + eventBus + } = this; + const { + pageNumber, + scaleSelect + } = this.#opts; + const self = this; + for (const { + element, + eventName, + eventDetails + } of buttons) { + element.addEventListener("click", evt => { + if (eventName !== null) { + eventBus.dispatch(eventName, { + source: this, + ...eventDetails, + isFromKeyboard: evt.detail === 0 + }); + } + }); + } + pageNumber.addEventListener("click", function () { + this.select(); + }); + pageNumber.addEventListener("change", function () { + eventBus.dispatch("pagenumberchanged", { + source: self, + value: this.value + }); + }); + scaleSelect.addEventListener("change", function () { + if (this.value === "custom") { + return; + } + eventBus.dispatch("scalechanged", { + source: self, + value: this.value + }); + }); + scaleSelect.addEventListener("click", function ({ + target + }) { + if (this.value === self.pageScaleValue && target.tagName.toUpperCase() === "OPTION") { + this.blur(); + } + }); + scaleSelect.oncontextmenu = pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.noContextMenu; + eventBus._on("annotationeditormodechanged", this.#editorModeChanged.bind(this)); + } + #editorModeChanged({ + mode + }) { + const { + editorFreeTextButton, + editorFreeTextParamsToolbar, + editorHighlightButton, + editorHighlightParamsToolbar, + editorInkButton, + editorInkParamsToolbar, + editorStampButton, + editorStampParamsToolbar + } = this.#opts; + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorFreeTextButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.FREETEXT, editorFreeTextParamsToolbar); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorHighlightButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.HIGHLIGHT, editorHighlightParamsToolbar); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorInkButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.INK, editorInkParamsToolbar); + (0,_ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.toggleCheckedBtn)(editorStampButton, mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.STAMP, editorStampParamsToolbar); + const isDisable = mode === pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.AnnotationEditorType.DISABLE; + editorFreeTextButton.disabled = isDisable; + editorHighlightButton.disabled = isDisable; + editorInkButton.disabled = isDisable; + editorStampButton.disabled = isDisable; + } + #updateUIState(resetNumPages = false) { + const { + pageNumber, + pagesCount, + pageScaleValue, + pageScale + } = this; + const opts = this.#opts; + if (resetNumPages) { + if (this.hasPageLabels) { + opts.pageNumber.type = "text"; + opts.numPages.setAttribute("data-l10n-id", "pdfjs-page-of-pages"); + } else { + opts.pageNumber.type = "number"; + opts.numPages.setAttribute("data-l10n-id", "pdfjs-of-pages"); + opts.numPages.setAttribute("data-l10n-args", JSON.stringify({ + pagesCount + })); + } + opts.pageNumber.max = pagesCount; + } + if (this.hasPageLabels) { + opts.pageNumber.value = this.pageLabel; + opts.numPages.setAttribute("data-l10n-args", JSON.stringify({ + pageNumber, + pagesCount + })); + } else { + opts.pageNumber.value = pageNumber; + } + opts.previous.disabled = pageNumber <= 1; + opts.next.disabled = pageNumber >= pagesCount; + opts.zoomOut.disabled = pageScale <= _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MIN_SCALE; + opts.zoomIn.disabled = pageScale >= _ui_utils_js__WEBPACK_IMPORTED_MODULE_1__.MAX_SCALE; + let predefinedValueFound = false; + for (const option of opts.scaleSelect.options) { + if (option.value !== pageScaleValue) { + option.selected = false; + continue; + } + option.selected = true; + predefinedValueFound = true; + } + if (!predefinedValueFound) { + opts.customScaleOption.selected = true; + opts.customScaleOption.setAttribute("data-l10n-args", JSON.stringify({ + scale: Math.round(pageScale * 10000) / 100 + })); + } + } + updateLoadingIndicatorState(loading = false) { + const { + pageNumber + } = this.#opts; + pageNumber.classList.toggle("loading", loading); + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 4927: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ AutoPrintRegExp: () => (/* binding */ AutoPrintRegExp), +/* harmony export */ CursorTool: () => (/* binding */ CursorTool), +/* harmony export */ DEFAULT_SCALE: () => (/* binding */ DEFAULT_SCALE), +/* harmony export */ DEFAULT_SCALE_DELTA: () => (/* binding */ DEFAULT_SCALE_DELTA), +/* harmony export */ DEFAULT_SCALE_VALUE: () => (/* binding */ DEFAULT_SCALE_VALUE), +/* harmony export */ MAX_AUTO_SCALE: () => (/* binding */ MAX_AUTO_SCALE), +/* harmony export */ MAX_SCALE: () => (/* binding */ MAX_SCALE), +/* harmony export */ MIN_SCALE: () => (/* binding */ MIN_SCALE), +/* harmony export */ OutputScale: () => (/* binding */ OutputScale), +/* harmony export */ PresentationModeState: () => (/* binding */ PresentationModeState), +/* harmony export */ ProgressBar: () => (/* binding */ ProgressBar), +/* harmony export */ RenderingStates: () => (/* binding */ RenderingStates), +/* harmony export */ SCROLLBAR_PADDING: () => (/* binding */ SCROLLBAR_PADDING), +/* harmony export */ ScrollMode: () => (/* binding */ ScrollMode), +/* harmony export */ SidebarView: () => (/* binding */ SidebarView), +/* harmony export */ SpreadMode: () => (/* binding */ SpreadMode), +/* harmony export */ TextLayerMode: () => (/* binding */ TextLayerMode), +/* harmony export */ UNKNOWN_SCALE: () => (/* binding */ UNKNOWN_SCALE), +/* harmony export */ VERTICAL_PADDING: () => (/* binding */ VERTICAL_PADDING), +/* harmony export */ animationStarted: () => (/* binding */ animationStarted), +/* harmony export */ apiPageLayoutToViewerModes: () => (/* binding */ apiPageLayoutToViewerModes), +/* harmony export */ apiPageModeToSidebarView: () => (/* binding */ apiPageModeToSidebarView), +/* harmony export */ approximateFraction: () => (/* binding */ approximateFraction), +/* harmony export */ binarySearchFirstItem: () => (/* binding */ binarySearchFirstItem), +/* harmony export */ docStyle: () => (/* binding */ docStyle), +/* harmony export */ getActiveOrFocusedElement: () => (/* binding */ getActiveOrFocusedElement), +/* harmony export */ getPageSizeInches: () => (/* binding */ getPageSizeInches), +/* harmony export */ getVisibleElements: () => (/* binding */ getVisibleElements), +/* harmony export */ isPortraitOrientation: () => (/* binding */ isPortraitOrientation), +/* harmony export */ isValidRotation: () => (/* binding */ isValidRotation), +/* harmony export */ isValidScrollMode: () => (/* binding */ isValidScrollMode), +/* harmony export */ isValidSpreadMode: () => (/* binding */ isValidSpreadMode), +/* harmony export */ normalizeWheelEventDelta: () => (/* binding */ normalizeWheelEventDelta), +/* harmony export */ normalizeWheelEventDirection: () => (/* binding */ normalizeWheelEventDirection), +/* harmony export */ parseQueryString: () => (/* binding */ parseQueryString), +/* harmony export */ removeNullCharacters: () => (/* binding */ removeNullCharacters), +/* harmony export */ roundToDivide: () => (/* binding */ roundToDivide), +/* harmony export */ scrollIntoView: () => (/* binding */ scrollIntoView), +/* harmony export */ toggleCheckedBtn: () => (/* binding */ toggleCheckedBtn), +/* harmony export */ toggleExpandedBtn: () => (/* binding */ toggleExpandedBtn), +/* harmony export */ watchScroll: () => (/* binding */ watchScroll) +/* harmony export */ }); +/* unused harmony export backtrackBeforeAllVisibleElements */ +const DEFAULT_SCALE_VALUE = "auto"; +const DEFAULT_SCALE = 1.0; +const DEFAULT_SCALE_DELTA = 1.1; +const MIN_SCALE = 0.1; +const MAX_SCALE = 10.0; +const UNKNOWN_SCALE = 0; +const MAX_AUTO_SCALE = 1.25; +const SCROLLBAR_PADDING = 40; +const VERTICAL_PADDING = 5; +const RenderingStates = { + INITIAL: 0, + RUNNING: 1, + PAUSED: 2, + FINISHED: 3 +}; +const PresentationModeState = { + UNKNOWN: 0, + NORMAL: 1, + CHANGING: 2, + FULLSCREEN: 3 +}; +const SidebarView = { + UNKNOWN: -1, + NONE: 0, + THUMBS: 1, + OUTLINE: 2, + ATTACHMENTS: 3, + LAYERS: 4 +}; +const TextLayerMode = { + DISABLE: 0, + ENABLE: 1, + ENABLE_PERMISSIONS: 2 +}; +const ScrollMode = { + UNKNOWN: -1, + VERTICAL: 0, + HORIZONTAL: 1, + WRAPPED: 2, + PAGE: 3 +}; +const SpreadMode = { + UNKNOWN: -1, + NONE: 0, + ODD: 1, + EVEN: 2 +}; +const CursorTool = { + SELECT: 0, + HAND: 1, + ZOOM: 2 +}; +const AutoPrintRegExp = /\bprint\s*\(/; +class OutputScale { + constructor() { + const pixelRatio = window.devicePixelRatio || 1; + this.sx = pixelRatio; + this.sy = pixelRatio; + } + get scaled() { + return this.sx !== 1 || this.sy !== 1; + } +} +function scrollIntoView(element, spot, scrollMatches = false) { + let parent = element.offsetParent; + if (!parent) { + console.error("offsetParent is not set -- cannot scroll"); + return; + } + let offsetY = element.offsetTop + element.clientTop; + let offsetX = element.offsetLeft + element.clientLeft; + while (parent.clientHeight === parent.scrollHeight && parent.clientWidth === parent.scrollWidth || scrollMatches && (parent.classList.contains("markedContent") || getComputedStyle(parent).overflow === "hidden")) { + offsetY += parent.offsetTop; + offsetX += parent.offsetLeft; + parent = parent.offsetParent; + if (!parent) { + return; + } + } + if (spot) { + if (spot.top !== undefined) { + offsetY += spot.top; + } + if (spot.left !== undefined) { + offsetX += spot.left; + parent.scrollLeft = offsetX; + } + } + parent.scrollTop = offsetY; +} +function watchScroll(viewAreaElement, callback) { + const debounceScroll = function (evt) { + if (rAF) { + return; + } + rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { + rAF = null; + const currentX = viewAreaElement.scrollLeft; + const lastX = state.lastX; + if (currentX !== lastX) { + state.right = currentX > lastX; + } + state.lastX = currentX; + const currentY = viewAreaElement.scrollTop; + const lastY = state.lastY; + if (currentY !== lastY) { + state.down = currentY > lastY; + } + state.lastY = currentY; + callback(state); + }); + }; + const state = { + right: true, + down: true, + lastX: viewAreaElement.scrollLeft, + lastY: viewAreaElement.scrollTop, + _eventHandler: debounceScroll + }; + let rAF = null; + viewAreaElement.addEventListener("scroll", debounceScroll, true); + return state; +} +function parseQueryString(query) { + const params = new Map(); + for (const [key, value] of new URLSearchParams(query)) { + params.set(key.toLowerCase(), value); + } + return params; +} +const InvisibleCharactersRegExp = /[\x00-\x1F]/g; +function removeNullCharacters(str, replaceInvisible = false) { + if (!InvisibleCharactersRegExp.test(str)) { + return str; + } + if (replaceInvisible) { + return str.replaceAll(InvisibleCharactersRegExp, m => { + return m === "\x00" ? "" : " "; + }); + } + return str.replaceAll("\x00", ""); +} +function binarySearchFirstItem(items, condition, start = 0) { + let minIndex = start; + let maxIndex = items.length - 1; + if (maxIndex < 0 || !condition(items[maxIndex])) { + return items.length; + } + if (condition(items[minIndex])) { + return minIndex; + } + while (minIndex < maxIndex) { + const currentIndex = minIndex + maxIndex >> 1; + const currentItem = items[currentIndex]; + if (condition(currentItem)) { + maxIndex = currentIndex; + } else { + minIndex = currentIndex + 1; + } + } + return minIndex; +} +function approximateFraction(x) { + if (Math.floor(x) === x) { + return [x, 1]; + } + const xinv = 1 / x; + const limit = 8; + if (xinv > limit) { + return [1, limit]; + } else if (Math.floor(xinv) === xinv) { + return [1, xinv]; + } + const x_ = x > 1 ? xinv : x; + let a = 0, + b = 1, + c = 1, + d = 1; + while (true) { + const p = a + c, + q = b + d; + if (q > limit) { + break; + } + if (x_ <= p / q) { + c = p; + d = q; + } else { + a = p; + b = q; + } + } + let result; + if (x_ - a / b < c / d - x_) { + result = x_ === x ? [a, b] : [b, a]; + } else { + result = x_ === x ? [c, d] : [d, c]; + } + return result; +} +function roundToDivide(x, div) { + const r = x % div; + return r === 0 ? x : Math.round(x - r + div); +} +function getPageSizeInches({ + view, + userUnit, + rotate +}) { + const [x1, y1, x2, y2] = view; + const changeOrientation = rotate % 180 !== 0; + const width = (x2 - x1) / 72 * userUnit; + const height = (y2 - y1) / 72 * userUnit; + return { + width: changeOrientation ? height : width, + height: changeOrientation ? width : height + }; +} +function backtrackBeforeAllVisibleElements(index, views, top) { + if (index < 2) { + return index; + } + let elt = views[index].div; + let pageTop = elt.offsetTop + elt.clientTop; + if (pageTop >= top) { + elt = views[index - 1].div; + pageTop = elt.offsetTop + elt.clientTop; + } + for (let i = index - 2; i >= 0; --i) { + elt = views[i].div; + if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) { + break; + } + index = i; + } + return index; +} +function getVisibleElements({ + scrollEl, + views, + sortByVisibility = false, + horizontal = false, + rtl = false +}) { + const top = scrollEl.scrollTop, + bottom = top + scrollEl.clientHeight; + const left = scrollEl.scrollLeft, + right = left + scrollEl.clientWidth; + function isElementBottomAfterViewTop(view) { + const element = view.div; + const elementBottom = element.offsetTop + element.clientTop + element.clientHeight; + return elementBottom > top; + } + function isElementNextAfterViewHorizontally(view) { + const element = view.div; + const elementLeft = element.offsetLeft + element.clientLeft; + const elementRight = elementLeft + element.clientWidth; + return rtl ? elementLeft < right : elementRight > left; + } + const visible = [], + ids = new Set(), + numViews = views.length; + let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop); + if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) { + firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top); + } + let lastEdge = horizontal ? right : -1; + for (let i = firstVisibleElementInd; i < numViews; i++) { + const view = views[i], + element = view.div; + const currentWidth = element.offsetLeft + element.clientLeft; + const currentHeight = element.offsetTop + element.clientTop; + const viewWidth = element.clientWidth, + viewHeight = element.clientHeight; + const viewRight = currentWidth + viewWidth; + const viewBottom = currentHeight + viewHeight; + if (lastEdge === -1) { + if (viewBottom >= bottom) { + lastEdge = viewBottom; + } + } else if ((horizontal ? currentWidth : currentHeight) > lastEdge) { + break; + } + if (viewBottom <= top || currentHeight >= bottom || viewRight <= left || currentWidth >= right) { + continue; + } + const hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, viewBottom - bottom); + const hiddenWidth = Math.max(0, left - currentWidth) + Math.max(0, viewRight - right); + const fractionHeight = (viewHeight - hiddenHeight) / viewHeight, + fractionWidth = (viewWidth - hiddenWidth) / viewWidth; + const percent = fractionHeight * fractionWidth * 100 | 0; + visible.push({ + id: view.id, + x: currentWidth, + y: currentHeight, + view, + percent, + widthPercent: fractionWidth * 100 | 0 + }); + ids.add(view.id); + } + const first = visible[0], + last = visible.at(-1); + if (sortByVisibility) { + visible.sort(function (a, b) { + const pc = a.percent - b.percent; + if (Math.abs(pc) > 0.001) { + return -pc; + } + return a.id - b.id; + }); + } + return { + first, + last, + views: visible, + ids + }; +} +function normalizeWheelEventDirection(evt) { + let delta = Math.hypot(evt.deltaX, evt.deltaY); + const angle = Math.atan2(evt.deltaY, evt.deltaX); + if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) { + delta = -delta; + } + return delta; +} +function normalizeWheelEventDelta(evt) { + const deltaMode = evt.deltaMode; + let delta = normalizeWheelEventDirection(evt); + const MOUSE_PIXELS_PER_LINE = 30; + const MOUSE_LINES_PER_PAGE = 30; + if (deltaMode === WheelEvent.DOM_DELTA_PIXEL) { + delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE; + } else if (deltaMode === WheelEvent.DOM_DELTA_LINE) { + delta /= MOUSE_LINES_PER_PAGE; + } + return delta; +} +function isValidRotation(angle) { + return Number.isInteger(angle) && angle % 90 === 0; +} +function isValidScrollMode(mode) { + return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN; +} +function isValidSpreadMode(mode) { + return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN; +} +function isPortraitOrientation(size) { + return size.width <= size.height; +} +const animationStarted = new Promise(function (resolve) { + window.requestAnimationFrame(resolve); +}); +const docStyle = document.documentElement.style; +function clamp(v, min, max) { + return Math.min(Math.max(v, min), max); +} +class ProgressBar { + #classList = null; + #disableAutoFetchTimeout = null; + #percent = 0; + #style = null; + #visible = true; + constructor(bar) { + this.#classList = bar.classList; + this.#style = bar.style; + } + get percent() { + return this.#percent; + } + set percent(val) { + this.#percent = clamp(val, 0, 100); + if (isNaN(val)) { + this.#classList.add("indeterminate"); + return; + } + this.#classList.remove("indeterminate"); + this.#style.setProperty("--progressBar-percent", `${this.#percent}%`); + } + setWidth(viewer) { + if (!viewer) { + return; + } + const container = viewer.parentNode; + const scrollbarWidth = container.offsetWidth - viewer.offsetWidth; + if (scrollbarWidth > 0) { + this.#style.setProperty("--progressBar-end-offset", `${scrollbarWidth}px`); + } + } + setDisableAutoFetch(delay = 5000) { + if (isNaN(this.#percent)) { + return; + } + if (this.#disableAutoFetchTimeout) { + clearTimeout(this.#disableAutoFetchTimeout); + } + this.show(); + this.#disableAutoFetchTimeout = setTimeout(() => { + this.#disableAutoFetchTimeout = null; + this.hide(); + }, delay); + } + hide() { + if (!this.#visible) { + return; + } + this.#visible = false; + this.#classList.add("hidden"); + } + show() { + if (this.#visible) { + return; + } + this.#visible = true; + this.#classList.remove("hidden"); + } +} +function getActiveOrFocusedElement() { + let curRoot = document; + let curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus"); + while (curActiveOrFocused?.shadowRoot) { + curRoot = curActiveOrFocused.shadowRoot; + curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus"); + } + return curActiveOrFocused; +} +function apiPageLayoutToViewerModes(layout) { + let scrollMode = ScrollMode.VERTICAL, + spreadMode = SpreadMode.NONE; + switch (layout) { + case "SinglePage": + scrollMode = ScrollMode.PAGE; + break; + case "OneColumn": + break; + case "TwoPageLeft": + scrollMode = ScrollMode.PAGE; + case "TwoColumnLeft": + spreadMode = SpreadMode.ODD; + break; + case "TwoPageRight": + scrollMode = ScrollMode.PAGE; + case "TwoColumnRight": + spreadMode = SpreadMode.EVEN; + break; + } + return { + scrollMode, + spreadMode + }; +} +function apiPageModeToSidebarView(mode) { + switch (mode) { + case "UseNone": + return SidebarView.NONE; + case "UseThumbs": + return SidebarView.THUMBS; + case "UseOutlines": + return SidebarView.OUTLINE; + case "UseAttachments": + return SidebarView.ATTACHMENTS; + case "UseOC": + return SidebarView.LAYERS; + } + return SidebarView.NONE; +} +function toggleCheckedBtn(button, toggle, view = null) { + button.classList.toggle("toggled", toggle); + button.setAttribute("aria-checked", toggle); + view?.classList.toggle("hidden", !toggle); +} +function toggleExpandedBtn(button, toggle, view = null) { + button.classList.toggle("toggled", toggle); + button.setAttribute("aria-expanded", toggle); + view?.classList.toggle("hidden", !toggle); +} + + +/***/ }), + +/***/ 1096: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ ViewHistory: () => (/* binding */ ViewHistory) +/* harmony export */ }); +const DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20; +class ViewHistory { + constructor(fingerprint, cacheSize = DEFAULT_VIEW_HISTORY_CACHE_SIZE) { + this.fingerprint = fingerprint; + this.cacheSize = cacheSize; + this._initializedPromise = this._readFromStorage().then(databaseStr => { + const database = JSON.parse(databaseStr || "{}"); + let index = -1; + if (!Array.isArray(database.files)) { + database.files = []; + } else { + while (database.files.length >= this.cacheSize) { + database.files.shift(); + } + for (let i = 0, ii = database.files.length; i < ii; i++) { + const branch = database.files[i]; + if (branch.fingerprint === this.fingerprint) { + index = i; + break; + } + } + } + if (index === -1) { + index = database.files.push({ + fingerprint: this.fingerprint + }) - 1; + } + this.file = database.files[index]; + this.database = database; + }); + } + async _writeToStorage() { + const databaseStr = JSON.stringify(this.database); + localStorage.setItem("pdfjs.history", databaseStr); + } + async _readFromStorage() { + return localStorage.getItem("pdfjs.history"); + } + async set(name, val) { + await this._initializedPromise; + this.file[name] = val; + return this._writeToStorage(); + } + async setMultiple(properties) { + await this._initializedPromise; + for (const name in properties) { + this.file[name] = properties[name]; + } + return this._writeToStorage(); + } + async get(name, defaultValue) { + await this._initializedPromise; + const val = this.file[name]; + return val !== undefined ? val : defaultValue; + } + async getMultiple(properties) { + await this._initializedPromise; + const values = Object.create(null); + for (const name in properties) { + const val = this.file[name]; + values[name] = val !== undefined ? val : properties[name]; + } + return values; + } +} + + +/***/ }), + +/***/ 6400: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ PDFViewerApplication: () => (/* reexport safe */ _app_js__WEBPACK_IMPORTED_MODULE_5__.PDFViewerApplication), +/* harmony export */ PDFViewerApplicationConstants: () => (/* binding */ AppConstants), +/* harmony export */ PDFViewerApplicationOptions: () => (/* reexport safe */ _app_options_js__WEBPACK_IMPORTED_MODULE_3__.AppOptions) +/* harmony export */ }); +/* harmony import */ var web_com__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1546); +/* harmony import */ var web_print_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1834); +/* harmony import */ var _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4927); +/* harmony import */ var _app_options_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8961); +/* harmony import */ var _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3234); +/* harmony import */ var _app_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(39); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([web_com__WEBPACK_IMPORTED_MODULE_0__, web_print_service__WEBPACK_IMPORTED_MODULE_1__, _app_js__WEBPACK_IMPORTED_MODULE_5__]); +([web_com__WEBPACK_IMPORTED_MODULE_0__, web_print_service__WEBPACK_IMPORTED_MODULE_1__, _app_js__WEBPACK_IMPORTED_MODULE_5__] = __webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__); + + + + + + +const pdfjsVersion = '4.0.379'; +const pdfjsBuild = '9e14d04fd'; +const AppConstants = { + LinkTarget: _pdf_link_service_js__WEBPACK_IMPORTED_MODULE_4__.LinkTarget, + RenderingStates: _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.RenderingStates, + ScrollMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.ScrollMode, + SpreadMode: _ui_utils_js__WEBPACK_IMPORTED_MODULE_2__.SpreadMode +}; +window.PDFViewerApplication = _app_js__WEBPACK_IMPORTED_MODULE_5__.PDFViewerApplication; +window.PDFViewerApplicationConstants = AppConstants; +window.PDFViewerApplicationOptions = _app_options_js__WEBPACK_IMPORTED_MODULE_3__.AppOptions; +function getViewerConfiguration() { + return { + appContainer: document.body, + mainContainer: document.getElementById("viewerContainer"), + viewerContainer: document.getElementById("viewer"), + toolbar: { + container: document.getElementById("toolbarViewer"), + numPages: document.getElementById("numPages"), + pageNumber: document.getElementById("pageNumber"), + scaleSelect: document.getElementById("scaleSelect"), + customScaleOption: document.getElementById("customScaleOption"), + previous: document.getElementById("previous"), + next: document.getElementById("next"), + zoomIn: document.getElementById("zoomIn"), + zoomOut: document.getElementById("zoomOut"), + viewFind: document.getElementById("viewFind"), + print: document.getElementById("print"), + editorFreeTextButton: document.getElementById("editorFreeText"), + editorFreeTextParamsToolbar: document.getElementById("editorFreeTextParamsToolbar"), + editorHighlightButton: document.getElementById("editorHighlight"), + editorHighlightParamsToolbar: document.getElementById("editorHighlightParamsToolbar"), + editorHighlightColorPicker: document.getElementById("editorHighlightColorPicker"), + editorInkButton: document.getElementById("editorInk"), + editorInkParamsToolbar: document.getElementById("editorInkParamsToolbar"), + editorStampButton: document.getElementById("editorStamp"), + editorStampParamsToolbar: document.getElementById("editorStampParamsToolbar"), + download: document.getElementById("download") + }, + secondaryToolbar: { + toolbar: document.getElementById("secondaryToolbar"), + toggleButton: document.getElementById("secondaryToolbarToggle"), + presentationModeButton: document.getElementById("presentationMode"), + openFileButton: document.getElementById("secondaryOpenFile"), + printButton: document.getElementById("secondaryPrint"), + downloadButton: document.getElementById("secondaryDownload"), + viewBookmarkButton: document.getElementById("viewBookmark"), + firstPageButton: document.getElementById("firstPage"), + lastPageButton: document.getElementById("lastPage"), + pageRotateCwButton: document.getElementById("pageRotateCw"), + pageRotateCcwButton: document.getElementById("pageRotateCcw"), + cursorSelectToolButton: document.getElementById("cursorSelectTool"), + cursorHandToolButton: document.getElementById("cursorHandTool"), + scrollPageButton: document.getElementById("scrollPage"), + scrollVerticalButton: document.getElementById("scrollVertical"), + scrollHorizontalButton: document.getElementById("scrollHorizontal"), + scrollWrappedButton: document.getElementById("scrollWrapped"), + spreadNoneButton: document.getElementById("spreadNone"), + spreadOddButton: document.getElementById("spreadOdd"), + spreadEvenButton: document.getElementById("spreadEven"), + documentPropertiesButton: document.getElementById("documentProperties") + }, + sidebar: { + outerContainer: document.getElementById("outerContainer"), + sidebarContainer: document.getElementById("sidebarContainer"), + toggleButton: document.getElementById("sidebarToggle"), + resizer: document.getElementById("sidebarResizer"), + thumbnailButton: document.getElementById("viewThumbnail"), + outlineButton: document.getElementById("viewOutline"), + attachmentsButton: document.getElementById("viewAttachments"), + layersButton: document.getElementById("viewLayers"), + thumbnailView: document.getElementById("thumbnailView"), + outlineView: document.getElementById("outlineView"), + attachmentsView: document.getElementById("attachmentsView"), + layersView: document.getElementById("layersView"), + currentOutlineItemButton: document.getElementById("currentOutlineItem") + }, + findBar: { + bar: document.getElementById("findbar"), + toggleButton: document.getElementById("viewFind"), + findField: document.getElementById("findInput"), + highlightAllCheckbox: document.getElementById("findHighlightAll"), + caseSensitiveCheckbox: document.getElementById("findMatchCase"), + matchDiacriticsCheckbox: document.getElementById("findMatchDiacritics"), + entireWordCheckbox: document.getElementById("findEntireWord"), + findMsg: document.getElementById("findMsg"), + findResultsCount: document.getElementById("findResultsCount"), + findPreviousButton: document.getElementById("findPrevious"), + findNextButton: document.getElementById("findNext") + }, + passwordOverlay: { + dialog: document.getElementById("passwordDialog"), + label: document.getElementById("passwordText"), + input: document.getElementById("password"), + submitButton: document.getElementById("passwordSubmit"), + cancelButton: document.getElementById("passwordCancel") + }, + documentProperties: { + dialog: document.getElementById("documentPropertiesDialog"), + closeButton: document.getElementById("documentPropertiesClose"), + fields: { + fileName: document.getElementById("fileNameField"), + fileSize: document.getElementById("fileSizeField"), + title: document.getElementById("titleField"), + author: document.getElementById("authorField"), + subject: document.getElementById("subjectField"), + keywords: document.getElementById("keywordsField"), + creationDate: document.getElementById("creationDateField"), + modificationDate: document.getElementById("modificationDateField"), + creator: document.getElementById("creatorField"), + producer: document.getElementById("producerField"), + version: document.getElementById("versionField"), + pageCount: document.getElementById("pageCountField"), + pageSize: document.getElementById("pageSizeField"), + linearized: document.getElementById("linearizedField") + } + }, + altTextDialog: { + dialog: document.getElementById("altTextDialog"), + optionDescription: document.getElementById("descriptionButton"), + optionDecorative: document.getElementById("decorativeButton"), + textarea: document.getElementById("descriptionTextarea"), + cancelButton: document.getElementById("altTextCancel"), + saveButton: document.getElementById("altTextSave") + }, + annotationEditorParams: { + editorFreeTextFontSize: document.getElementById("editorFreeTextFontSize"), + editorFreeTextColor: document.getElementById("editorFreeTextColor"), + editorInkColor: document.getElementById("editorInkColor"), + editorInkThickness: document.getElementById("editorInkThickness"), + editorInkOpacity: document.getElementById("editorInkOpacity"), + editorStampAddImage: document.getElementById("editorStampAddImage") + }, + printContainer: document.getElementById("printContainer"), + openFileInput: document.getElementById("fileInput"), + debuggerScriptPath: "./debugger.mjs" + }; +} +function webViewerLoad() { + const config = getViewerConfiguration(); + const event = new CustomEvent("webviewerloaded", { + bubbles: true, + cancelable: true, + detail: { + source: window + } + }); + try { + parent.document.dispatchEvent(event); + } catch (ex) { + console.error(`webviewerloaded: ${ex}`); + document.dispatchEvent(event); + } + _app_js__WEBPACK_IMPORTED_MODULE_5__.PDFViewerApplication.run(config); +} +document.blockUnblockOnload?.(true); +if (document.readyState === "interactive" || document.readyState === "complete") { + webViewerLoad(); +} else { + document.addEventListener("DOMContentLoaded", webViewerLoad, true); +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }), + +/***/ 8012: +/***/ ((__webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try { +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ XfaLayerBuilder: () => (/* binding */ XfaLayerBuilder) +/* harmony export */ }); +/* harmony import */ var pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1869); +var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__]); +pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0]; + +class XfaLayerBuilder { + constructor({ + pdfPage, + annotationStorage = null, + linkService, + xfaHtml = null + }) { + this.pdfPage = pdfPage; + this.annotationStorage = annotationStorage; + this.linkService = linkService; + this.xfaHtml = xfaHtml; + this.div = null; + this._cancelled = false; + } + async render(viewport, intent = "display") { + if (intent === "print") { + const parameters = { + viewport: viewport.clone({ + dontFlip: true + }), + div: this.div, + xfaHtml: this.xfaHtml, + annotationStorage: this.annotationStorage, + linkService: this.linkService, + intent + }; + this.div = document.createElement("div"); + parameters.div = this.div; + return pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.XfaLayer.render(parameters); + } + const xfaHtml = await this.pdfPage.getXfa(); + if (this._cancelled || !xfaHtml) { + return { + textDivs: [] + }; + } + const parameters = { + viewport: viewport.clone({ + dontFlip: true + }), + div: this.div, + xfaHtml, + annotationStorage: this.annotationStorage, + linkService: this.linkService, + intent + }; + if (this.div) { + return pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.XfaLayer.update(parameters); + } + this.div = document.createElement("div"); + parameters.div = this.div; + return pdfjs_lib__WEBPACK_IMPORTED_MODULE_0__.XfaLayer.render(parameters); + } + cancel() { + this._cancelled = true; + } + hide() { + if (!this.div) { + return; + } + this.div.hidden = true; + } +} + +__webpack_async_result__(); +} catch(e) { __webpack_async_result__(e); } }); + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/async module */ +/******/ (() => { +/******/ var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__"; +/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__"; +/******/ var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__"; +/******/ var resolveQueue = (queue) => { +/******/ if(queue && queue.d < 1) { +/******/ queue.d = 1; +/******/ queue.forEach((fn) => (fn.r--)); +/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn())); +/******/ } +/******/ } +/******/ var wrapDeps = (deps) => (deps.map((dep) => { +/******/ if(dep !== null && typeof dep === "object") { +/******/ if(dep[webpackQueues]) return dep; +/******/ if(dep.then) { +/******/ var queue = []; +/******/ queue.d = 0; +/******/ dep.then((r) => { +/******/ obj[webpackExports] = r; +/******/ resolveQueue(queue); +/******/ }, (e) => { +/******/ obj[webpackError] = e; +/******/ resolveQueue(queue); +/******/ }); +/******/ var obj = {}; +/******/ obj[webpackQueues] = (fn) => (fn(queue)); +/******/ return obj; +/******/ } +/******/ } +/******/ var ret = {}; +/******/ ret[webpackQueues] = x => {}; +/******/ ret[webpackExports] = dep; +/******/ return ret; +/******/ })); +/******/ __webpack_require__.a = (module, body, hasAwait) => { +/******/ var queue; +/******/ hasAwait && ((queue = []).d = -1); +/******/ var depQueues = new Set(); +/******/ var exports = module.exports; +/******/ var currentDeps; +/******/ var outerResolve; +/******/ var reject; +/******/ var promise = new Promise((resolve, rej) => { +/******/ reject = rej; +/******/ outerResolve = resolve; +/******/ }); +/******/ promise[webpackExports] = exports; +/******/ promise[webpackQueues] = (fn) => (queue && fn(queue), depQueues.forEach(fn), promise["catch"](x => {})); +/******/ module.exports = promise; +/******/ body((deps) => { +/******/ currentDeps = wrapDeps(deps); +/******/ var fn; +/******/ var getResult = () => (currentDeps.map((d) => { +/******/ if(d[webpackError]) throw d[webpackError]; +/******/ return d[webpackExports]; +/******/ })) +/******/ var promise = new Promise((resolve) => { +/******/ fn = () => (resolve(getResult)); +/******/ fn.r = 0; +/******/ var fnQueue = (q) => (q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))); +/******/ currentDeps.map((dep) => (dep[webpackQueues](fnQueue))); +/******/ }); +/******/ return fn.r ? promise : getResult(); +/******/ }, (err) => ((err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue))); +/******/ queue && queue.d < 0 && (queue.d = 0); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module used 'module' so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__(6400); +/******/ __webpack_exports__ = await __webpack_exports__; +/******/ var __webpack_exports__PDFViewerApplication = __webpack_exports__.PDFViewerApplication; +/******/ var __webpack_exports__PDFViewerApplicationConstants = __webpack_exports__.PDFViewerApplicationConstants; +/******/ var __webpack_exports__PDFViewerApplicationOptions = __webpack_exports__.PDFViewerApplicationOptions; +/******/ export { __webpack_exports__PDFViewerApplication as PDFViewerApplication, __webpack_exports__PDFViewerApplicationConstants as PDFViewerApplicationConstants, __webpack_exports__PDFViewerApplicationOptions as PDFViewerApplicationOptions }; +/******/ + +//# sourceMappingURL=viewer.mjs.map \ No newline at end of file diff --git a/www/lib/pdfjs/modern/web/viewer.mjs.map b/www/lib/pdfjs/modern/web/viewer.mjs.map new file mode 100644 index 000000000..2ade1af7a --- /dev/null +++ b/www/lib/pdfjs/modern/web/viewer.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"viewer.mjs","mappings":"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","sources":["webpack://pdf.js/node_modules/@fluent/bundle/esm/types.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/resolver.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/scope.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/builtins.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/memoizer.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/bundle.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/resource.js","webpack://pdf.js/node_modules/@fluent/bundle/esm/index.js","webpack://pdf.js/node_modules/@fluent/dom/esm/overlay.js","webpack://pdf.js/node_modules/cached-iterable/src/cached_iterable.mjs","webpack://pdf.js/node_modules/cached-iterable/src/cached_sync_iterable.mjs","webpack://pdf.js/node_modules/cached-iterable/src/cached_async_iterable.mjs","webpack://pdf.js/node_modules/cached-iterable/src/index.mjs","webpack://pdf.js/node_modules/@fluent/dom/esm/localization.js","webpack://pdf.js/node_modules/@fluent/dom/esm/dom_localization.js","webpack://pdf.js/node_modules/@fluent/dom/esm/index.js","webpack://pdf.js/web/alt_text_manager.js","webpack://pdf.js/web/annotation_editor_layer_builder.js","webpack://pdf.js/web/annotation_editor_params.js","webpack://pdf.js/web/annotation_layer_builder.js","webpack://pdf.js/web/app.js","webpack://pdf.js/web/app_options.js","webpack://pdf.js/web/base_tree_viewer.js","webpack://pdf.js/web/download_manager.js","webpack://pdf.js/web/draw_layer_builder.js","webpack://pdf.js/web/event_utils.js","webpack://pdf.js/web/generic_scripting.js","webpack://pdf.js/web/genericcom.js","webpack://pdf.js/web/genericl10n.js","webpack://pdf.js/web/grab_to_pan.js","webpack://pdf.js/web/l10n.js","webpack://pdf.js/web/l10n_utils.js","webpack://pdf.js/web/overlay_manager.js","webpack://pdf.js/web/password_prompt.js","webpack://pdf.js/web/pdf_attachment_viewer.js","webpack://pdf.js/web/pdf_cursor_tools.js","webpack://pdf.js/web/pdf_document_properties.js","webpack://pdf.js/web/pdf_find_bar.js","webpack://pdf.js/web/pdf_find_controller.js","webpack://pdf.js/web/pdf_find_utils.js","webpack://pdf.js/web/pdf_history.js","webpack://pdf.js/web/pdf_layer_viewer.js","webpack://pdf.js/web/pdf_link_service.js","webpack://pdf.js/web/pdf_outline_viewer.js","webpack://pdf.js/web/pdf_page_view.js","webpack://pdf.js/web/pdf_presentation_mode.js","webpack://pdf.js/web/pdf_print_service.js","webpack://pdf.js/web/pdf_rendering_queue.js","webpack://pdf.js/web/pdf_scripting_manager.js","webpack://pdf.js/web/pdf_sidebar.js","webpack://pdf.js/web/pdf_thumbnail_view.js","webpack://pdf.js/web/pdf_thumbnail_viewer.js","webpack://pdf.js/web/pdf_viewer.js","webpack://pdf.js/web/pdfjs.js","webpack://pdf.js/web/preferences.js","webpack://pdf.js/web/print_utils.js","webpack://pdf.js/web/secondary_toolbar.js","webpack://pdf.js/web/struct_tree_layer_builder.js","webpack://pdf.js/web/text_accessibility.js","webpack://pdf.js/web/text_highlighter.js","webpack://pdf.js/web/text_layer_builder.js","webpack://pdf.js/web/toolbar.js","webpack://pdf.js/web/ui_utils.js","webpack://pdf.js/web/view_history.js","webpack://pdf.js/web/viewer.js","webpack://pdf.js/web/xfa_layer_builder.js","webpack://pdf.js/webpack/bootstrap","webpack://pdf.js/webpack/runtime/async module","webpack://pdf.js/webpack/runtime/define property getters","webpack://pdf.js/webpack/runtime/hasOwnProperty shorthand","webpack://pdf.js/webpack/before-startup","webpack://pdf.js/webpack/startup","webpack://pdf.js/webpack/after-startup"],"sourcesContent":["/**\n * The `FluentType` class is the base of Fluent's type system.\n *\n * Fluent types wrap JavaScript values and store additional configuration for\n * them, which can then be used in the `toString` method together with a proper\n * `Intl` formatter.\n */\nexport class FluentType {\n /**\n * Create a `FluentType` instance.\n *\n * @param value The JavaScript value to wrap.\n */\n constructor(value) {\n this.value = value;\n }\n /**\n * Unwrap the raw value stored by this `FluentType`.\n */\n valueOf() {\n return this.value;\n }\n}\n/**\n * A `FluentType` representing no correct value.\n */\nexport class FluentNone extends FluentType {\n /**\n * Create an instance of `FluentNone` with an optional fallback value.\n * @param value The fallback value of this `FluentNone`.\n */\n constructor(value = \"???\") {\n super(value);\n }\n /**\n * Format this `FluentNone` to the fallback string.\n */\n toString(scope) {\n return `{${this.value}}`;\n }\n}\n/**\n * A `FluentType` representing a number.\n *\n * A `FluentNumber` instance stores the number value of the number it\n * represents. It may also store an option bag of options which will be passed\n * to `Intl.NumerFormat` when the `FluentNumber` is formatted to a string.\n */\nexport class FluentNumber extends FluentType {\n /**\n * Create an instance of `FluentNumber` with options to the\n * `Intl.NumberFormat` constructor.\n *\n * @param value The number value of this `FluentNumber`.\n * @param opts Options which will be passed to `Intl.NumberFormat`.\n */\n constructor(value, opts = {}) {\n super(value);\n this.opts = opts;\n }\n /**\n * Format this `FluentNumber` to a string.\n */\n toString(scope) {\n try {\n const nf = scope.memoizeIntlObject(Intl.NumberFormat, this.opts);\n return nf.format(this.value);\n }\n catch (err) {\n scope.reportError(err);\n return this.value.toString(10);\n }\n }\n}\n/**\n * A `FluentType` representing a date and time.\n *\n * A `FluentDateTime` instance stores the number value of the date it\n * represents, as a numerical timestamp in milliseconds. It may also store an\n * option bag of options which will be passed to `Intl.DateTimeFormat` when the\n * `FluentDateTime` is formatted to a string.\n */\nexport class FluentDateTime extends FluentType {\n /**\n * Create an instance of `FluentDateTime` with options to the\n * `Intl.DateTimeFormat` constructor.\n *\n * @param value The number value of this `FluentDateTime`, in milliseconds.\n * @param opts Options which will be passed to `Intl.DateTimeFormat`.\n */\n constructor(value, opts = {}) {\n super(value);\n this.opts = opts;\n }\n /**\n * Format this `FluentDateTime` to a string.\n */\n toString(scope) {\n try {\n const dtf = scope.memoizeIntlObject(Intl.DateTimeFormat, this.opts);\n return dtf.format(this.value);\n }\n catch (err) {\n scope.reportError(err);\n return new Date(this.value).toISOString();\n }\n }\n}\n","/* global Intl */\n/**\n * @overview\n *\n * The role of the Fluent resolver is to format a `Pattern` to an instance of\n * `FluentValue`. For performance reasons, primitive strings are considered\n * such instances, too.\n *\n * Translations can contain references to other messages or variables,\n * conditional logic in form of select expressions, traits which describe their\n * grammatical features, and can use Fluent builtins which make use of the\n * `Intl` formatters to format numbers and dates into the bundle's languages.\n * See the documentation of the Fluent syntax for more information.\n *\n * In case of errors the resolver will try to salvage as much of the\n * translation as possible. In rare situations where the resolver didn't know\n * how to recover from an error it will return an instance of `FluentNone`.\n *\n * All expressions resolve to an instance of `FluentValue`. The caller should\n * use the `toString` method to convert the instance to a native value.\n *\n * Functions in this file pass around an instance of the `Scope` class, which\n * stores the data required for successful resolution and error recovery.\n */\nimport { FluentType, FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\n/**\n * The maximum number of placeables which can be expanded in a single call to\n * `formatPattern`. The limit protects against the Billion Laughs and Quadratic\n * Blowup attacks. See https://msdn.microsoft.com/en-us/magazine/ee335713.aspx.\n */\nconst MAX_PLACEABLES = 100;\n/** Unicode bidi isolation characters. */\nconst FSI = \"\\u2068\";\nconst PDI = \"\\u2069\";\n/** Helper: match a variant key to the given selector. */\nfunction match(scope, selector, key) {\n if (key === selector) {\n // Both are strings.\n return true;\n }\n // XXX Consider comparing options too, e.g. minimumFractionDigits.\n if (key instanceof FluentNumber &&\n selector instanceof FluentNumber &&\n key.value === selector.value) {\n return true;\n }\n if (selector instanceof FluentNumber && typeof key === \"string\") {\n let category = scope\n .memoizeIntlObject(Intl.PluralRules, selector.opts)\n .select(selector.value);\n if (key === category) {\n return true;\n }\n }\n return false;\n}\n/** Helper: resolve the default variant from a list of variants. */\nfunction getDefault(scope, variants, star) {\n if (variants[star]) {\n return resolvePattern(scope, variants[star].value);\n }\n scope.reportError(new RangeError(\"No default\"));\n return new FluentNone();\n}\n/** Helper: resolve arguments to a call expression. */\nfunction getArguments(scope, args) {\n const positional = [];\n const named = Object.create(null);\n for (const arg of args) {\n if (arg.type === \"narg\") {\n named[arg.name] = resolveExpression(scope, arg.value);\n }\n else {\n positional.push(resolveExpression(scope, arg));\n }\n }\n return { positional, named };\n}\n/** Resolve an expression to a Fluent type. */\nfunction resolveExpression(scope, expr) {\n switch (expr.type) {\n case \"str\":\n return expr.value;\n case \"num\":\n return new FluentNumber(expr.value, {\n minimumFractionDigits: expr.precision,\n });\n case \"var\":\n return resolveVariableReference(scope, expr);\n case \"mesg\":\n return resolveMessageReference(scope, expr);\n case \"term\":\n return resolveTermReference(scope, expr);\n case \"func\":\n return resolveFunctionReference(scope, expr);\n case \"select\":\n return resolveSelectExpression(scope, expr);\n default:\n return new FluentNone();\n }\n}\n/** Resolve a reference to a variable. */\nfunction resolveVariableReference(scope, { name }) {\n let arg;\n if (scope.params) {\n // We're inside a TermReference. It's OK to reference undefined parameters.\n if (Object.prototype.hasOwnProperty.call(scope.params, name)) {\n arg = scope.params[name];\n }\n else {\n return new FluentNone(`$${name}`);\n }\n }\n else if (scope.args &&\n Object.prototype.hasOwnProperty.call(scope.args, name)) {\n // We're in the top-level Pattern or inside a MessageReference. Missing\n // variables references produce ReferenceErrors.\n arg = scope.args[name];\n }\n else {\n scope.reportError(new ReferenceError(`Unknown variable: $${name}`));\n return new FluentNone(`$${name}`);\n }\n // Return early if the argument already is an instance of FluentType.\n if (arg instanceof FluentType) {\n return arg;\n }\n // Convert the argument to a Fluent type.\n switch (typeof arg) {\n case \"string\":\n return arg;\n case \"number\":\n return new FluentNumber(arg);\n case \"object\":\n if (arg instanceof Date) {\n return new FluentDateTime(arg.getTime());\n }\n // eslint-disable-next-line no-fallthrough\n default:\n scope.reportError(new TypeError(`Variable type not supported: $${name}, ${typeof arg}`));\n return new FluentNone(`$${name}`);\n }\n}\n/** Resolve a reference to another message. */\nfunction resolveMessageReference(scope, { name, attr }) {\n const message = scope.bundle._messages.get(name);\n if (!message) {\n scope.reportError(new ReferenceError(`Unknown message: ${name}`));\n return new FluentNone(name);\n }\n if (attr) {\n const attribute = message.attributes[attr];\n if (attribute) {\n return resolvePattern(scope, attribute);\n }\n scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));\n return new FluentNone(`${name}.${attr}`);\n }\n if (message.value) {\n return resolvePattern(scope, message.value);\n }\n scope.reportError(new ReferenceError(`No value: ${name}`));\n return new FluentNone(name);\n}\n/** Resolve a call to a Term with key-value arguments. */\nfunction resolveTermReference(scope, { name, attr, args }) {\n const id = `-${name}`;\n const term = scope.bundle._terms.get(id);\n if (!term) {\n scope.reportError(new ReferenceError(`Unknown term: ${id}`));\n return new FluentNone(id);\n }\n if (attr) {\n const attribute = term.attributes[attr];\n if (attribute) {\n // Every TermReference has its own variables.\n scope.params = getArguments(scope, args).named;\n const resolved = resolvePattern(scope, attribute);\n scope.params = null;\n return resolved;\n }\n scope.reportError(new ReferenceError(`Unknown attribute: ${attr}`));\n return new FluentNone(`${id}.${attr}`);\n }\n scope.params = getArguments(scope, args).named;\n const resolved = resolvePattern(scope, term.value);\n scope.params = null;\n return resolved;\n}\n/** Resolve a call to a Function with positional and key-value arguments. */\nfunction resolveFunctionReference(scope, { name, args }) {\n // Some functions are built-in. Others may be provided by the runtime via\n // the `FluentBundle` constructor.\n let func = scope.bundle._functions[name];\n if (!func) {\n scope.reportError(new ReferenceError(`Unknown function: ${name}()`));\n return new FluentNone(`${name}()`);\n }\n if (typeof func !== \"function\") {\n scope.reportError(new TypeError(`Function ${name}() is not callable`));\n return new FluentNone(`${name}()`);\n }\n try {\n let resolved = getArguments(scope, args);\n return func(resolved.positional, resolved.named);\n }\n catch (err) {\n scope.reportError(err);\n return new FluentNone(`${name}()`);\n }\n}\n/** Resolve a select expression to the member object. */\nfunction resolveSelectExpression(scope, { selector, variants, star }) {\n let sel = resolveExpression(scope, selector);\n if (sel instanceof FluentNone) {\n return getDefault(scope, variants, star);\n }\n // Match the selector against keys of each variant, in order.\n for (const variant of variants) {\n const key = resolveExpression(scope, variant.key);\n if (match(scope, sel, key)) {\n return resolvePattern(scope, variant.value);\n }\n }\n return getDefault(scope, variants, star);\n}\n/** Resolve a pattern (a complex string with placeables). */\nexport function resolveComplexPattern(scope, ptn) {\n if (scope.dirty.has(ptn)) {\n scope.reportError(new RangeError(\"Cyclic reference\"));\n return new FluentNone();\n }\n // Tag the pattern as dirty for the purpose of the current resolution.\n scope.dirty.add(ptn);\n const result = [];\n // Wrap interpolations with Directional Isolate Formatting characters\n // only when the pattern has more than one element.\n const useIsolating = scope.bundle._useIsolating && ptn.length > 1;\n for (const elem of ptn) {\n if (typeof elem === \"string\") {\n result.push(scope.bundle._transform(elem));\n continue;\n }\n scope.placeables++;\n if (scope.placeables > MAX_PLACEABLES) {\n scope.dirty.delete(ptn);\n // This is a fatal error which causes the resolver to instantly bail out\n // on this pattern. The length check protects against excessive memory\n // usage, and throwing protects against eating up the CPU when long\n // placeables are deeply nested.\n throw new RangeError(`Too many placeables expanded: ${scope.placeables}, ` +\n `max allowed is ${MAX_PLACEABLES}`);\n }\n if (useIsolating) {\n result.push(FSI);\n }\n result.push(resolveExpression(scope, elem).toString(scope));\n if (useIsolating) {\n result.push(PDI);\n }\n }\n scope.dirty.delete(ptn);\n return result.join(\"\");\n}\n/**\n * Resolve a simple or a complex Pattern to a FluentString\n * (which is really the string primitive).\n */\nfunction resolvePattern(scope, value) {\n // Resolve a simple pattern.\n if (typeof value === \"string\") {\n return scope.bundle._transform(value);\n }\n return resolveComplexPattern(scope, value);\n}\n","export class Scope {\n constructor(bundle, errors, args) {\n /**\n * The Set of patterns already encountered during this resolution.\n * Used to detect and prevent cyclic resolutions.\n * @ignore\n */\n this.dirty = new WeakSet();\n /** A dict of parameters passed to a TermReference. */\n this.params = null;\n /**\n * The running count of placeables resolved so far.\n * Used to detect the Billion Laughs and Quadratic Blowup attacks.\n * @ignore\n */\n this.placeables = 0;\n this.bundle = bundle;\n this.errors = errors;\n this.args = args;\n }\n reportError(error) {\n if (!this.errors || !(error instanceof Error)) {\n throw error;\n }\n this.errors.push(error);\n }\n memoizeIntlObject(ctor, opts) {\n let cache = this.bundle._intls.get(ctor);\n if (!cache) {\n cache = {};\n this.bundle._intls.set(ctor, cache);\n }\n let id = JSON.stringify(opts);\n if (!cache[id]) {\n cache[id] = new ctor(this.bundle.locales, opts);\n }\n return cache[id];\n }\n}\n","/**\n * @overview\n *\n * The FTL resolver ships with a number of functions built-in.\n *\n * Each function take two arguments:\n * - args - an array of positional args\n * - opts - an object of key-value args\n *\n * Arguments to functions are guaranteed to already be instances of\n * `FluentValue`. Functions must return `FluentValues` as well.\n */\nimport { FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\nfunction values(opts, allowed) {\n const unwrapped = Object.create(null);\n for (const [name, opt] of Object.entries(opts)) {\n if (allowed.includes(name)) {\n unwrapped[name] = opt.valueOf();\n }\n }\n return unwrapped;\n}\nconst NUMBER_ALLOWED = [\n \"unitDisplay\",\n \"currencyDisplay\",\n \"useGrouping\",\n \"minimumIntegerDigits\",\n \"minimumFractionDigits\",\n \"maximumFractionDigits\",\n \"minimumSignificantDigits\",\n \"maximumSignificantDigits\",\n];\n/**\n * The implementation of the `NUMBER()` builtin available to translations.\n *\n * Translations may call the `NUMBER()` builtin in order to specify formatting\n * options of a number. For example:\n *\n * pi = The value of π is {NUMBER($pi, maximumFractionDigits: 2)}.\n *\n * The implementation expects an array of `FluentValues` representing the\n * positional arguments, and an object of named `FluentValues` representing the\n * named parameters.\n *\n * The following options are recognized:\n *\n * unitDisplay\n * currencyDisplay\n * useGrouping\n * minimumIntegerDigits\n * minimumFractionDigits\n * maximumFractionDigits\n * minimumSignificantDigits\n * maximumSignificantDigits\n *\n * Other options are ignored.\n *\n * @param args The positional arguments passed to this `NUMBER()`.\n * @param opts The named argments passed to this `NUMBER()`.\n */\nexport function NUMBER(args, opts) {\n let arg = args[0];\n if (arg instanceof FluentNone) {\n return new FluentNone(`NUMBER(${arg.valueOf()})`);\n }\n if (arg instanceof FluentNumber) {\n return new FluentNumber(arg.valueOf(), {\n ...arg.opts,\n ...values(opts, NUMBER_ALLOWED),\n });\n }\n if (arg instanceof FluentDateTime) {\n return new FluentNumber(arg.valueOf(), {\n ...values(opts, NUMBER_ALLOWED),\n });\n }\n throw new TypeError(\"Invalid argument to NUMBER\");\n}\nconst DATETIME_ALLOWED = [\n \"dateStyle\",\n \"timeStyle\",\n \"fractionalSecondDigits\",\n \"dayPeriod\",\n \"hour12\",\n \"weekday\",\n \"era\",\n \"year\",\n \"month\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n \"timeZoneName\",\n];\n/**\n * The implementation of the `DATETIME()` builtin available to translations.\n *\n * Translations may call the `DATETIME()` builtin in order to specify\n * formatting options of a number. For example:\n *\n * now = It's {DATETIME($today, month: \"long\")}.\n *\n * The implementation expects an array of `FluentValues` representing the\n * positional arguments, and an object of named `FluentValues` representing the\n * named parameters.\n *\n * The following options are recognized:\n *\n * dateStyle\n * timeStyle\n * fractionalSecondDigits\n * dayPeriod\n * hour12\n * weekday\n * era\n * year\n * month\n * day\n * hour\n * minute\n * second\n * timeZoneName\n *\n * Other options are ignored.\n *\n * @param args The positional arguments passed to this `DATETIME()`.\n * @param opts The named argments passed to this `DATETIME()`.\n */\nexport function DATETIME(args, opts) {\n let arg = args[0];\n if (arg instanceof FluentNone) {\n return new FluentNone(`DATETIME(${arg.valueOf()})`);\n }\n if (arg instanceof FluentDateTime) {\n return new FluentDateTime(arg.valueOf(), {\n ...arg.opts,\n ...values(opts, DATETIME_ALLOWED),\n });\n }\n if (arg instanceof FluentNumber) {\n return new FluentDateTime(arg.valueOf(), {\n ...values(opts, DATETIME_ALLOWED),\n });\n }\n throw new TypeError(\"Invalid argument to DATETIME\");\n}\n","const cache = new Map();\nexport function getMemoizerForLocale(locales) {\n const stringLocale = Array.isArray(locales) ? locales.join(\" \") : locales;\n let memoizer = cache.get(stringLocale);\n if (memoizer === undefined) {\n memoizer = new Map();\n cache.set(stringLocale, memoizer);\n }\n return memoizer;\n}\n","import { resolveComplexPattern } from \"./resolver.js\";\nimport { Scope } from \"./scope.js\";\nimport { FluentNone } from \"./types.js\";\nimport { NUMBER, DATETIME } from \"./builtins.js\";\nimport { getMemoizerForLocale } from \"./memoizer.js\";\n/**\n * Message bundles are single-language stores of translation resources. They are\n * responsible for formatting message values and attributes to strings.\n */\nexport class FluentBundle {\n /**\n * Create an instance of `FluentBundle`.\n *\n * @example\n * ```js\n * let bundle = new FluentBundle([\"en-US\", \"en\"]);\n *\n * let bundle = new FluentBundle(locales, {useIsolating: false});\n *\n * let bundle = new FluentBundle(locales, {\n * useIsolating: true,\n * functions: {\n * NODE_ENV: () => process.env.NODE_ENV\n * }\n * });\n * ```\n *\n * @param locales - Used to instantiate `Intl` formatters used by translations.\n * @param options - Optional configuration for the bundle.\n */\n constructor(locales, { functions, useIsolating = true, transform = (v) => v, } = {}) {\n /** @ignore */\n this._terms = new Map();\n /** @ignore */\n this._messages = new Map();\n this.locales = Array.isArray(locales) ? locales : [locales];\n this._functions = {\n NUMBER,\n DATETIME,\n ...functions,\n };\n this._useIsolating = useIsolating;\n this._transform = transform;\n this._intls = getMemoizerForLocale(locales);\n }\n /**\n * Check if a message is present in the bundle.\n *\n * @param id - The identifier of the message to check.\n */\n hasMessage(id) {\n return this._messages.has(id);\n }\n /**\n * Return a raw unformatted message object from the bundle.\n *\n * Raw messages are `{value, attributes}` shapes containing translation units\n * called `Patterns`. `Patterns` are implementation-specific; they should be\n * treated as black boxes and formatted with `FluentBundle.formatPattern`.\n *\n * @param id - The identifier of the message to check.\n */\n getMessage(id) {\n return this._messages.get(id);\n }\n /**\n * Add a translation resource to the bundle.\n *\n * @example\n * ```js\n * let res = new FluentResource(\"foo = Foo\");\n * bundle.addResource(res);\n * bundle.getMessage(\"foo\");\n * // → {value: .., attributes: {..}}\n * ```\n *\n * @param res\n * @param options\n */\n addResource(res, { allowOverrides = false, } = {}) {\n const errors = [];\n for (let i = 0; i < res.body.length; i++) {\n let entry = res.body[i];\n if (entry.id.startsWith(\"-\")) {\n // Identifiers starting with a dash (-) define terms. Terms are private\n // and cannot be retrieved from FluentBundle.\n if (allowOverrides === false && this._terms.has(entry.id)) {\n errors.push(new Error(`Attempt to override an existing term: \"${entry.id}\"`));\n continue;\n }\n this._terms.set(entry.id, entry);\n }\n else {\n if (allowOverrides === false && this._messages.has(entry.id)) {\n errors.push(new Error(`Attempt to override an existing message: \"${entry.id}\"`));\n continue;\n }\n this._messages.set(entry.id, entry);\n }\n }\n return errors;\n }\n /**\n * Format a `Pattern` to a string.\n *\n * Format a raw `Pattern` into a string. `args` will be used to resolve\n * references to variables passed as arguments to the translation.\n *\n * In case of errors `formatPattern` will try to salvage as much of the\n * translation as possible and will still return a string. For performance\n * reasons, the encountered errors are not returned but instead are appended\n * to the `errors` array passed as the third argument.\n *\n * If `errors` is omitted, the first encountered error will be thrown.\n *\n * @example\n * ```js\n * let errors = [];\n * bundle.addResource(\n * new FluentResource(\"hello = Hello, {$name}!\"));\n *\n * let hello = bundle.getMessage(\"hello\");\n * if (hello.value) {\n * bundle.formatPattern(hello.value, {name: \"Jane\"}, errors);\n * // Returns \"Hello, Jane!\" and `errors` is empty.\n *\n * bundle.formatPattern(hello.value, undefined, errors);\n * // Returns \"Hello, {$name}!\" and `errors` is now:\n * // []\n * }\n * ```\n */\n formatPattern(pattern, args = null, errors = null) {\n // Resolve a simple pattern without creating a scope. No error handling is\n // required; by definition simple patterns don't have placeables.\n if (typeof pattern === \"string\") {\n return this._transform(pattern);\n }\n // Resolve a complex pattern.\n let scope = new Scope(this, errors, args);\n try {\n let value = resolveComplexPattern(scope, pattern);\n return value.toString(scope);\n }\n catch (err) {\n if (scope.errors && err instanceof Error) {\n scope.errors.push(err);\n return new FluentNone().toString(scope);\n }\n throw err;\n }\n }\n}\n","// This regex is used to iterate through the beginnings of messages and terms.\n// With the /m flag, the ^ matches at the beginning of every line.\nconst RE_MESSAGE_START = /^(-?[a-zA-Z][\\w-]*) *= */gm;\n// Both Attributes and Variants are parsed in while loops. These regexes are\n// used to break out of them.\nconst RE_ATTRIBUTE_START = /\\.([a-zA-Z][\\w-]*) *= */y;\nconst RE_VARIANT_START = /\\*?\\[/y;\nconst RE_NUMBER_LITERAL = /(-?[0-9]+(?:\\.([0-9]+))?)/y;\nconst RE_IDENTIFIER = /([a-zA-Z][\\w-]*)/y;\nconst RE_REFERENCE = /([$-])?([a-zA-Z][\\w-]*)(?:\\.([a-zA-Z][\\w-]*))?/y;\nconst RE_FUNCTION_NAME = /^[A-Z][A-Z0-9_-]*$/;\n// A \"run\" is a sequence of text or string literal characters which don't\n// require any special handling. For TextElements such special characters are: {\n// (starts a placeable), and line breaks which require additional logic to check\n// if the next line is indented. For StringLiterals they are: \\ (starts an\n// escape sequence), \" (ends the literal), and line breaks which are not allowed\n// in StringLiterals. Note that string runs may be empty; text runs may not.\nconst RE_TEXT_RUN = /([^{}\\n\\r]+)/y;\nconst RE_STRING_RUN = /([^\\\\\"\\n\\r]*)/y;\n// Escape sequences.\nconst RE_STRING_ESCAPE = /\\\\([\\\\\"])/y;\nconst RE_UNICODE_ESCAPE = /\\\\u([a-fA-F0-9]{4})|\\\\U([a-fA-F0-9]{6})/y;\n// Used for trimming TextElements and indents.\nconst RE_LEADING_NEWLINES = /^\\n+/;\nconst RE_TRAILING_SPACES = / +$/;\n// Used in makeIndent to strip spaces from blank lines and normalize CRLF to LF.\nconst RE_BLANK_LINES = / *\\r?\\n/g;\n// Used in makeIndent to measure the indentation.\nconst RE_INDENT = /( *)$/;\n// Common tokens.\nconst TOKEN_BRACE_OPEN = /{\\s*/y;\nconst TOKEN_BRACE_CLOSE = /\\s*}/y;\nconst TOKEN_BRACKET_OPEN = /\\[\\s*/y;\nconst TOKEN_BRACKET_CLOSE = /\\s*] */y;\nconst TOKEN_PAREN_OPEN = /\\s*\\(\\s*/y;\nconst TOKEN_ARROW = /\\s*->\\s*/y;\nconst TOKEN_COLON = /\\s*:\\s*/y;\n// Note the optional comma. As a deviation from the Fluent EBNF, the parser\n// doesn't enforce commas between call arguments.\nconst TOKEN_COMMA = /\\s*,?\\s*/y;\nconst TOKEN_BLANK = /\\s+/y;\n/**\n * Fluent Resource is a structure storing parsed localization entries.\n */\nexport class FluentResource {\n constructor(source) {\n this.body = [];\n RE_MESSAGE_START.lastIndex = 0;\n let cursor = 0;\n // Iterate over the beginnings of messages and terms to efficiently skip\n // comments and recover from errors.\n while (true) {\n let next = RE_MESSAGE_START.exec(source);\n if (next === null) {\n break;\n }\n cursor = RE_MESSAGE_START.lastIndex;\n try {\n this.body.push(parseMessage(next[1]));\n }\n catch (err) {\n if (err instanceof SyntaxError) {\n // Don't report any Fluent syntax errors. Skip directly to the\n // beginning of the next message or term.\n continue;\n }\n throw err;\n }\n }\n // The parser implementation is inlined below for performance reasons,\n // as well as for convenience of accessing `source` and `cursor`.\n // The parser focuses on minimizing the number of false negatives at the\n // expense of increasing the risk of false positives. In other words, it\n // aims at parsing valid Fluent messages with a success rate of 100%, but it\n // may also parse a few invalid messages which the reference parser would\n // reject. The parser doesn't perform any validation and may produce entries\n // which wouldn't make sense in the real world. For best results users are\n // advised to validate translations with the fluent-syntax parser\n // pre-runtime.\n // The parser makes an extensive use of sticky regexes which can be anchored\n // to any offset of the source string without slicing it. Errors are thrown\n // to bail out of parsing of ill-formed messages.\n function test(re) {\n re.lastIndex = cursor;\n return re.test(source);\n }\n // Advance the cursor by the char if it matches. May be used as a predicate\n // (was the match found?) or, if errorClass is passed, as an assertion.\n function consumeChar(char, errorClass) {\n if (source[cursor] === char) {\n cursor++;\n return true;\n }\n if (errorClass) {\n throw new errorClass(`Expected ${char}`);\n }\n return false;\n }\n // Advance the cursor by the token if it matches. May be used as a predicate\n // (was the match found?) or, if errorClass is passed, as an assertion.\n function consumeToken(re, errorClass) {\n if (test(re)) {\n cursor = re.lastIndex;\n return true;\n }\n if (errorClass) {\n throw new errorClass(`Expected ${re.toString()}`);\n }\n return false;\n }\n // Execute a regex, advance the cursor, and return all capture groups.\n function match(re) {\n re.lastIndex = cursor;\n let result = re.exec(source);\n if (result === null) {\n throw new SyntaxError(`Expected ${re.toString()}`);\n }\n cursor = re.lastIndex;\n return result;\n }\n // Execute a regex, advance the cursor, and return the capture group.\n function match1(re) {\n return match(re)[1];\n }\n function parseMessage(id) {\n let value = parsePattern();\n let attributes = parseAttributes();\n if (value === null && Object.keys(attributes).length === 0) {\n throw new SyntaxError(\"Expected message value or attributes\");\n }\n return { id, value, attributes };\n }\n function parseAttributes() {\n let attrs = Object.create(null);\n while (test(RE_ATTRIBUTE_START)) {\n let name = match1(RE_ATTRIBUTE_START);\n let value = parsePattern();\n if (value === null) {\n throw new SyntaxError(\"Expected attribute value\");\n }\n attrs[name] = value;\n }\n return attrs;\n }\n function parsePattern() {\n let first;\n // First try to parse any simple text on the same line as the id.\n if (test(RE_TEXT_RUN)) {\n first = match1(RE_TEXT_RUN);\n }\n // If there's a placeable on the first line, parse a complex pattern.\n if (source[cursor] === \"{\" || source[cursor] === \"}\") {\n // Re-use the text parsed above, if possible.\n return parsePatternElements(first ? [first] : [], Infinity);\n }\n // RE_TEXT_VALUE stops at newlines. Only continue parsing the pattern if\n // what comes after the newline is indented.\n let indent = parseIndent();\n if (indent) {\n if (first) {\n // If there's text on the first line, the blank block is part of the\n // translation content in its entirety.\n return parsePatternElements([first, indent], indent.length);\n }\n // Otherwise, we're dealing with a block pattern, i.e. a pattern which\n // starts on a new line. Discrad the leading newlines but keep the\n // inline indent; it will be used by the dedentation logic.\n indent.value = trim(indent.value, RE_LEADING_NEWLINES);\n return parsePatternElements([indent], indent.length);\n }\n if (first) {\n // It was just a simple inline text after all.\n return trim(first, RE_TRAILING_SPACES);\n }\n return null;\n }\n // Parse a complex pattern as an array of elements.\n function parsePatternElements(elements = [], commonIndent) {\n while (true) {\n if (test(RE_TEXT_RUN)) {\n elements.push(match1(RE_TEXT_RUN));\n continue;\n }\n if (source[cursor] === \"{\") {\n elements.push(parsePlaceable());\n continue;\n }\n if (source[cursor] === \"}\") {\n throw new SyntaxError(\"Unbalanced closing brace\");\n }\n let indent = parseIndent();\n if (indent) {\n elements.push(indent);\n commonIndent = Math.min(commonIndent, indent.length);\n continue;\n }\n break;\n }\n let lastIndex = elements.length - 1;\n let lastElement = elements[lastIndex];\n // Trim the trailing spaces in the last element if it's a TextElement.\n if (typeof lastElement === \"string\") {\n elements[lastIndex] = trim(lastElement, RE_TRAILING_SPACES);\n }\n let baked = [];\n for (let element of elements) {\n if (element instanceof Indent) {\n // Dedent indented lines by the maximum common indent.\n element = element.value.slice(0, element.value.length - commonIndent);\n }\n if (element) {\n baked.push(element);\n }\n }\n return baked;\n }\n function parsePlaceable() {\n consumeToken(TOKEN_BRACE_OPEN, SyntaxError);\n let selector = parseInlineExpression();\n if (consumeToken(TOKEN_BRACE_CLOSE)) {\n return selector;\n }\n if (consumeToken(TOKEN_ARROW)) {\n let variants = parseVariants();\n consumeToken(TOKEN_BRACE_CLOSE, SyntaxError);\n return {\n type: \"select\",\n selector,\n ...variants,\n };\n }\n throw new SyntaxError(\"Unclosed placeable\");\n }\n function parseInlineExpression() {\n if (source[cursor] === \"{\") {\n // It's a nested placeable.\n return parsePlaceable();\n }\n if (test(RE_REFERENCE)) {\n let [, sigil, name, attr = null] = match(RE_REFERENCE);\n if (sigil === \"$\") {\n return { type: \"var\", name };\n }\n if (consumeToken(TOKEN_PAREN_OPEN)) {\n let args = parseArguments();\n if (sigil === \"-\") {\n // A parameterized term: -term(...).\n return { type: \"term\", name, attr, args };\n }\n if (RE_FUNCTION_NAME.test(name)) {\n return { type: \"func\", name, args };\n }\n throw new SyntaxError(\"Function names must be all upper-case\");\n }\n if (sigil === \"-\") {\n // A non-parameterized term: -term.\n return {\n type: \"term\",\n name,\n attr,\n args: [],\n };\n }\n return { type: \"mesg\", name, attr };\n }\n return parseLiteral();\n }\n function parseArguments() {\n let args = [];\n while (true) {\n switch (source[cursor]) {\n case \")\": // End of the argument list.\n cursor++;\n return args;\n case undefined: // EOF\n throw new SyntaxError(\"Unclosed argument list\");\n }\n args.push(parseArgument());\n // Commas between arguments are treated as whitespace.\n consumeToken(TOKEN_COMMA);\n }\n }\n function parseArgument() {\n let expr = parseInlineExpression();\n if (expr.type !== \"mesg\") {\n return expr;\n }\n if (consumeToken(TOKEN_COLON)) {\n // The reference is the beginning of a named argument.\n return {\n type: \"narg\",\n name: expr.name,\n value: parseLiteral(),\n };\n }\n // It's a regular message reference.\n return expr;\n }\n function parseVariants() {\n let variants = [];\n let count = 0;\n let star;\n while (test(RE_VARIANT_START)) {\n if (consumeChar(\"*\")) {\n star = count;\n }\n let key = parseVariantKey();\n let value = parsePattern();\n if (value === null) {\n throw new SyntaxError(\"Expected variant value\");\n }\n variants[count++] = { key, value };\n }\n if (count === 0) {\n return null;\n }\n if (star === undefined) {\n throw new SyntaxError(\"Expected default variant\");\n }\n return { variants, star };\n }\n function parseVariantKey() {\n consumeToken(TOKEN_BRACKET_OPEN, SyntaxError);\n let key;\n if (test(RE_NUMBER_LITERAL)) {\n key = parseNumberLiteral();\n }\n else {\n key = {\n type: \"str\",\n value: match1(RE_IDENTIFIER),\n };\n }\n consumeToken(TOKEN_BRACKET_CLOSE, SyntaxError);\n return key;\n }\n function parseLiteral() {\n if (test(RE_NUMBER_LITERAL)) {\n return parseNumberLiteral();\n }\n if (source[cursor] === '\"') {\n return parseStringLiteral();\n }\n throw new SyntaxError(\"Invalid expression\");\n }\n function parseNumberLiteral() {\n let [, value, fraction = \"\"] = match(RE_NUMBER_LITERAL);\n let precision = fraction.length;\n return {\n type: \"num\",\n value: parseFloat(value),\n precision,\n };\n }\n function parseStringLiteral() {\n consumeChar('\"', SyntaxError);\n let value = \"\";\n while (true) {\n value += match1(RE_STRING_RUN);\n if (source[cursor] === \"\\\\\") {\n value += parseEscapeSequence();\n continue;\n }\n if (consumeChar('\"')) {\n return { type: \"str\", value };\n }\n // We've reached an EOL of EOF.\n throw new SyntaxError(\"Unclosed string literal\");\n }\n }\n // Unescape known escape sequences.\n function parseEscapeSequence() {\n if (test(RE_STRING_ESCAPE)) {\n return match1(RE_STRING_ESCAPE);\n }\n if (test(RE_UNICODE_ESCAPE)) {\n let [, codepoint4, codepoint6] = match(RE_UNICODE_ESCAPE);\n let codepoint = parseInt(codepoint4 || codepoint6, 16);\n return codepoint <= 0xd7ff || 0xe000 <= codepoint\n ? // It's a Unicode scalar value.\n String.fromCodePoint(codepoint)\n : // Lonely surrogates can cause trouble when the parsing result is\n // saved using UTF-8. Use U+FFFD REPLACEMENT CHARACTER instead.\n \"�\";\n }\n throw new SyntaxError(\"Unknown escape sequence\");\n }\n // Parse blank space. Return it if it looks like indent before a pattern\n // line. Skip it othwerwise.\n function parseIndent() {\n let start = cursor;\n consumeToken(TOKEN_BLANK);\n // Check the first non-blank character after the indent.\n switch (source[cursor]) {\n case \".\":\n case \"[\":\n case \"*\":\n case \"}\":\n case undefined: // EOF\n // A special character. End the Pattern.\n return false;\n case \"{\":\n // Placeables don't require indentation (in EBNF: block-placeable).\n // Continue the Pattern.\n return makeIndent(source.slice(start, cursor));\n }\n // If the first character on the line is not one of the special characters\n // listed above, it's a regular text character. Check if there's at least\n // one space of indent before it.\n if (source[cursor - 1] === \" \") {\n // It's an indented text character (in EBNF: indented-char). Continue\n // the Pattern.\n return makeIndent(source.slice(start, cursor));\n }\n // A not-indented text character is likely the identifier of the next\n // message. End the Pattern.\n return false;\n }\n // Trim blanks in text according to the given regex.\n function trim(text, re) {\n return text.replace(re, \"\");\n }\n // Normalize a blank block and extract the indent details.\n function makeIndent(blank) {\n let value = blank.replace(RE_BLANK_LINES, \"\\n\");\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let length = RE_INDENT.exec(blank)[1].length;\n return new Indent(value, length);\n }\n }\n}\nclass Indent {\n constructor(value, length) {\n this.value = value;\n this.length = length;\n }\n}\n","/**\n * @module fluent\n * @overview\n *\n * `fluent` is a JavaScript implementation of Project Fluent, a localization\n * framework designed to unleash the expressive power of the natural language.\n *\n */\nexport { FluentBundle } from \"./bundle.js\";\nexport { FluentResource } from \"./resource.js\";\nexport { FluentType, FluentNone, FluentNumber, FluentDateTime, } from \"./types.js\";\n","/* eslint no-console: [\"error\", {allow: [\"warn\"]}] */\n/* global console */\n// Match the opening angle bracket (<) in HTML tags, and HTML entities like\n// &, &, &.\nconst reOverlay = /<|&#?\\w+;/;\n/**\n * Elements allowed in translations even if they are not present in the source\n * HTML. They are text-level elements as defined by the HTML5 spec:\n * https://www.w3.org/TR/html5/text-level-semantics.html with the exception of:\n *\n * - a - because we don't allow href on it anyways,\n * - ruby, rt, rp - because we don't allow nested elements to be inserted.\n */\nconst TEXT_LEVEL_ELEMENTS = {\n \"http://www.w3.org/1999/xhtml\": [\n \"em\",\n \"strong\",\n \"small\",\n \"s\",\n \"cite\",\n \"q\",\n \"dfn\",\n \"abbr\",\n \"data\",\n \"time\",\n \"code\",\n \"var\",\n \"samp\",\n \"kbd\",\n \"sub\",\n \"sup\",\n \"i\",\n \"b\",\n \"u\",\n \"mark\",\n \"bdi\",\n \"bdo\",\n \"span\",\n \"br\",\n \"wbr\",\n ],\n};\nconst LOCALIZABLE_ATTRIBUTES = {\n \"http://www.w3.org/1999/xhtml\": {\n global: [\"title\", \"aria-label\", \"aria-valuetext\"],\n a: [\"download\"],\n area: [\"download\", \"alt\"],\n // value is special-cased in isAttrNameLocalizable\n input: [\"alt\", \"placeholder\"],\n menuitem: [\"label\"],\n menu: [\"label\"],\n optgroup: [\"label\"],\n option: [\"label\"],\n track: [\"label\"],\n img: [\"alt\"],\n textarea: [\"placeholder\"],\n th: [\"abbr\"],\n },\n \"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul\": {\n global: [\n \"accesskey\",\n \"aria-label\",\n \"aria-valuetext\",\n \"label\",\n \"title\",\n \"tooltiptext\",\n ],\n description: [\"value\"],\n key: [\"key\", \"keycode\"],\n label: [\"value\"],\n textbox: [\"placeholder\", \"value\"],\n },\n};\n/**\n * Translate an element.\n *\n * Translate the element's text content and attributes. Some HTML markup is\n * allowed in the translation. The element's children with the data-l10n-name\n * attribute will be treated as arguments to the translation. If the\n * translation defines the same children, their attributes and text contents\n * will be used for translating the matching source child.\n *\n * @param {Element} element\n * @param {Object} translation\n * @private\n */\nexport default function translateElement(element, translation) {\n const { value } = translation;\n if (typeof value === \"string\") {\n if (element.localName === \"title\" &&\n element.namespaceURI === \"http://www.w3.org/1999/xhtml\") {\n // A special case for the HTML title element whose content must be text.\n element.textContent = value;\n }\n else if (!reOverlay.test(value)) {\n // If the translation doesn't contain any markup skip the overlay logic.\n element.textContent = value;\n }\n else {\n // Else parse the translation's HTML using an inert template element,\n // sanitize it and replace the element's content.\n const templateElement = element.ownerDocument.createElementNS(\"http://www.w3.org/1999/xhtml\", \"template\");\n templateElement.innerHTML = value;\n overlayChildNodes(templateElement.content, element);\n }\n }\n // Even if the translation doesn't define any localizable attributes, run\n // overlayAttributes to remove any localizable attributes set by previous\n // translations.\n overlayAttributes(translation, element);\n}\n/**\n * Replace child nodes of an element with child nodes of another element.\n *\n * The contents of the target element will be cleared and fully replaced with\n * sanitized contents of the source element.\n *\n * @param {DocumentFragment} fromFragment - The source of children to overlay.\n * @param {Element} toElement - The target of the overlay.\n * @private\n */\nfunction overlayChildNodes(fromFragment, toElement) {\n for (const childNode of fromFragment.childNodes) {\n if (childNode.nodeType === childNode.TEXT_NODE) {\n // Keep the translated text node.\n continue;\n }\n if (childNode.hasAttribute(\"data-l10n-name\")) {\n const sanitized = getNodeForNamedElement(toElement, childNode);\n fromFragment.replaceChild(sanitized, childNode);\n continue;\n }\n if (isElementAllowed(childNode)) {\n const sanitized = createSanitizedElement(childNode);\n fromFragment.replaceChild(sanitized, childNode);\n continue;\n }\n console.warn(`An element of forbidden type \"${childNode.localName}\" was found in ` +\n \"the translation. Only safe text-level elements and elements with \" +\n \"data-l10n-name are allowed.\");\n // If all else fails, replace the element with its text content.\n fromFragment.replaceChild(createTextNodeFromTextContent(childNode), childNode);\n }\n toElement.textContent = \"\";\n toElement.appendChild(fromFragment);\n}\nfunction hasAttribute(attributes, name) {\n if (!attributes) {\n return false;\n }\n for (let attr of attributes) {\n if (attr.name === name) {\n return true;\n }\n }\n return false;\n}\n/**\n * Transplant localizable attributes of an element to another element.\n *\n * Any localizable attributes already set on the target element will be\n * cleared.\n *\n * @param {Element|Object} fromElement - The source of child nodes to overlay.\n * @param {Element} toElement - The target of the overlay.\n * @private\n */\nfunction overlayAttributes(fromElement, toElement) {\n const explicitlyAllowed = toElement.hasAttribute(\"data-l10n-attrs\")\n ? toElement\n .getAttribute(\"data-l10n-attrs\")\n .split(\",\")\n .map(i => i.trim())\n : null;\n // Remove existing localizable attributes if they\n // will not be used in the new translation.\n for (const attr of Array.from(toElement.attributes)) {\n if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) &&\n !hasAttribute(fromElement.attributes, attr.name)) {\n toElement.removeAttribute(attr.name);\n }\n }\n // fromElement might be a {value, attributes} object as returned by\n // Localization.messageFromBundle. In which case attributes may be null to\n // save GC cycles.\n if (!fromElement.attributes) {\n return;\n }\n // Set localizable attributes.\n for (const attr of Array.from(fromElement.attributes)) {\n if (isAttrNameLocalizable(attr.name, toElement, explicitlyAllowed) &&\n toElement.getAttribute(attr.name) !== attr.value) {\n toElement.setAttribute(attr.name, attr.value);\n }\n }\n}\n/**\n * Sanitize a child element created by the translation.\n *\n * Try to find a corresponding child in sourceElement and use it as the base\n * for the sanitization. This will preserve functional attribtues defined on\n * the child element in the source HTML.\n *\n * @param {Element} sourceElement - The source for data-l10n-name lookups.\n * @param {Element} translatedChild - The translated child to be sanitized.\n * @returns {Element}\n * @private\n */\nfunction getNodeForNamedElement(sourceElement, translatedChild) {\n const childName = translatedChild.getAttribute(\"data-l10n-name\");\n const sourceChild = sourceElement.querySelector(`[data-l10n-name=\"${childName}\"]`);\n if (!sourceChild) {\n console.warn(`An element named \"${childName}\" wasn't found in the source.`);\n return createTextNodeFromTextContent(translatedChild);\n }\n if (sourceChild.localName !== translatedChild.localName) {\n console.warn(`An element named \"${childName}\" was found in the translation ` +\n `but its type ${translatedChild.localName} didn't match the ` +\n `element found in the source (${sourceChild.localName}).`);\n return createTextNodeFromTextContent(translatedChild);\n }\n // Remove it from sourceElement so that the translation cannot use\n // the same reference name again.\n sourceElement.removeChild(sourceChild);\n // We can't currently guarantee that a translation won't remove\n // sourceChild from the element completely, which could break the app if\n // it relies on an event handler attached to the sourceChild. Let's make\n // this limitation explicit for now by breaking the identitiy of the\n // sourceChild by cloning it. This will destroy all event handlers\n // attached to sourceChild via addEventListener and via on\n // properties.\n const clone = sourceChild.cloneNode(false);\n return shallowPopulateUsing(translatedChild, clone);\n}\n/**\n * Sanitize an allowed element.\n *\n * Text-level elements allowed in translations may only use safe attributes\n * and will have any nested markup stripped to text content.\n *\n * @param {Element} element - The element to be sanitized.\n * @returns {Element}\n * @private\n */\nfunction createSanitizedElement(element) {\n // Start with an empty element of the same type to remove nested children\n // and non-localizable attributes defined by the translation.\n const clone = element.ownerDocument.createElement(element.localName);\n return shallowPopulateUsing(element, clone);\n}\n/**\n * Convert an element to a text node.\n *\n * @param {Element} element - The element to be sanitized.\n * @returns {Node}\n * @private\n */\nfunction createTextNodeFromTextContent(element) {\n return element.ownerDocument.createTextNode(element.textContent);\n}\n/**\n * Check if element is allowed in the translation.\n *\n * This method is used by the sanitizer when the translation markup contains\n * an element which is not present in the source code.\n *\n * @param {Element} element\n * @returns {boolean}\n * @private\n */\nfunction isElementAllowed(element) {\n const allowed = TEXT_LEVEL_ELEMENTS[element.namespaceURI];\n return allowed && allowed.includes(element.localName);\n}\n/**\n * Check if attribute is allowed for the given element.\n *\n * This method is used by the sanitizer when the translation markup contains\n * DOM attributes, or when the translation has traits which map to DOM\n * attributes.\n *\n * `explicitlyAllowed` can be passed as a list of attributes explicitly\n * allowed on this element.\n *\n * @param {string} name\n * @param {Element} element\n * @param {Array} explicitlyAllowed\n * @returns {boolean}\n * @private\n */\nfunction isAttrNameLocalizable(name, element, explicitlyAllowed = null) {\n if (explicitlyAllowed && explicitlyAllowed.includes(name)) {\n return true;\n }\n const allowed = LOCALIZABLE_ATTRIBUTES[element.namespaceURI];\n if (!allowed) {\n return false;\n }\n const attrName = name.toLowerCase();\n const elemName = element.localName;\n // Is it a globally safe attribute?\n if (allowed.global.includes(attrName)) {\n return true;\n }\n // Are there no allowed attributes for this element?\n if (!allowed[elemName]) {\n return false;\n }\n // Is it allowed on this element?\n if (allowed[elemName].includes(attrName)) {\n return true;\n }\n // Special case for value on HTML inputs with type button, reset, submit\n if (element.namespaceURI === \"http://www.w3.org/1999/xhtml\" &&\n elemName === \"input\" &&\n attrName === \"value\") {\n const type = element.type.toLowerCase();\n if (type === \"submit\" || type === \"button\" || type === \"reset\") {\n return true;\n }\n }\n return false;\n}\n/**\n * Helper to set textContent and localizable attributes on an element.\n *\n * @param {Element} fromElement\n * @param {Element} toElement\n * @returns {Element}\n * @private\n */\nfunction shallowPopulateUsing(fromElement, toElement) {\n toElement.textContent = fromElement.textContent;\n overlayAttributes(fromElement, toElement);\n return toElement;\n}\n","/*\n * Base CachedIterable class.\n */\nexport default class CachedIterable extends Array {\n /**\n * Create a `CachedIterable` instance from an iterable or, if another\n * instance of `CachedIterable` is passed, return it without any\n * modifications.\n *\n * @param {Iterable} iterable\n * @returns {CachedIterable}\n */\n static from(iterable) {\n if (iterable instanceof this) {\n return iterable;\n }\n\n return new this(iterable);\n }\n}\n","import CachedIterable from \"./cached_iterable.mjs\";\n\n/*\n * CachedSyncIterable caches the elements yielded by an iterable.\n *\n * It can be used to iterate over an iterable many times without depleting the\n * iterable.\n */\nexport default class CachedSyncIterable extends CachedIterable {\n /**\n * Create an `CachedSyncIterable` instance.\n *\n * @param {Iterable} iterable\n * @returns {CachedSyncIterable}\n */\n constructor(iterable) {\n super();\n\n if (Symbol.iterator in Object(iterable)) {\n this.iterator = iterable[Symbol.iterator]();\n } else {\n throw new TypeError(\"Argument must implement the iteration protocol.\");\n }\n }\n\n [Symbol.iterator]() {\n const cached = this;\n let cur = 0;\n\n return {\n next() {\n if (cached.length <= cur) {\n cached.push(cached.iterator.next());\n }\n return cached[cur++];\n }\n };\n }\n\n /**\n * This method allows user to consume the next element from the iterator\n * into the cache.\n *\n * @param {number} count - number of elements to consume\n */\n touchNext(count = 1) {\n let idx = 0;\n while (idx++ < count) {\n const last = this[this.length - 1];\n if (last && last.done) {\n break;\n }\n this.push(this.iterator.next());\n }\n // Return the last cached {value, done} object to allow the calling\n // code to decide if it needs to call touchNext again.\n return this[this.length - 1];\n }\n}\n","import CachedIterable from \"./cached_iterable.mjs\";\n\n/*\n * CachedAsyncIterable caches the elements yielded by an async iterable.\n *\n * It can be used to iterate over an iterable many times without depleting the\n * iterable.\n */\nexport default class CachedAsyncIterable extends CachedIterable {\n /**\n * Create an `CachedAsyncIterable` instance.\n *\n * @param {Iterable} iterable\n * @returns {CachedAsyncIterable}\n */\n constructor(iterable) {\n super();\n\n if (Symbol.asyncIterator in Object(iterable)) {\n this.iterator = iterable[Symbol.asyncIterator]();\n } else if (Symbol.iterator in Object(iterable)) {\n this.iterator = iterable[Symbol.iterator]();\n } else {\n throw new TypeError(\"Argument must implement the iteration protocol.\");\n }\n }\n\n /**\n * Asynchronous iterator caching the yielded elements.\n *\n * Elements yielded by the original iterable will be cached and available\n * synchronously. Returns an async generator object implementing the\n * iterator protocol over the elements of the original (async or sync)\n * iterable.\n */\n [Symbol.asyncIterator]() {\n const cached = this;\n let cur = 0;\n\n return {\n async next() {\n if (cached.length <= cur) {\n cached.push(cached.iterator.next());\n }\n return cached[cur++];\n }\n };\n }\n\n /**\n * This method allows user to consume the next element from the iterator\n * into the cache.\n *\n * @param {number} count - number of elements to consume\n */\n async touchNext(count = 1) {\n let idx = 0;\n while (idx++ < count) {\n const last = this[this.length - 1];\n if (last && (await last).done) {\n break;\n }\n this.push(this.iterator.next());\n }\n // Return the last cached {value, done} object to allow the calling\n // code to decide if it needs to call touchNext again.\n return this[this.length - 1];\n }\n}\n","export {default as CachedSyncIterable} from \"./cached_sync_iterable.mjs\";\nexport {default as CachedAsyncIterable} from \"./cached_async_iterable.mjs\";\n","/* eslint no-console: [\"error\", { allow: [\"warn\", \"error\"] }] */\n/* global console */\nimport { CachedAsyncIterable } from \"cached-iterable\";\n/**\n * The `Localization` class is a central high-level API for vanilla\n * JavaScript use of Fluent.\n * It combines language negotiation, FluentBundle and I/O to\n * provide a scriptable API to format translations.\n */\nexport default class Localization {\n /**\n * @param {Array} resourceIds - List of resource IDs\n * @param {Function} generateBundles - Function that returns a\n * generator over FluentBundles\n *\n * @returns {Localization}\n */\n constructor(resourceIds = [], generateBundles) {\n this.resourceIds = resourceIds;\n this.generateBundles = generateBundles;\n this.onChange(true);\n }\n addResourceIds(resourceIds, eager = false) {\n this.resourceIds.push(...resourceIds);\n this.onChange(eager);\n return this.resourceIds.length;\n }\n removeResourceIds(resourceIds) {\n this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r));\n this.onChange();\n return this.resourceIds.length;\n }\n /**\n * Format translations and handle fallback if needed.\n *\n * Format translations for `keys` from `FluentBundle` instances on this\n * DOMLocalization. In case of errors, fetch the next context in the\n * fallback chain.\n *\n * @param {Array} keys - Translation keys to format.\n * @param {Function} method - Formatting function.\n * @returns {Promise>}\n * @private\n */\n async formatWithFallback(keys, method) {\n const translations = [];\n let hasAtLeastOneBundle = false;\n for await (const bundle of this.bundles) {\n hasAtLeastOneBundle = true;\n const missingIds = keysFromBundle(method, bundle, keys, translations);\n if (missingIds.size === 0) {\n break;\n }\n if (typeof console !== \"undefined\") {\n const locale = bundle.locales[0];\n const ids = Array.from(missingIds).join(\", \");\n console.warn(`[fluent] Missing translations in ${locale}: ${ids}`);\n }\n }\n if (!hasAtLeastOneBundle && typeof console !== \"undefined\") {\n // eslint-disable-next-line max-len\n console.warn(`[fluent] Request for keys failed because no resource bundles got generated.\n keys: ${JSON.stringify(keys)}.\n resourceIds: ${JSON.stringify(this.resourceIds)}.`);\n }\n return translations;\n }\n /**\n * Format translations into `{value, attributes}` objects.\n *\n * The fallback logic is the same as in `formatValues`\n * but it returns `{value, attributes}` objects\n * which are suitable for the translation of DOM elements.\n *\n * Returns a Promise resolving to an array of the translation strings.\n *\n * @example\n * ```js\n * docL10n.formatMessages([\n * {id: 'hello', args: { who: 'Mary' }},\n * {id: 'welcome'}\n * ]).then(console.log);\n *\n * // [\n * // { value: 'Hello, Mary!', attributes: null },\n * // {\n * // value: 'Welcome!',\n * // attributes: [ { name: \"title\", value: 'Hello' } ]\n * // }\n * // ]\n * ```\n *\n * @param {Array} keys\n * @returns {Promise>}\n * @private\n */\n formatMessages(keys) {\n return this.formatWithFallback(keys, messageFromBundle);\n }\n /**\n * Retrieve translations corresponding to the passed keys.\n *\n * A generalized version of `DOMLocalization.formatValue`. Keys must\n * be `{id, args}` objects.\n *\n * Returns a Promise resolving to an array of the translation strings.\n *\n * @example\n * ```js\n * docL10n.formatValues([\n * {id: 'hello', args: { who: 'Mary' }},\n * {id: 'hello', args: { who: 'John' }},\n * {id: 'welcome'}\n * ]).then(console.log);\n *\n * // ['Hello, Mary!', 'Hello, John!', 'Welcome!']\n * ```\n *\n * @param {Array} keys\n * @returns {Promise>}\n */\n formatValues(keys) {\n return this.formatWithFallback(keys, valueFromBundle);\n }\n /**\n * Retrieve the translation corresponding to the `id` identifier.\n *\n * If passed, `args` is a simple hash object with a list of variables that\n * will be interpolated in the value of the translation.\n *\n * Returns a Promise resolving to the translation string.\n *\n * Use this sparingly for one-off messages which don't need to be\n * retranslated when the user changes their language preferences, e.g. in\n * notifications.\n *\n * @example\n * ```js\n * docL10n.formatValue(\n * 'hello', { who: 'world' }\n * ).then(console.log);\n *\n * // 'Hello, world!'\n * ```\n *\n * @param {string} id - Identifier of the translation to format\n * @param {Object} [args] - Optional external arguments\n * @returns {Promise}\n */\n async formatValue(id, args) {\n const [val] = await this.formatValues([{ id, args }]);\n return val;\n }\n handleEvent() {\n this.onChange();\n }\n /**\n * This method should be called when there's a reason to believe\n * that language negotiation or available resources changed.\n */\n onChange(eager = false) {\n this.bundles = CachedAsyncIterable.from(this.generateBundles(this.resourceIds));\n if (eager) {\n this.bundles.touchNext(2);\n }\n }\n}\n/**\n * Format the value of a message into a string or `null`.\n *\n * This function is passed as a method to `keysFromBundle` and resolve\n * a value of a single L10n Entity using provided `FluentBundle`.\n *\n * If the message doesn't have a value, return `null`.\n *\n * @param {FluentBundle} bundle\n * @param {Array} errors\n * @param {Object} message\n * @param {Object} args\n * @returns {string|null}\n * @private\n */\nfunction valueFromBundle(bundle, errors, message, args) {\n if (message.value) {\n return bundle.formatPattern(message.value, args, errors);\n }\n return null;\n}\n/**\n * Format all public values of a message into a {value, attributes} object.\n *\n * This function is passed as a method to `keysFromBundle` and resolve\n * a single L10n Entity using provided `FluentBundle`.\n *\n * The function will return an object with a value and attributes of the\n * entity.\n *\n * @param {FluentBundle} bundle\n * @param {Array} errors\n * @param {Object} message\n * @param {Object} args\n * @returns {Object}\n * @private\n */\nfunction messageFromBundle(bundle, errors, message, args) {\n const formatted = {\n value: null,\n attributes: null,\n };\n if (message.value) {\n formatted.value = bundle.formatPattern(message.value, args, errors);\n }\n let attrNames = Object.keys(message.attributes);\n if (attrNames.length > 0) {\n formatted.attributes = new Array(attrNames.length);\n for (let [i, name] of attrNames.entries()) {\n let value = bundle.formatPattern(message.attributes[name], args, errors);\n formatted.attributes[i] = { name, value };\n }\n }\n return formatted;\n}\n/**\n * This function is an inner function for `Localization.formatWithFallback`.\n *\n * It takes a `FluentBundle`, list of l10n-ids and a method to be used for\n * key resolution (either `valueFromBundle` or `messageFromBundle`) and\n * optionally a value returned from `keysFromBundle` executed against\n * another `FluentBundle`.\n *\n * The idea here is that if the previous `FluentBundle` did not resolve\n * all keys, we're calling this function with the next context to resolve\n * the remaining ones.\n *\n * In the function, we loop over `keys` and check if we have the `prev`\n * passed and if it has an error entry for the position we're in.\n *\n * If it doesn't, it means that we have a good translation for this key and\n * we return it. If it does, we'll try to resolve the key using the passed\n * `FluentBundle`.\n *\n * In the end, we fill the translations array, and return the Set with\n * missing ids.\n *\n * See `Localization.formatWithFallback` for more info on how this is used.\n *\n * @param {Function} method\n * @param {FluentBundle} bundle\n * @param {Array} keys\n * @param {{Array<{value: string, attributes: Object}>}} translations\n *\n * @returns {Set}\n * @private\n */\nfunction keysFromBundle(method, bundle, keys, translations) {\n const messageErrors = [];\n const missingIds = new Set();\n keys.forEach(({ id, args }, i) => {\n if (translations[i] !== undefined) {\n return;\n }\n let message = bundle.getMessage(id);\n if (message) {\n messageErrors.length = 0;\n translations[i] = method(bundle, messageErrors, message, args);\n if (messageErrors.length > 0 && typeof console !== \"undefined\") {\n const locale = bundle.locales[0];\n const errors = messageErrors.join(\", \");\n // eslint-disable-next-line max-len\n console.warn(`[fluent][resolver] errors in ${locale}/${id}: ${errors}.`);\n }\n }\n else {\n missingIds.add(id);\n }\n });\n return missingIds;\n}\n","import translateElement from \"./overlay.js\";\nimport Localization from \"./localization.js\";\nconst L10NID_ATTR_NAME = \"data-l10n-id\";\nconst L10NARGS_ATTR_NAME = \"data-l10n-args\";\nconst L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`;\n/**\n * The `DOMLocalization` class is responsible for fetching resources and\n * formatting translations.\n *\n * It implements the fallback strategy in case of errors encountered during the\n * formatting of translations and methods for observing DOM\n * trees with a `MutationObserver`.\n */\nexport default class DOMLocalization extends Localization {\n /**\n * @param {Array} resourceIds - List of resource IDs\n * @param {Function} generateBundles - Function that returns a\n * generator over FluentBundles\n * @returns {DOMLocalization}\n */\n constructor(resourceIds, generateBundles) {\n super(resourceIds, generateBundles);\n // A Set of DOM trees observed by the `MutationObserver`.\n this.roots = new Set();\n // requestAnimationFrame handler.\n this.pendingrAF = null;\n // list of elements pending for translation.\n this.pendingElements = new Set();\n this.windowElement = null;\n this.mutationObserver = null;\n this.observerConfig = {\n attributes: true,\n characterData: false,\n childList: true,\n subtree: true,\n attributeFilter: [L10NID_ATTR_NAME, L10NARGS_ATTR_NAME],\n };\n }\n onChange(eager = false) {\n super.onChange(eager);\n if (this.roots) {\n this.translateRoots();\n }\n }\n /**\n * Set the `data-l10n-id` and `data-l10n-args` attributes on DOM elements.\n * FluentDOM makes use of mutation observers to detect changes\n * to `data-l10n-*` attributes and translate elements asynchronously.\n * `setAttributes` is a convenience method which allows to translate\n * DOM elements declaratively.\n *\n * You should always prefer to use `data-l10n-id` on elements (statically in\n * HTML or dynamically via `setAttributes`) over manually retrieving\n * translations with `format`. The use of attributes ensures that the\n * elements can be retranslated when the user changes their language\n * preferences.\n *\n * ```javascript\n * localization.setAttributes(\n * document.querySelector('#welcome'), 'hello', { who: 'world' }\n * );\n * ```\n *\n * This will set the following attributes on the `#welcome` element.\n * The MutationObserver will pick up this change and will localize the element\n * asynchronously.\n *\n * ```html\n *

\n *

\n * ```\n *\n * @param {Element} element - Element to set attributes on\n * @param {string} id - l10n-id string\n * @param {Object} args - KVP list of l10n arguments\n * @returns {Element}\n */\n setAttributes(element, id, args) {\n element.setAttribute(L10NID_ATTR_NAME, id);\n if (args) {\n element.setAttribute(L10NARGS_ATTR_NAME, JSON.stringify(args));\n }\n else {\n element.removeAttribute(L10NARGS_ATTR_NAME);\n }\n return element;\n }\n /**\n * Get the `data-l10n-*` attributes from DOM elements.\n *\n * ```javascript\n * localization.getAttributes(\n * document.querySelector('#welcome')\n * );\n * // -> { id: 'hello', args: { who: 'world' } }\n * ```\n *\n * @param {Element} element - HTML element\n * @returns {{id: string, args: Object}}\n */\n getAttributes(element) {\n return {\n id: element.getAttribute(L10NID_ATTR_NAME),\n args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null),\n };\n }\n /**\n * Add `newRoot` to the list of roots managed by this `DOMLocalization`.\n *\n * Additionally, if this `DOMLocalization` has an observer, start observing\n * `newRoot` in order to translate mutations in it.\n *\n * @param {Element} newRoot - Root to observe.\n */\n connectRoot(newRoot) {\n for (const root of this.roots) {\n if (root === newRoot ||\n root.contains(newRoot) ||\n newRoot.contains(root)) {\n throw new Error(\"Cannot add a root that overlaps with existing root.\");\n }\n }\n if (this.windowElement) {\n if (this.windowElement !== newRoot.ownerDocument.defaultView) {\n throw new Error(`Cannot connect a root:\n DOMLocalization already has a root from a different window.`);\n }\n }\n else {\n this.windowElement = newRoot.ownerDocument.defaultView;\n this.mutationObserver = new this.windowElement.MutationObserver(mutations => this.translateMutations(mutations));\n }\n this.roots.add(newRoot);\n this.mutationObserver.observe(newRoot, this.observerConfig);\n }\n /**\n * Remove `root` from the list of roots managed by this `DOMLocalization`.\n *\n * Additionally, if this `DOMLocalization` has an observer, stop observing\n * `root`.\n *\n * Returns `true` if the root was the last one managed by this\n * `DOMLocalization`.\n *\n * @param {Element} root - Root to disconnect.\n * @returns {boolean}\n */\n disconnectRoot(root) {\n this.roots.delete(root);\n // Pause the mutation observer to stop observing `root`.\n this.pauseObserving();\n if (this.roots.size === 0) {\n this.mutationObserver = null;\n this.windowElement = null;\n this.pendingrAF = null;\n this.pendingElements.clear();\n return true;\n }\n // Resume observing all other roots.\n this.resumeObserving();\n return false;\n }\n /**\n * Translate all roots associated with this `DOMLocalization`.\n *\n * @returns {Promise}\n */\n translateRoots() {\n const roots = Array.from(this.roots);\n return Promise.all(roots.map(root => this.translateFragment(root)));\n }\n /**\n * Pauses the `MutationObserver`.\n *\n * @private\n */\n pauseObserving() {\n if (!this.mutationObserver) {\n return;\n }\n this.translateMutations(this.mutationObserver.takeRecords());\n this.mutationObserver.disconnect();\n }\n /**\n * Resumes the `MutationObserver`.\n *\n * @private\n */\n resumeObserving() {\n if (!this.mutationObserver) {\n return;\n }\n for (const root of this.roots) {\n this.mutationObserver.observe(root, this.observerConfig);\n }\n }\n /**\n * Translate mutations detected by the `MutationObserver`.\n *\n * @private\n */\n translateMutations(mutations) {\n for (const mutation of mutations) {\n switch (mutation.type) {\n case \"attributes\":\n if (mutation.target.hasAttribute(\"data-l10n-id\")) {\n this.pendingElements.add(mutation.target);\n }\n break;\n case \"childList\":\n for (const addedNode of mutation.addedNodes) {\n if (addedNode.nodeType === addedNode.ELEMENT_NODE) {\n if (addedNode.childElementCount) {\n for (const element of this.getTranslatables(addedNode)) {\n this.pendingElements.add(element);\n }\n }\n else if (addedNode.hasAttribute(L10NID_ATTR_NAME)) {\n this.pendingElements.add(addedNode);\n }\n }\n }\n break;\n }\n }\n // This fragment allows us to coalesce all pending translations\n // into a single requestAnimationFrame.\n if (this.pendingElements.size > 0) {\n if (this.pendingrAF === null) {\n this.pendingrAF = this.windowElement.requestAnimationFrame(() => {\n this.translateElements(Array.from(this.pendingElements));\n this.pendingElements.clear();\n this.pendingrAF = null;\n });\n }\n }\n }\n /**\n * Translate a DOM element or fragment asynchronously using this\n * `DOMLocalization` object.\n *\n * Manually trigger the translation (or re-translation) of a DOM fragment.\n * Use the `data-l10n-id` and `data-l10n-args` attributes to mark up the DOM\n * with information about which translations to use.\n *\n * Returns a `Promise` that gets resolved once the translation is complete.\n *\n * @param {DOMFragment} frag - Element or DocumentFragment to be translated\n * @returns {Promise}\n */\n translateFragment(frag) {\n return this.translateElements(this.getTranslatables(frag));\n }\n /**\n * Translate a list of DOM elements asynchronously using this\n * `DOMLocalization` object.\n *\n * Manually trigger the translation (or re-translation) of a list of elements.\n * Use the `data-l10n-id` and `data-l10n-args` attributes to mark up the DOM\n * with information about which translations to use.\n *\n * Returns a `Promise` that gets resolved once the translation is complete.\n *\n * @param {Array} elements - List of elements to be translated\n * @returns {Promise}\n */\n async translateElements(elements) {\n if (!elements.length) {\n return undefined;\n }\n const keys = elements.map(this.getKeysForElement);\n const translations = await this.formatMessages(keys);\n return this.applyTranslations(elements, translations);\n }\n /**\n * Applies translations onto elements.\n *\n * @param {Array} elements\n * @param {Array} translations\n * @private\n */\n applyTranslations(elements, translations) {\n this.pauseObserving();\n for (let i = 0; i < elements.length; i++) {\n if (translations[i] !== undefined) {\n translateElement(elements[i], translations[i]);\n }\n }\n this.resumeObserving();\n }\n /**\n * Collects all translatable child elements of the element.\n *\n * @param {Element} element\n * @returns {Array}\n * @private\n */\n getTranslatables(element) {\n const nodes = Array.from(element.querySelectorAll(L10N_ELEMENT_QUERY));\n if (typeof element.hasAttribute === \"function\" &&\n element.hasAttribute(L10NID_ATTR_NAME)) {\n nodes.push(element);\n }\n return nodes;\n }\n /**\n * Get the `data-l10n-*` attributes from DOM elements as a two-element\n * array.\n *\n * @param {Element} element\n * @returns {Object}\n * @private\n */\n getKeysForElement(element) {\n return {\n id: element.getAttribute(L10NID_ATTR_NAME),\n args: JSON.parse(element.getAttribute(L10NARGS_ATTR_NAME) || null),\n };\n }\n}\n","export { default as DOMLocalization } from \"./dom_localization.js\";\nexport { default as Localization } from \"./localization.js\";\n","/* Copyright 2023 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DOMSVGFactory, shadow } from \"pdfjs-lib\";\n\nclass AltTextManager {\n #boundUpdateUIState = this.#updateUIState.bind(this);\n\n #boundSetPosition = this.#setPosition.bind(this);\n\n #boundOnClick = this.#onClick.bind(this);\n\n #currentEditor = null;\n\n #cancelButton;\n\n #dialog;\n\n #eventBus;\n\n #hasUsedPointer = false;\n\n #optionDescription;\n\n #optionDecorative;\n\n #overlayManager;\n\n #saveButton;\n\n #textarea;\n\n #uiManager;\n\n #previousAltText = null;\n\n #svgElement = null;\n\n #rectElement = null;\n\n #container;\n\n #telemetryData = null;\n\n constructor(\n {\n dialog,\n optionDescription,\n optionDecorative,\n textarea,\n cancelButton,\n saveButton,\n },\n container,\n overlayManager,\n eventBus\n ) {\n this.#dialog = dialog;\n this.#optionDescription = optionDescription;\n this.#optionDecorative = optionDecorative;\n this.#textarea = textarea;\n this.#cancelButton = cancelButton;\n this.#saveButton = saveButton;\n this.#overlayManager = overlayManager;\n this.#eventBus = eventBus;\n this.#container = container;\n\n dialog.addEventListener(\"close\", this.#close.bind(this));\n dialog.addEventListener(\"contextmenu\", event => {\n if (event.target !== this.#textarea) {\n event.preventDefault();\n }\n });\n cancelButton.addEventListener(\"click\", this.#finish.bind(this));\n saveButton.addEventListener(\"click\", this.#save.bind(this));\n optionDescription.addEventListener(\"change\", this.#boundUpdateUIState);\n optionDecorative.addEventListener(\"change\", this.#boundUpdateUIState);\n\n this.#overlayManager.register(dialog);\n }\n\n get _elements() {\n return shadow(this, \"_elements\", [\n this.#optionDescription,\n this.#optionDecorative,\n this.#textarea,\n this.#saveButton,\n this.#cancelButton,\n ]);\n }\n\n #createSVGElement() {\n if (this.#svgElement) {\n return;\n }\n\n // We create a mask to add to the dialog backdrop: the idea is to have a\n // darken background everywhere except on the editor to clearly see the\n // picture to describe.\n\n const svgFactory = new DOMSVGFactory();\n const svg = (this.#svgElement = svgFactory.createElement(\"svg\"));\n svg.setAttribute(\"width\", \"0\");\n svg.setAttribute(\"height\", \"0\");\n const defs = svgFactory.createElement(\"defs\");\n svg.append(defs);\n const mask = svgFactory.createElement(\"mask\");\n defs.append(mask);\n mask.setAttribute(\"id\", \"alttext-manager-mask\");\n mask.setAttribute(\"maskContentUnits\", \"objectBoundingBox\");\n let rect = svgFactory.createElement(\"rect\");\n mask.append(rect);\n rect.setAttribute(\"fill\", \"white\");\n rect.setAttribute(\"width\", \"1\");\n rect.setAttribute(\"height\", \"1\");\n rect.setAttribute(\"x\", \"0\");\n rect.setAttribute(\"y\", \"0\");\n\n rect = this.#rectElement = svgFactory.createElement(\"rect\");\n mask.append(rect);\n rect.setAttribute(\"fill\", \"black\");\n this.#dialog.append(svg);\n }\n\n async editAltText(uiManager, editor) {\n if (this.#currentEditor || !editor) {\n return;\n }\n\n this.#createSVGElement();\n\n this.#hasUsedPointer = false;\n for (const element of this._elements) {\n element.addEventListener(\"click\", this.#boundOnClick);\n }\n\n const { altText, decorative } = editor.altTextData;\n if (decorative === true) {\n this.#optionDecorative.checked = true;\n this.#optionDescription.checked = false;\n } else {\n this.#optionDecorative.checked = false;\n this.#optionDescription.checked = true;\n }\n this.#previousAltText = this.#textarea.value = altText?.trim() || \"\";\n this.#updateUIState();\n\n this.#currentEditor = editor;\n this.#uiManager = uiManager;\n this.#uiManager.removeEditListeners();\n this.#eventBus._on(\"resize\", this.#boundSetPosition);\n\n try {\n await this.#overlayManager.open(this.#dialog);\n this.#setPosition();\n } catch (ex) {\n this.#close();\n throw ex;\n }\n }\n\n #setPosition() {\n if (!this.#currentEditor) {\n return;\n }\n const dialog = this.#dialog;\n const { style } = dialog;\n const {\n x: containerX,\n y: containerY,\n width: containerW,\n height: containerH,\n } = this.#container.getBoundingClientRect();\n const { innerWidth: windowW, innerHeight: windowH } = window;\n const { width: dialogW, height: dialogH } = dialog.getBoundingClientRect();\n const { x, y, width, height } = this.#currentEditor.getClientDimensions();\n const MARGIN = 10;\n const isLTR = this.#uiManager.direction === \"ltr\";\n\n const xs = Math.max(x, containerX);\n const xe = Math.min(x + width, containerX + containerW);\n const ys = Math.max(y, containerY);\n const ye = Math.min(y + height, containerY + containerH);\n this.#rectElement.setAttribute(\"width\", `${(xe - xs) / windowW}`);\n this.#rectElement.setAttribute(\"height\", `${(ye - ys) / windowH}`);\n this.#rectElement.setAttribute(\"x\", `${xs / windowW}`);\n this.#rectElement.setAttribute(\"y\", `${ys / windowH}`);\n\n let left = null;\n let top = Math.max(y, 0);\n top += Math.min(windowH - (top + dialogH), 0);\n\n if (isLTR) {\n // Prefer to position the dialog \"after\" (so on the right) the editor.\n if (x + width + MARGIN + dialogW < windowW) {\n left = x + width + MARGIN;\n } else if (x > dialogW + MARGIN) {\n left = x - dialogW - MARGIN;\n }\n } else if (x > dialogW + MARGIN) {\n left = x - dialogW - MARGIN;\n } else if (x + width + MARGIN + dialogW < windowW) {\n left = x + width + MARGIN;\n }\n\n if (left === null) {\n top = null;\n left = Math.max(x, 0);\n left += Math.min(windowW - (left + dialogW), 0);\n if (y > dialogH + MARGIN) {\n top = y - dialogH - MARGIN;\n } else if (y + height + MARGIN + dialogH < windowH) {\n top = y + height + MARGIN;\n }\n }\n\n if (top !== null) {\n dialog.classList.add(\"positioned\");\n if (isLTR) {\n style.left = `${left}px`;\n } else {\n style.right = `${windowW - left - dialogW}px`;\n }\n style.top = `${top}px`;\n } else {\n dialog.classList.remove(\"positioned\");\n style.left = \"\";\n style.top = \"\";\n }\n }\n\n #finish() {\n if (this.#overlayManager.active === this.#dialog) {\n this.#overlayManager.close(this.#dialog);\n }\n }\n\n #close() {\n this.#eventBus.dispatch(\"reporttelemetry\", {\n source: this,\n details: {\n type: \"editing\",\n subtype: this.#currentEditor.editorType,\n data: this.#telemetryData || {\n action: \"alt_text_cancel\",\n alt_text_keyboard: !this.#hasUsedPointer,\n },\n },\n });\n this.#telemetryData = null;\n\n this.#removeOnClickListeners();\n this.#uiManager?.addEditListeners();\n this.#eventBus._off(\"resize\", this.#boundSetPosition);\n this.#currentEditor.altTextFinish();\n this.#currentEditor = null;\n this.#uiManager = null;\n }\n\n #updateUIState() {\n this.#textarea.disabled = this.#optionDecorative.checked;\n }\n\n #save() {\n const altText = this.#textarea.value.trim();\n const decorative = this.#optionDecorative.checked;\n this.#currentEditor.altTextData = {\n altText,\n decorative,\n };\n this.#telemetryData = {\n action: \"alt_text_save\",\n alt_text_description: !!altText,\n alt_text_edit:\n !!this.#previousAltText && this.#previousAltText !== altText,\n alt_text_decorative: decorative,\n alt_text_keyboard: !this.#hasUsedPointer,\n };\n this.#finish();\n }\n\n #onClick(evt) {\n if (evt.detail === 0) {\n return; // The keyboard was used.\n }\n this.#hasUsedPointer = true;\n this.#removeOnClickListeners();\n }\n\n #removeOnClickListeners() {\n for (const element of this._elements) {\n element.removeEventListener(\"click\", this.#boundOnClick);\n }\n }\n\n destroy() {\n this.#uiManager = null; // Avoid re-adding the edit listeners.\n this.#finish();\n this.#svgElement?.remove();\n this.#svgElement = this.#rectElement = null;\n }\n}\n\nexport { AltTextManager };\n","/* Copyright 2022 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** @typedef {import(\"../src/display/api\").PDFPageProxy} PDFPageProxy */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"../src/display/display_utils\").PageViewport} PageViewport */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"../src/display/editor/tools.js\").AnnotationEditorUIManager} AnnotationEditorUIManager */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"./text_accessibility.js\").TextAccessibilityManager} TextAccessibilityManager */\n/** @typedef {import(\"./interfaces\").IL10n} IL10n */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"../src/display/annotation_layer.js\").AnnotationLayer} AnnotationLayer */\n\nimport { AnnotationEditorLayer } from \"pdfjs-lib\";\nimport { NullL10n } from \"web-l10n_utils\";\n\n/**\n * @typedef {Object} AnnotationEditorLayerBuilderOptions\n * @property {AnnotationEditorUIManager} [uiManager]\n * @property {HTMLDivElement} pageDiv\n * @property {PDFPageProxy} pdfPage\n * @property {IL10n} [l10n]\n * @property {TextAccessibilityManager} [accessibilityManager]\n * @property {AnnotationLayer} [annotationLayer]\n * @property {TextLayer} [textLayer]\n * @property {DrawLayer} [drawLayer]\n */\n\nclass AnnotationEditorLayerBuilder {\n #annotationLayer = null;\n\n #drawLayer = null;\n\n #textLayer = null;\n\n #uiManager;\n\n /**\n * @param {AnnotationEditorLayerBuilderOptions} options\n */\n constructor(options) {\n this.pageDiv = options.pageDiv;\n this.pdfPage = options.pdfPage;\n this.accessibilityManager = options.accessibilityManager;\n this.l10n = options.l10n || NullL10n;\n this.annotationEditorLayer = null;\n this.div = null;\n this._cancelled = false;\n this.#uiManager = options.uiManager;\n this.#annotationLayer = options.annotationLayer || null;\n this.#textLayer = options.textLayer || null;\n this.#drawLayer = options.drawLayer || null;\n }\n\n /**\n * @param {PageViewport} viewport\n * @param {string} intent (default value is 'display')\n */\n async render(viewport, intent = \"display\") {\n if (intent !== \"display\") {\n return;\n }\n\n if (this._cancelled) {\n return;\n }\n\n const clonedViewport = viewport.clone({ dontFlip: true });\n if (this.div) {\n this.annotationEditorLayer.update({ viewport: clonedViewport });\n this.show();\n return;\n }\n\n // Create an AnnotationEditor layer div\n const div = (this.div = document.createElement(\"div\"));\n div.className = \"annotationEditorLayer\";\n div.tabIndex = 0;\n div.hidden = true;\n div.dir = this.#uiManager.direction;\n this.pageDiv.append(div);\n\n this.annotationEditorLayer = new AnnotationEditorLayer({\n uiManager: this.#uiManager,\n div,\n accessibilityManager: this.accessibilityManager,\n pageIndex: this.pdfPage.pageNumber - 1,\n l10n: this.l10n,\n viewport: clonedViewport,\n annotationLayer: this.#annotationLayer,\n textLayer: this.#textLayer,\n drawLayer: this.#drawLayer,\n });\n\n const parameters = {\n viewport: clonedViewport,\n div,\n annotations: null,\n intent,\n };\n\n this.annotationEditorLayer.render(parameters);\n this.show();\n }\n\n cancel() {\n this._cancelled = true;\n\n if (!this.div) {\n return;\n }\n this.pageDiv = null;\n this.annotationEditorLayer.destroy();\n this.div.remove();\n }\n\n hide() {\n if (!this.div) {\n return;\n }\n this.div.hidden = true;\n }\n\n show() {\n if (!this.div || this.annotationEditorLayer.isEmpty) {\n return;\n }\n this.div.hidden = false;\n }\n}\n\nexport { AnnotationEditorLayerBuilder };\n","/* Copyright 2022 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AnnotationEditorParamsType } from \"pdfjs-lib\";\n\nclass AnnotationEditorParams {\n /**\n * @param {AnnotationEditorParamsOptions} options\n * @param {EventBus} eventBus\n */\n constructor(options, eventBus) {\n this.eventBus = eventBus;\n this.#bindListeners(options);\n }\n\n #bindListeners({\n editorFreeTextFontSize,\n editorFreeTextColor,\n editorInkColor,\n editorInkThickness,\n editorInkOpacity,\n editorStampAddImage,\n }) {\n const dispatchEvent = (typeStr, value) => {\n this.eventBus.dispatch(\"switchannotationeditorparams\", {\n source: this,\n type: AnnotationEditorParamsType[typeStr],\n value,\n });\n };\n editorFreeTextFontSize.addEventListener(\"input\", function () {\n dispatchEvent(\"FREETEXT_SIZE\", this.valueAsNumber);\n });\n editorFreeTextColor.addEventListener(\"input\", function () {\n dispatchEvent(\"FREETEXT_COLOR\", this.value);\n });\n editorInkColor.addEventListener(\"input\", function () {\n dispatchEvent(\"INK_COLOR\", this.value);\n });\n editorInkThickness.addEventListener(\"input\", function () {\n dispatchEvent(\"INK_THICKNESS\", this.valueAsNumber);\n });\n editorInkOpacity.addEventListener(\"input\", function () {\n dispatchEvent(\"INK_OPACITY\", this.valueAsNumber);\n });\n editorStampAddImage.addEventListener(\"click\", () => {\n dispatchEvent(\"CREATE\");\n });\n\n this.eventBus._on(\"annotationeditorparamschanged\", evt => {\n for (const [type, value] of evt.details) {\n switch (type) {\n case AnnotationEditorParamsType.FREETEXT_SIZE:\n editorFreeTextFontSize.value = value;\n break;\n case AnnotationEditorParamsType.FREETEXT_COLOR:\n editorFreeTextColor.value = value;\n break;\n case AnnotationEditorParamsType.INK_COLOR:\n editorInkColor.value = value;\n break;\n case AnnotationEditorParamsType.INK_THICKNESS:\n editorInkThickness.value = value;\n break;\n case AnnotationEditorParamsType.INK_OPACITY:\n editorInkOpacity.value = value;\n break;\n }\n }\n });\n }\n}\n\nexport { AnnotationEditorParams };\n","/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** @typedef {import(\"../src/display/api\").PDFPageProxy} PDFPageProxy */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"../src/display/display_utils\").PageViewport} PageViewport */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"../src/display/annotation_storage\").AnnotationStorage} AnnotationStorage */\n/** @typedef {import(\"./interfaces\").IDownloadManager} IDownloadManager */\n/** @typedef {import(\"./interfaces\").IPDFLinkService} IPDFLinkService */\n// eslint-disable-next-line max-len\n/** @typedef {import(\"./text_accessibility.js\").TextAccessibilityManager} TextAccessibilityManager */\n\nimport { AnnotationLayer } from \"pdfjs-lib\";\nimport { PresentationModeState } from \"./ui_utils.js\";\n\n/**\n * @typedef {Object} AnnotationLayerBuilderOptions\n * @property {HTMLDivElement} pageDiv\n * @property {PDFPageProxy} pdfPage\n * @property {AnnotationStorage} [annotationStorage]\n * @property {string} [imageResourcesPath] - Path for image resources, mainly\n * for annotation icons. Include trailing slash.\n * @property {boolean} renderForms\n * @property {IPDFLinkService} linkService\n * @property {IDownloadManager} [downloadManager]\n * @property {boolean} [enableScripting]\n * @property {Promise} [hasJSActionsPromise]\n * @property {Promise> | null>}\n * [fieldObjectsPromise]\n * @property {Map} [annotationCanvasMap]\n * @property {TextAccessibilityManager} [accessibilityManager]\n */\n\nclass AnnotationLayerBuilder {\n #onPresentationModeChanged = null;\n\n /**\n * @param {AnnotationLayerBuilderOptions} options\n */\n constructor({\n pageDiv,\n pdfPage,\n linkService,\n downloadManager,\n annotationStorage = null,\n imageResourcesPath = \"\",\n renderForms = true,\n enableScripting = false,\n hasJSActionsPromise = null,\n fieldObjectsPromise = null,\n annotationCanvasMap = null,\n accessibilityManager = null,\n }) {\n this.pageDiv = pageDiv;\n this.pdfPage = pdfPage;\n this.linkService = linkService;\n this.downloadManager = downloadManager;\n this.imageResourcesPath = imageResourcesPath;\n this.renderForms = renderForms;\n this.annotationStorage = annotationStorage;\n this.enableScripting = enableScripting;\n this._hasJSActionsPromise = hasJSActionsPromise || Promise.resolve(false);\n this._fieldObjectsPromise = fieldObjectsPromise || Promise.resolve(null);\n this._annotationCanvasMap = annotationCanvasMap;\n this._accessibilityManager = accessibilityManager;\n\n this.annotationLayer = null;\n this.div = null;\n this._cancelled = false;\n this._eventBus = linkService.eventBus;\n }\n\n /**\n * @param {PageViewport} viewport\n * @param {string} intent (default value is 'display')\n * @returns {Promise} A promise that is resolved when rendering of the\n * annotations is complete.\n */\n async render(viewport, intent = \"display\") {\n if (this.div) {\n if (this._cancelled || !this.annotationLayer) {\n return;\n }\n // If an annotationLayer already exists, refresh its children's\n // transformation matrices.\n this.annotationLayer.update({\n viewport: viewport.clone({ dontFlip: true }),\n });\n return;\n }\n\n const [annotations, hasJSActions, fieldObjects] = await Promise.all([\n this.pdfPage.getAnnotations({ intent }),\n this._hasJSActionsPromise,\n this._fieldObjectsPromise,\n ]);\n if (this._cancelled) {\n return;\n }\n\n // Create an annotation layer div and render the annotations\n // if there is at least one annotation.\n const div = (this.div = document.createElement(\"div\"));\n div.className = \"annotationLayer\";\n this.pageDiv.append(div);\n\n if (annotations.length === 0) {\n this.hide();\n return;\n }\n\n this.annotationLayer = new AnnotationLayer({\n div,\n accessibilityManager: this._accessibilityManager,\n annotationCanvasMap: this._annotationCanvasMap,\n page: this.pdfPage,\n viewport: viewport.clone({ dontFlip: true }),\n });\n\n await this.annotationLayer.render({\n annotations,\n imageResourcesPath: this.imageResourcesPath,\n renderForms: this.renderForms,\n linkService: this.linkService,\n downloadManager: this.downloadManager,\n annotationStorage: this.annotationStorage,\n enableScripting: this.enableScripting,\n hasJSActions,\n fieldObjects,\n });\n\n // Ensure that interactive form elements in the annotationLayer are\n // disabled while PresentationMode is active (see issue 12232).\n if (this.linkService.isInPresentationMode) {\n this.#updatePresentationModeState(PresentationModeState.FULLSCREEN);\n }\n if (!this.#onPresentationModeChanged) {\n this.#onPresentationModeChanged = evt => {\n this.#updatePresentationModeState(evt.state);\n };\n this._eventBus?._on(\n \"presentationmodechanged\",\n this.#onPresentationModeChanged\n );\n }\n }\n\n cancel() {\n this._cancelled = true;\n\n if (this.#onPresentationModeChanged) {\n this._eventBus?._off(\n \"presentationmodechanged\",\n this.#onPresentationModeChanged\n );\n this.#onPresentationModeChanged = null;\n }\n }\n\n hide() {\n if (!this.div) {\n return;\n }\n this.div.hidden = true;\n }\n\n #updatePresentationModeState(state) {\n if (!this.div) {\n return;\n }\n let disableFormElements = false;\n\n switch (state) {\n case PresentationModeState.FULLSCREEN:\n disableFormElements = true;\n break;\n case PresentationModeState.NORMAL:\n break;\n default:\n return;\n }\n for (const section of this.div.childNodes) {\n if (section.hasAttribute(\"data-internal-link\")) {\n continue;\n }\n section.inert = disableFormElements;\n }\n }\n}\n\nexport { AnnotationLayerBuilder };\n","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n animationStarted,\n apiPageLayoutToViewerModes,\n apiPageModeToSidebarView,\n AutoPrintRegExp,\n CursorTool,\n DEFAULT_SCALE_VALUE,\n getActiveOrFocusedElement,\n isValidRotation,\n isValidScrollMode,\n isValidSpreadMode,\n normalizeWheelEventDirection,\n parseQueryString,\n ProgressBar,\n RenderingStates,\n ScrollMode,\n SidebarView,\n SpreadMode,\n TextLayerMode,\n} from \"./ui_utils.js\";\nimport {\n AnnotationEditorType,\n build,\n FeatureTest,\n getDocument,\n getFilenameFromUrl,\n getPdfFilenameFromUrl,\n GlobalWorkerOptions,\n InvalidPDFException,\n isDataScheme,\n isPdfFile,\n MissingPDFException,\n PDFWorker,\n PromiseCapability,\n shadow,\n UnexpectedResponseException,\n version,\n} from \"pdfjs-lib\";\nimport { AppOptions, OptionKind } from \"./app_options.js\";\nimport { AutomationEventBus, EventBus } from \"./event_utils.js\";\nimport { LinkTarget, PDFLinkService } from \"./pdf_link_service.js\";\nimport { AltTextManager } from \"web-alt_text_manager\";\nimport { AnnotationEditorParams } from \"web-annotation_editor_params\";\nimport { OverlayManager } from \"./overlay_manager.js\";\nimport { PasswordPrompt } from \"./password_prompt.js\";\nimport { PDFAttachmentViewer } from \"web-pdf_attachment_viewer\";\nimport { PDFCursorTools } from \"web-pdf_cursor_tools\";\nimport { PDFDocumentProperties } from \"web-pdf_document_properties\";\nimport { PDFFindBar } from \"web-pdf_find_bar\";\nimport { PDFFindController } from \"./pdf_find_controller.js\";\nimport { PDFHistory } from \"./pdf_history.js\";\nimport { PDFLayerViewer } from \"web-pdf_layer_viewer\";\nimport { PDFOutlineViewer } from \"web-pdf_outline_viewer\";\nimport { PDFPresentationMode } from \"web-pdf_presentation_mode\";\nimport { PDFRenderingQueue } from \"./pdf_rendering_queue.js\";\nimport { PDFScriptingManager } from \"./pdf_scripting_manager.js\";\nimport { PDFSidebar } from \"web-pdf_sidebar\";\nimport { PDFThumbnailViewer } from \"web-pdf_thumbnail_viewer\";\nimport { PDFViewer } from \"./pdf_viewer.js\";\nimport { SecondaryToolbar } from \"web-secondary_toolbar\";\nimport { Toolbar } from \"web-toolbar\";\nimport { ViewHistory } from \"./view_history.js\";\n\nconst FORCE_PAGES_LOADED_TIMEOUT = 10000; // ms\nconst WHEEL_ZOOM_DISABLED_TIMEOUT = 1000; // ms\n\nconst ViewOnLoad = {\n UNKNOWN: -1,\n PREVIOUS: 0, // Default value.\n INITIAL: 1,\n};\n\nclass DefaultExternalServices {\n constructor() {\n throw new Error(\"Cannot initialize DefaultExternalServices.\");\n }\n\n static updateFindControlState(data) {}\n\n static updateFindMatchesCount(data) {}\n\n static initPassiveLoading(callbacks) {}\n\n static reportTelemetry(data) {}\n\n static createDownloadManager() {\n throw new Error(\"Not implemented: createDownloadManager\");\n }\n\n static createPreferences() {\n throw new Error(\"Not implemented: createPreferences\");\n }\n\n static async createL10n() {\n throw new Error(\"Not implemented: createL10n\");\n }\n\n static createScripting() {\n throw new Error(\"Not implemented: createScripting\");\n }\n\n static updateEditorStates(data) {\n throw new Error(\"Not implemented: updateEditorStates\");\n }\n\n static getNimbusExperimentData() {\n return shadow(this, \"getNimbusExperimentData\", Promise.resolve(null));\n }\n}\n\nconst PDFViewerApplication = {\n initialBookmark: document.location.hash.substring(1),\n _initializedCapability: new PromiseCapability(),\n appConfig: null,\n pdfDocument: null,\n pdfLoadingTask: null,\n printService: null,\n /** @type {PDFViewer} */\n pdfViewer: null,\n /** @type {PDFThumbnailViewer} */\n pdfThumbnailViewer: null,\n /** @type {PDFRenderingQueue} */\n pdfRenderingQueue: null,\n /** @type {PDFPresentationMode} */\n pdfPresentationMode: null,\n /** @type {PDFDocumentProperties} */\n pdfDocumentProperties: null,\n /** @type {PDFLinkService} */\n pdfLinkService: null,\n /** @type {PDFHistory} */\n pdfHistory: null,\n /** @type {PDFSidebar} */\n pdfSidebar: null,\n /** @type {PDFOutlineViewer} */\n pdfOutlineViewer: null,\n /** @type {PDFAttachmentViewer} */\n pdfAttachmentViewer: null,\n /** @type {PDFLayerViewer} */\n pdfLayerViewer: null,\n /** @type {PDFCursorTools} */\n pdfCursorTools: null,\n /** @type {PDFScriptingManager} */\n pdfScriptingManager: null,\n /** @type {ViewHistory} */\n store: null,\n /** @type {DownloadManager} */\n downloadManager: null,\n /** @type {OverlayManager} */\n overlayManager: null,\n /** @type {Preferences} */\n preferences: null,\n /** @type {Toolbar} */\n toolbar: null,\n /** @type {SecondaryToolbar} */\n secondaryToolbar: null,\n /** @type {EventBus} */\n eventBus: null,\n /** @type {IL10n} */\n l10n: null,\n /** @type {AnnotationEditorParams} */\n annotationEditorParams: null,\n isInitialViewSet: false,\n downloadComplete: false,\n isViewerEmbedded: window.parent !== window,\n url: \"\",\n baseUrl: \"\",\n _downloadUrl: \"\",\n externalServices: DefaultExternalServices,\n _boundEvents: Object.create(null),\n documentInfo: null,\n metadata: null,\n _contentDispositionFilename: null,\n _contentLength: null,\n _saveInProgress: false,\n _wheelUnusedTicks: 0,\n _wheelUnusedFactor: 1,\n _touchUnusedTicks: 0,\n _touchUnusedFactor: 1,\n _PDFBug: null,\n _hasAnnotationEditors: false,\n _title: document.title,\n _printAnnotationStoragePromise: null,\n _touchInfo: null,\n _isCtrlKeyDown: false,\n _nimbusDataPromise: null,\n\n // Called once when the document is loaded.\n async initialize(appConfig) {\n let l10nPromise;\n // In the (various) extension builds, where the locale is set automatically,\n // initialize the `L10n`-instance as soon as possible.\n if (typeof PDFJSDev !== \"undefined\" && !PDFJSDev.test(\"GENERIC\")) {\n l10nPromise = this.externalServices.createL10n();\n }\n this.appConfig = appConfig;\n\n if (\n typeof PDFJSDev === \"undefined\"\n ? window.isGECKOVIEW\n : PDFJSDev.test(\"GECKOVIEW\")\n ) {\n this._nimbusDataPromise = this.externalServices.getNimbusExperimentData();\n }\n\n // Ensure that `Preferences`, and indirectly `AppOptions`, have initialized\n // before creating e.g. the various viewer components.\n try {\n await this.preferences.initializedPromise;\n } catch (ex) {\n console.error(`initialize: \"${ex.message}\".`);\n }\n if (AppOptions.get(\"pdfBugEnabled\")) {\n await this._parseHashParams();\n }\n\n if (typeof PDFJSDev === \"undefined\" || !PDFJSDev.test(\"MOZCENTRAL\")) {\n let mode;\n switch (AppOptions.get(\"viewerCssTheme\")) {\n case 1:\n mode = \"is-light\";\n break;\n case 2:\n mode = \"is-dark\";\n break;\n }\n if (mode) {\n document.documentElement.classList.add(mode);\n }\n }\n\n // Ensure that the `L10n`-instance has been initialized before creating\n // e.g. the various viewer components.\n if (typeof PDFJSDev === \"undefined\" || PDFJSDev.test(\"GENERIC\")) {\n l10nPromise = this.externalServices.createL10n();\n }\n this.l10n = await l10nPromise;\n document.getElementsByTagName(\"html\")[0].dir = this.l10n.getDirection();\n // Connect Fluent, when necessary, and translate what we already have.\n if (typeof PDFJSDev === \"undefined\" || !PDFJSDev.test(\"MOZCENTRAL\")) {\n this.l10n.translate(appConfig.appContainer || document.documentElement);\n }\n\n if (\n this.isViewerEmbedded &&\n AppOptions.get(\"externalLinkTarget\") === LinkTarget.NONE\n ) {\n // Prevent external links from \"replacing\" the viewer,\n // when it's embedded in e.g. an