Merge branch 'main' into mirnumaan-patch-1

This commit is contained in:
Numaan Bashir Mir 2024-10-05 10:41:39 +10:00 committed by GitHub
commit cc63fd8b39
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
183 changed files with 3883 additions and 971 deletions

View File

@ -35,7 +35,7 @@ module.exports = {
4
],
'linebreak-style': [
'error',
'off', // git handles linebreak conversion for us
'unix'
],
'quotes': [

View File

@ -89,6 +89,7 @@ body:
label: Version
description: What version of CryptPad are you running?
options:
- 2024.9.0
- 2024.6.1
- 2024.6.0
- 2024.3.1

11
.gitignore vendored
View File

@ -17,12 +17,11 @@ customize
messages.log
www/scratch
data
pins/
blob/
block/
blobstage/
block/
logs/
pins
blob
block
blobstage
logs
privileged.conf
config/config.js
config/sso.js

View File

@ -29,6 +29,10 @@ Files: .stylelintrc.js
Copyright: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
License: AGPL-3.0-or-later
Files: scripts/tests/test-data/*
Copyright: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
License: AGPL-3.0-or-later
## Dependencies
Files: www/common/theme/*

View File

@ -19,6 +19,7 @@ module.exports = {
"declaration-block-no-shorthand-property-overrides": null,
"comment-whitespace-inside": null,
"no-invalid-double-slash-comments": null,
"property-no-vendor-prefix": null,
"selector-no-vendor-prefix": null,

View File

@ -4,6 +4,100 @@ SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and cont
SPDX-License-Identifier: AGPL-3.0-or-later
-->
# Autumn release (2024.9.0)
## Goals
This release improves the performance of CryptPad with server optimizations and an optional cryptography plugin. We also include lots of improvements and fixes across various areas.
## Features
- Add support for cryptography plugins to replace tweetnacl on the server [#1667](https://github.com/cryptpad/cryptpad/pull/1667)
- We use our [CryptPad Sodium plugin](https://github.com/cryptpad/cryptpad-sodium-plugin) to improve the performance of our flagship instance cryptpad.fr.
- Documentation will be available shortly in the form of a blog post and section in the admin guide.
## Improvements
- Server memory improvements [#1543](https://github.com/cryptpad/cryptpad/pull/1543)
- Server optimization when computing metadata [#1566](https://github.com/cryptpad/cryptpad/pull/1566)
- Team roster channels slow down team members accounts [#1614](https://github.com/cryptpad/cryptpad/pull/1614)
- Deployment
- Add example configs for Caddy [#1603](https://github.com/cryptpad/cryptpad/pull/1603)
- Add support for HTTP -> HTTPS (80 -> 443 ports) redirection [#1582](https://github.com/cryptpad/cryptpad/pull/1582)
- Added "git config --add safe.directory" [#1539](https://github.com/cryptpad/cryptpad/pull/1539)
- Add confirmation modal when admins turn on mandatory 2FA [#1552](https://github.com/cryptpad/cryptpad/pull/1552)
- Developers on Windows can now launch their local instance with `npm run windev`
## Fixes
- Modals accessibility
- `Shift-Tab` option for `Ctrl-E` modals [#1647](https://github.com/cryptpad/cryptpad/pull/1647)
- Remove focus from disabled elements on modals [#1618](https://github.com/cryptpad/cryptpad/pull/1618)
- `+New` button fixes on Drive [#1610](https://github.com/cryptpad/cryptpad/pull/1610)
- Accessibility improvements to modals [#1563](https://github.com/cryptpad/cryptpad/pull/1563)
- `Ctrl+E` modal fixes [#1559](https://github.com/cryptpad/cryptpad/pull/1559)
- Focus style fixes [#1560](https://github.com/cryptpad/cryptpad/pull/1560)
- Make password change confirmation button responsive on mobile [#1569](https://github.com/cryptpad/cryptpad/pull/1569)
- Calendar
- Fix calendar ownership sharing bug [#1655](https://github.com/cryptpad/cryptpad/pull/1655)
- Calendar modal UI fixes [#1615](https://github.com/cryptpad/cryptpad/pull/1615)
- Make 'New Event' modal appear in user view for small screens [#1583](https://github.com/cryptpad/cryptpad/pull/1583)
- Teams
- Improve Teams card list accessibility [#1585](https://github.com/cryptpad/cryptpad/pull/1585)
- Fix emoji avatar handling and team name overflowing in sidebar teams [#1598](https://github.com/cryptpad/cryptpad/pull/1598)
- Toolbar/menus
- Make code history buttons not overlap on small screens [#1586](https://github.com/cryptpad/cryptpad/pull/1586)
- Fix misaligned/missing file dropdown menu items [#1578](https://github.com/cryptpad/cryptpad/pull/1578)
- Diagram
- Ignore unknown fields in diagram document [#1666](https://github.com/cryptpad/cryptpad/commit/02da76d3de76455a5573dd43d7ef6e68bf62c959)
- Forms
- Fix overflowing check and radio items in form app conditional [#1591](https://github.com/cryptpad/cryptpad/pull/1591)
- Kanban
- fixed a bug that was causing duplicate cards when many editors were collaborating [02da76d](https://github.com/cryptpad/cryptpad/commit/02da76d3de76455a5573dd43d7ef6e68bf62c959)
- OnlyOffice
- OnlyOffice document out of sync with multiple tabs as guest [#1671](https://github.com/cryptpad/cryptpad/issues/1671)
- Miscellaneous
- Fix ownership/sharing issues with password-protected pads [#1565](https://github.com/cryptpad/cryptpad/pull/1565)
- Make performance table responsive for mobile (admin panel) [#1555](https://github.com/cryptpad/cryptpad/pull/1555)
- Fix bash indentation and trailing whitespaces [#1548](https://github.com/cryptpad/cryptpad/pull/1548)
- Drive focus fixes [#1611](https://github.com/cryptpad/cryptpad/pull/1611)
## Dependencies
We upgraded the following packages
- cryptpad
- chainpad-server to `5.2.2`
- netflux-websocket to `1.2.1`
- third-party
- express to `4.21.0`
- http-proxy-middleware to `3.0.2`
- requirejs to `2.3.7`
- stylelint to `16.9.0`
## Upgrade notes
If you are upgrading from a version older than `2024.6.1` please read the upgrade notes of all versions between yours and `2024.9.0` to avoid configuration issues.
To upgrade:
1. Stop your server
2. Get the latest code with git
```bash
git fetch origin --tags
git checkout 2024.9.0
npm ci
npm run install:components
./install-onlyoffice.sh
```
3. Restart your server
4. Review your instance's checkup page to ensure that you are passing all tests
# 2024.6.1
## Goals
@ -59,7 +153,7 @@ This release introduces a new onboarding flow to guide administrators through th
- Onboarding screens & app configuration [#1513](https://github.com/cryptpad/cryptpad/pull/1513)
- Bahasa Indonesia is a new available language [fe78b6a](https://github.com/cryptpad/cryptpad/commit/fe78b6ab1dc76ce9eb8d5361c309db8e92117fa8)
- Thanks to our [Weblate](https://weblate.cryptpad.org) contributors who made that happen!
- Thanks to our [Weblate](https://weblate.cryptpad.org) contributors who made that happen!
## Improvements
@ -92,7 +186,7 @@ This release introduces a new onboarding flow to guide administrators through th
- Switch to new `http2` Nginx option [#1516](https://github.com/cryptpad/cryptpad/pull/1516)
- Server fixes and aggregated stats [#1509](https://github.com/cryptpad/cryptpad/pull/1509)
- Create the block folder at boot [#911](https://github.com/cryptpad/cryptpad/pull/911)
- Remove obsolete `version` from `docker-compose.yml` [2e716eb](https://github.com/cryptpad/cryptpad/commit/2e716eb4e39fb835f95a1fa1a340e01142d11b1c)
- Remove obsolete `version` from `docker-compose.yml` [2e716eb](https://github.com/cryptpad/cryptpad/commit/2e716eb4e39fb835f95a1fa1a340e01142d11b1c)
- Other
- Unsharp the corners when hovering the dismiss button on notification drop-down menu [#1466](https://github.com/cryptpad/cryptpad/pull/1466)
- Fix contextual menu `Open` on anonymous drive [#1464](https://github.com/cryptpad/cryptpad/pull/1464)

View File

@ -14,7 +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 dependencies
RUN npm install --production \
&& npm run install:components

View File

@ -1,4 +1,4 @@
Copyright (c) <year> <owner>.
Copyright (c) <year> <owner>.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

View File

@ -35,7 +35,7 @@ Mozilla Public License Version 2.0
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
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"

View File

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script async data-bootload="/customize/four-oh-four.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/customize/four-oh-four.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript>

View File

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script async data-bootload="/customize/four-oh-four.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/customize/four-oh-four.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript>

View File

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript></noscript>

View File

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript></noscript>

View File

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript></noscript>

View File

@ -28,8 +28,9 @@ define([
var premiumButton = h('a', {
href: accounts.upgradeURL,
target: '_blank',
rel: 'noopener noreferrer'
}, h('button.cp-features-register-button', Msg.features_f_subscribe));
rel: 'noopener noreferrer',
class: 'cp-features-register-button',
}, Msg.features_f_subscribe);
var groupItemTemplate = function (title, content) {
return h('li.list-group-item', [
@ -119,14 +120,15 @@ define([
h('div.card-body',[
h('div.cp-features-register#cp-features-register', [
h('a', {
href: '/register/'
}, h('button.cp-features-register-button', Msg.features_f_register))
href: '/register/',
class: 'cp-features-register-button',
}, Msg.features_f_register)
]),
]),
]),
]);
var premiumFeatures =
h('div.col-12.col-sm-4.cp-anon-user',[
h('div.col-12.col-sm-4.cp-premium-user',[
h('div.card',[
h('div.title-card',[
h('h3.text-center',Msg.features_premium)

View File

@ -153,10 +153,10 @@ define([
if (Pages.areSubscriptionsAllowed() && !LocalStore.getPremium()) {
var sub = h('div.cp-sub-prompt', [
h('span', Msg.home_morestorage),
h('a', {href:"/accounts/"}, h('button', [
h('a', {href:"/accounts/", class:'subscribe-btn'}, [
h('i.fa.fa-ticket'),
Msg.features_f_subscribe
]))
])
]);
return sub;
} else {

View File

@ -200,8 +200,8 @@
}
.cp-usergrid-user, textarea, a, .fa-times {
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}
}
@ -244,8 +244,8 @@
}
}
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}
span.alertify-tabs-active {
@ -275,7 +275,7 @@
.tools_placeholder-color();
outline: none;
&:focus-visible {
outline: @cryptpad_color_brand solid 2px;
outline: @variables_focus_style;
}
}

View File

@ -129,8 +129,8 @@
box-sizing: border-box;
}
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}
@ -217,8 +217,8 @@
height: var(--checkmark-dim1);
}
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}

View File

@ -30,6 +30,11 @@
.cp-unselectable {
.tools_unselectable();
}
.btn-primary{
&:focus-visible {
outline: @variables_focus_style;
}
}
/* local mixins */
@drive_icon-margin: 10px;
@ -329,11 +334,10 @@
overflow: hidden;
text-overflow: ellipsis;
.leftside-menu-category_main();
margin: 0;
display: flex;
align-items: center;
cursor: pointer;
margin-left: -5px;
margin: 0 0 2px -5px;
padding-left: 5px;
.fa, .cptools {
display: inline-block;
@ -348,6 +352,9 @@
overflow: hidden;
text-overflow: ellipsis;
}
&:focus-visible {
outline: @variables_focus_style;
}
}
}
}
@ -373,6 +380,9 @@
padding-left: 20px;
.leftside-menu-category_main();
margin: 0;
&:focus-visible {
outline: @variables_focus_style;
}
}
}
}
@ -399,6 +409,10 @@
position: relative;
top: -1px;
}
&:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius_S;
}
}
.cp-app-drive-tree-docs {
box-shadow: @cryptpad_ui_shadow;
@ -953,6 +967,9 @@
li, li .fa, li .cptools {
cursor: pointer;
border-radius: @variables_radius;
&:focus {
outline: @cryptpad_color_brand solid 2px;
}
}
&> p {
display: flex;

View File

@ -28,6 +28,9 @@
}
&.tui-full-calendar-content {
font-size: @colortheme_app-font-size;
&:focus-visible {
outline: @variables_focus_style;
}
}
&[readonly] {
//margin-top:1rem;
@ -138,8 +141,8 @@
color: @cryptpad_text_col;
}
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}
}
@ -148,8 +151,8 @@
background-color: @cp_buttons-cancel;
box-sizing: border-box;
align-items: center;
padding: 0 6px;
line-height: 36px;
line-height: 20px;
padding: 8px 6px;
white-space: nowrap;
text-align: center;
text-transform: uppercase;
@ -257,8 +260,8 @@
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
&::-moz-focus-inner {
border: 0;

View File

@ -33,8 +33,8 @@
color: @cp_drive-fg;
}
&.cp-icons-element-selected {
background: @cp_drive-icon-hover;
color: @cp_drive-fg;
outline: @cryptpad_color_brand solid 2px;
}
.fa, .cptools {
display: block;

View File

@ -6,6 +6,7 @@
@import (reference) "./colortheme-all.less";
@import (reference) "./font.less";
@import (reference) "./variables.less";
@infopages-radius: 5px;
@infopages-radius-L: 10px;
@ -46,6 +47,10 @@ body.html {
a:hover {
opacity: 1;
}
a:focus-visible {
outline: @variables_focus_style;
border-radius: @variables_radius;
}
border: 0;
padding: 0;
margin: 0;
@ -231,6 +236,9 @@ body.html {
border: 0px;
border-radius: @infopages-radius;
padding: 0.5em 0.7em;
&:focus-visible {
outline: @variables_focus_style;
}
}
}
.cp-footer-version {
@ -293,6 +301,9 @@ body.html {
&:hover {
color: @cryptpad_text_col;
}
&:focus-visible {
outline: @variables_focus_style;
}
i {
margin-right: 5px;
}

View File

@ -47,6 +47,9 @@
align-items: center;
.leftside-menu-category_main();
box-shadow: @cryptpad_ui_shadow;
&:focus-visible {
outline: @variables_focus_style;
}
}
}
&.cp-leftside-narrow {

View File

@ -81,8 +81,8 @@
padding-left: 4px;
vertical-align: middle;
outline: none;
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}
.close {

View File

@ -29,35 +29,6 @@
font: @colortheme_app-font;
}
@media screen and (max-width: 870px) {
flex-flow: column;
.cp-toolbar-history-actions {
width: 100%;
.cp-history-actions-first {
margin-right: 0 !important;
}
}
.cp-toolbar-history-timeline {
width: ~"calc(100% - 20px)";
margin-right: 10px !important;
}
}
@media screen and (max-height: 500px) {
padding-top: 0px;
.cp-history-timeline-line {
display: none !important;
}
.cp-toolbar-history-timeline {
width: 100% !important;
margin: 0 !important;
}
.cp-history-timeline-actions {
margin-left: 0 !important;
}
}
&.cp-history-init {
padding: 0;
height: 32px;
@ -102,8 +73,8 @@
text-transform: uppercase;
display: inline-flex;
align-items: center;
.fa:not(:last-child) {
margin-right: 5px;
i:not(:last-child) {
margin-right: 0.5rem;
}
&:hover {
background-color: fade(@cp_toolbar-fg, 30%);
@ -293,6 +264,39 @@
left: ~"calc(50% - 6px)";
}
}
@media screen and (max-width: 870px) {
flex-flow: column;
.cp-toolbar-history-actions {
width: 100%;
margin: 0.6rem 0;
height: auto;
.cp-history-actions-first {
margin-right: 0 !important;
}
button {
margin: 0.1rem;
}
}
.cp-toolbar-history-timeline {
width: ~"calc(100% - 20px)";
margin-right: 10px !important;
}
}
@media screen and (max-height: 500px) {
padding-top: 0px;
.cp-history-timeline-line {
display: none !important;
}
.cp-toolbar-history-timeline {
width: 100% !important;
margin: 0 !important;
}
.cp-history-timeline-actions {
margin-left: 0 !important;
}
}
}
}

View File

@ -77,8 +77,8 @@
&:hover {
background-color: contrast(@cp_toolbar-bg, darken(@cp_toolbar-bg, 5%), lighten(@cp_toolbar-bg, 5%));
}
&:focus {
outline: @cryptpad_color_brand solid 2px;
&:focus-visible {
outline: @variables_focus_style;
}
}
button:nth-of-type(1) {
@ -373,7 +373,7 @@
* {
outline-style: none;
&:focus-visible {
outline: @cryptpad_color_brand solid 2px;
outline: @variables_focus_style;
}
}
@ -676,6 +676,10 @@
overflow: hidden;
text-overflow: ellipsis;
border-collapse: collapse;
&:focus {
margin: 2px;
border-radius: @variables_radius;
}
}
input {
color: @cryptpad_text_col;
@ -983,11 +987,8 @@
height: @toolbar_line-height;
display: inline-flex;
align-items: center;
.fa, .cptools {
margin-right: 5px;
}
.cp-dropdown-button-title .cp-icon {
margin-left: 5px;
i ~ span {
margin-left: 0.5rem;
}
&:hover {
background-color: fade(@cp_toolbar-bottom-bg, 70%);
@ -1109,15 +1110,6 @@
}
}
.cp-toolbar-bottom-left {
.cp-toolbar-appmenu, .cp-toolbar-file {
button {
&::before, .fa {
min-width: 20px;
text-align: center;
margin-right: 0;
}
}
}
.cp-toolbar-file {
order: 1;
}

View File

@ -18,6 +18,8 @@
@variables_shadow: 0 8px 32px 0 @cp_shadow-color;
// Rounded corners
@variables_radius_S: 3px;
@variables_radius: 5px;
@variables_radius_L: 10px;
@variables_focus_style: @cryptpad_color_brand solid 2px;

View File

@ -15,12 +15,19 @@
padding: 20px;
}
.cp-features-register-button {
text-decoration: none;
text-align: center;
background-color: @cp_buttons-primary;
color: @cryptpad_text_col;
font-size: 20px;
color: @cryptpad_color_white;
background: @cryptpad_color_brand;
border-radius: 0;
&:hover {
cursor: pointer;
margin: 10px 0;
border-radius: @infopages-radius;
padding: 10px 20px;
&:hover, &:focus {
background-color: contrast(@cp_buttons-primary-text, darken(@cp_buttons-primary, 10%), lighten(@cp_buttons-primary, 10%));
}
&:visited {
color: @cryptpad_text_col;
}
}
.cp-features-web {
@ -114,5 +121,10 @@
margin-top: 3em;
}
}
.cp-premium-user {
@media (max-width:575px) {
margin-top: 3em;
}
}
}

View File

@ -255,9 +255,10 @@
* {
display: block;
}
button {
background-color: @cryptpad_color_link;
color: @cryptpad_text_col_inv;
.subscribe-btn {
text-align: center;
background-color: @cp_buttons-primary;
color: @cryptpad_text_col;
font-size: 1.4rem;
margin: 10px 0;
border-radius: @infopages-radius-L;
@ -267,8 +268,7 @@
margin-right: 10px;
}
&:hover, &:focus {
background-color: @cp_static-card-bg;
color: @cryptpad_text_col;
background-color: contrast(@cp_buttons-primary-text, darken(@cp_buttons-primary, 10%), lighten(@cp_buttons-primary, 10%));
}
}
}

View File

@ -43,13 +43,10 @@
nav {
display: flex;
align-items: center;
justify-content: flex-end;
}
@media screen and (max-width: 600px) {
nav .btn-danger {
line-height: inherit;
align-items: flex-end;
.btn-confirm {
white-space: normal;
}
}

View File

@ -68,13 +68,10 @@
nav {
display: flex;
align-items: center;
justify-content: flex-end;
}
@media screen and (max-width: 600px) {
nav .btn-danger {
line-height: inherit;
align-items: flex-end;
.btn-confirm {
white-space: normal;
}
}

View File

@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/customize/template.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript></noscript>

View File

@ -22,9 +22,9 @@ if [ ! -f "$CPAD_CONF" ]; then
eg: docker run -v /path/to/config.js:/cryptpad/config/config.js \n\
#################################################################### \n"
cp "$CPAD_HOME"/config/config.example.js "$CPAD_CONF"
cp "$CPAD_HOME"/config/config.example.js "$CPAD_CONF"
sed -i -e "s@\(httpUnsafeOrigin:\).*[^,]@\1 '$CPAD_MAIN_DOMAIN'@" \
sed -i -e "s@\(httpUnsafeOrigin:\).*[^,]@\1 '$CPAD_MAIN_DOMAIN'@" \
-e "s@\(^ *\).*\(httpSafeOrigin:\).*[^,]@\1\2 '$CPAD_SANDBOX_DOMAIN'@" "$CPAD_CONF"
fi

10
docs/community/README.md Normal file
View File

@ -0,0 +1,10 @@
<!--
SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-->
# Community configuration files
This folder is listing community-contributed configuration files. They **aren't** supported and are provided as-is, without any warranty.
If you are using CryptPad in production and require professional support please contact sales@cryptpad.org

View File

@ -0,0 +1,245 @@
# SPDX-FileCopyrightText: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# This file is included strictly as an example of how Caddy can be configured
# to work with CryptPad. This example WILL NOT WORK AS IS. For best results,
# compare the sections of this configuration file against a working CryptPad
# installation (http server by the Nodejs process). If you are using CryptPad
# in production and require professional support please contact sales@cryptpad.org
(trustedProxies) {
# Force Caddy to accept `X-Forwarded-For` and other origin headers.
# Modify the line below if you want to restrict the scope of direct downstream sending these headers.
trusted_proxies 0.0.0.0/0 ::/0
}
# Caddy does not have variables for server names, so domains need to be hardcoded.
# You can bulk replace "your-main-domain.com" and "your-sandbox-domain.com" safely.
your-main-domain.com:443,
your-sandbox-domain.com:443 {
# Define your certificates below.
# No need to adjust TLS configurations, as the defaults in Caddy are already secure.
tls /path/to/fullchain/publicKey.pem /path/to/certificate/privateKey.pem
# Enable HSTS.
# Do not enable this line when configuring over mixnet, e.g. Tor.
header Strict-Transport-Security "max-age=63072000; includeSubDomains"
# Security headers
header X-XSS-Protection "1; mode=block"
header X-Content-Type-Options "nosniff"
header Access-Control-Allow-Credentials "true"
#header X-Frame-Options "SAMEORIGIN"
# OnlyOffice fonts may be loaded from both domains.
@onlyOfficeFonts {
path_regexp "^\\/common\\/onlyoffice\\/.*\\/fonts\\/.*$"
}
header Access-Control-Allow-Origin "*"
# By default CryptPad forbids remote domains from embedding CryptPad documents in iframes.
# The sandbox domain must always be permitted in order for the platform to function.
# If you wish to enable remote embedding you may change the value below to "*"
# as per the commented value.
header ?Access-Control-Allow-Origin "https://your-sandbox-domain.com"
#header ?Access-Control-Allow-Origin "*"
# Opt out of Google's FLoC Network
header Permissions-Policy "interest-cohort=()"
# Enable SharedArrayBuffer in Firefox (for .xlsx export)
header ?Cross-Origin-Resource-Policy "cross-origin"
header ?Cross-Origin-Embedder-Policy "require-corp"
# Specify the relative path to root of your custom error page.
# This error page won't only be served for 404 errors.
handle_errors {
rewrite * /error.htm
header Cache-Control "no-cache, no-store"
file_server
templates
}
# Insert the path to your CryptPad repository root here
root /home/cryptpad/cryptpad
# Any static assets loaded with "vers=" in their URL will be cached for a year
@staticAssets {
query "ver=*"
}
header @staticAssets Cache-Control "max-age=31536000"
vars {
# CSS can be dynamically set inline, loaded from the same domain, or from your main domain.
styleSrc "'unsafe-inline' 'self' https://your-main-domain.com"
# connect-src restricts URLs which can be loaded using script interfaces.
# If you have configured your instance to use a dedicated file delivery domain or API domain,
# you will need to add them below.
connectSrc "'self' https://your-main-domain.com blob: wss://api.your-main-domain.com https://your-sandbox-domain.com"
# Fonts can be loaded from data-URLs or the main domain.
fontSrc "'self' data: https://your-main-domain.com"
# Images can be loaded from anywhere, though we'd like to deprecate this as it allows
# the use of images for tracking.
imgSrc "'self' data: blob: https://your-main-domain.com"
# frame-src specifies valid sources for nested browsing contexts.
# This prevents loading any iframes from anywhere other than the sandbox domain.
frameSrc "'self' https://your-sandbox-domain.com blob:"
# media-src specifies valid sources for loading media using video or audio.
mediaSrc "blob:"
# child-src defines valid sources for webworkers and nested browser contexts.
# It is deprecated in favour of worker-src and frame-src.
childSrc "https://your-main-domain.com"
# worker-src valid sources for Worker, Shared Worker, or Service Worker scripts.
# Supercedes child-src, but is unfortunately not yet universally supported.
workerSrc "'self'"
# script-src specifies valid sources for JavaScript, including inline handlers.
scriptSrc "'self' resource: https://your-main-domain.com"
# frame-ancestors specifies which origins can embed your CryptPad instance.
# This must include 'self' and your main domain (over HTTPS) in order for CryptPad to work,
# if you have enabled remote embedding via the admin panel, then this must be more permissive.
# Note: cryptpad.fr permits web pages served via https: and vector: (element desktop app)
frameAncestors "'self' https://your-main-domain.com"
#frameAncestors "'self' https: vector:"
# A few assets are loaded via the sandbox domain.
# They unfortunately still require exceptions to the sandboxing to work correctly.
# Everything except the sandbox domain is a privileged scope, as they might be used to handle keys.
# Unsafe iframes are exceptions. Office file formats are converted outside of the sandboxed scope,
# because of bugs in Chromium-based browsers that incorrectly ignore headers supposed to enable
# the use of some modern APIs, that are required when JavaScript is run in a cross-origin context.
# We've applied other sandboxing techniques to mitigate the risk of running WebAssembly
# in this privileged scope.
# Privileged contexts allow a few more rights than unprivileged contexts, though limits are still applied.
scriptSrcUnsafe "'self' 'unsafe-eval' 'unsafe-inline' resource: https://your-main-domain.com"
}
# Finally, set all the security rules you have composed above.
@privilegedScope1 {
host "your-sandbox-domain.com"
path_regexp "^\\/(sheet|doc|presentation)\\/inner.html.*$"
}
@privilegedScope2 {
host "your-sandbox-domain.com"
path_regexp "^\\/common\\/onlyoffice\\/.*\\/.*\\.html.*$"
}
@privilegedScope3 {
host "your-sandbox-domain.com"
path_regexp "^\\/unsafeiframe\\/inner\\.html.*$"
}
header @privilegedScope1 Content-Security-Policy "default-src 'none'; child-src {vars.childSrc}; worker-src {vars.workerSrc}; media-src {vars.mediaSrc}; style-src {vars.styleSrc}; script-src {vars.scriptSrcUnsafe}; connect-src {vars.connectSrc}; font-src {vars.fontSrc}; img-src {vars.imgSrc}; frame-src {vars.frameSrc}; frame-ancestors {vars.frameAncestors}"
header @privilegedScope2 Content-Security-Policy "default-src 'none'; child-src {vars.childSrc}; worker-src {vars.workerSrc}; media-src {vars.mediaSrc}; style-src {vars.styleSrc}; script-src {vars.scriptSrcUnsafe}; connect-src {vars.connectSrc}; font-src {vars.fontSrc}; img-src {vars.imgSrc}; frame-src {vars.frameSrc}; frame-ancestors {vars.frameAncestors}"
header @privilegedScope3 Content-Security-Policy "default-src 'none'; child-src {vars.childSrc}; worker-src {vars.workerSrc}; media-src {vars.mediaSrc}; style-src {vars.styleSrc}; script-src {vars.scriptSrcUnsafe}; connect-src {vars.connectSrc}; font-src {vars.fontSrc}; img-src {vars.imgSrc}; frame-src {vars.frameSrc}; frame-ancestors {vars.frameAncestors}"
header ?Content-Security-Policy "default-src 'none'; child-src {vars.childSrc}; worker-src {vars.workerSrc}; media-src {vars.mediaSrc}; style-src {vars.styleSrc}; script-src {vars.scriptSrc}; connect-src {vars.connectSrc}; font-src {vars.fontSrc}; img-src {vars.imgSrc}; frame-src {vars.frameSrc}; frame-ancestors {vars.frameAncestors}"
# Add support for .mjs files used by pdfjs
@fileModuleJS {
path "*.mjs"
}
header @fileModuleJS Content-Type "application/javascript"
# The Node.js process can handle all traffic, whether accessed over websocket or as static assets.
# We prefer to serve static content from Caddy directly, and to leave the API server to handle the
# the dynamic content that only it can manage. This is primarily for optimization.
handle /cryptpad_websocket/* {
reverse_proxy * {
to 127.0.0.1:3003
header_up Host "{host}"
header_up X-Real-IP "{remote_host}"
# Caddy supports WebSockets directly. No additional headers are needed.
import trustedProxies
}
}
handle_path /customize.dist/* {
# This is needed in order to prevent infinite recursion between /customize/ and the root.
}
# Try to load customizeable content via /customize/ and fall back to the default content located
# at /customize.dist/ .
# This is what allows you to override behaviour.
handle_path /customize/* {
try_files /customize/{path} /customize.dist/{path}
file_server {
index index.html index.htm default.html default.htm
}
}
# /api/config is loaded once per page load, and is used to retrieve the caching variable,
# which is applied to every other resource loaded during that session.
@sharedReverseProxy {
path /api/*
path /extensions.js
}
handle @sharedReverseProxy {
reverse_proxy * {
to 127.0.0.1:3000
header_up Host "{host}"
header_up X-Real-IP "{remote_host}"
# These settings prevent both Caddy and the API server from setting duplicate headers.
header_down Cross-Origin-Resource-Policy cross-origin
header_down Cross-Origin-Embedder-Policy require-corp
import trustedProxies
}
}
# Requests for blobs and blocks are now proxied to the API server.
# This simplifies Caddy path configuration, in the event they are being hosted in a non-standard location
# or with odd unexpected permissions. Serving blobs in this manner also means that it will be possible to
# enforce access control for them, though this is not yet implemented.
# Access control (via TOTP 2FA) has been added to blocks, so they can be handled with the same directives.
@blobsAndBlocks {
path /blob/*
path /block/*
}
handle @blobsAndBlocks {
@corsPreflight {
method OPTIONS
}
handle @corsPreflight {
header Access-Control-Allow-Origin "https://your-sandbox-domain.com"
header Access-Control-Allow-Credentials "true"
header Access-Control-Allow-Methods "GET, POST, OPTIONS"
header Access-Control-Allow-Headers "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range"
header Access-Control-Max-Age "1728000"
header Content-Type "application/octet-stream; charset=utf-8"
header Content-Length "0"
respond 204
}
reverse_proxy * {
to 127.0.0.1:3000
# Preventing these headers from getting duplicated, since we are proxying to the API server.
header_down -X-Content-Type-Options
header_down -Access-Control-Allow-Origin
header_down -Permissions-Policy
header_down -X-XSS-Protection
header_down -Cross-Origin-Resource-Policy
header_down -Cross-Origin-Embedder-Policy
}
}
# The Node.JS server has some built-in forwarding rulesets to prevent URLs not suffixed with a slash
# from resulting in a 404 error. This simply adds a trailing slash to a variety of applications.
@preventNotFound {
path_regexp "^/(register|login|recovery|settings|user|pad|drive|poll|slide|code|whiteboard|file|media|profile|contacts|todo|filepicker|debug|kanban|sheet|support|admin|notifications|teams|calendar|presentation|doc|form|report|convert|checkup|diagram)$"
}
redir @preventNotFound "{path}/"
# Enable file serving
file_server {
index index.html index.htm default.html default.htm
}
}

View File

@ -0,0 +1,64 @@
# SPDX-FileCopyrightText: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# This file is included strictly as an example of how Caddy can be configured
# to work with CryptPad. This example WILL NOT WORK AS IS. For best results,
# compare the sections of this configuration file against a working CryptPad
# installation (http server by the Nodejs process). If you are using CryptPad
# in production and require professional support please contact sales@cryptpad.org
(trustedProxies) {
# Force Caddy to accept `X-Forwarded-For` and other origin headers.
# Modify the line below if you want to restrict the scope of direct downstream sending these headers.
trusted_proxies 0.0.0.0/0 ::/0
}
# Caddy does not have variables for server names, so domains need to be hardcoded.
# You can bulk replace "your-main-domain.com" and "your-sandbox-domain.com" safely.
your-main-domain.com:443,
your-sandbox-domain.com:443 {
# Define your certificates below.
# No need to adjust TLS configurations, as the defaults in Caddy are already secure.
tls /path/to/fullchain/publicKey.pem /path/to/certificate/privateKey.pem
# Enable HSTS.
# Do not enable this line when configuring over mixnet, e.g. Tor.
header Strict-Transport-Security "max-age=63072000; includeSubDomains"
# Specify the relative path to root of your custom error page.
# This error page won't only be served for 404 errors.
handle_errors {
rewrite * /error.htm
header Cache-Control "no-cache, no-store"
file_server
templates
}
# The Node.js process can handle all traffic, whether accessed over websocket or as static assets.
reverse_proxy /cryptpad_websocket/* {
to 127.0.0.1:3003
header_up Host "{host}"
header_up X-Real-IP "{remote_host}"
# Caddy supports WebSockets directly. No additional headers are needed.
import trustedProxies
}
reverse_proxy * {
to 127.0.0.1:3000
header_up Host "{host}"
header_up X-Real-IP "{remote_host}"
# These settings prevent both Caddy and the API server from setting duplicate headers.
header_down Cross-Origin-Resource-Policy cross-origin
header_down Cross-Origin-Embedder-Policy require-corp
import trustedProxies
}
# Enable file serving
file_server {
index index.html index.htm default.html default.htm
}
}

View File

@ -4,7 +4,7 @@
# 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
# and require professional support please contact sales@cryptpad.org
# This configuration requires mod_ssl, mod_socache_shmcb, mod_proxy,
# mod_proxy_http and mod_headers

View File

@ -8,6 +8,21 @@
# installation (http server by the Nodejs process). If you are using CryptPad
# in production and require professional support please contact sales@cryptpad.fr
server {
listen 80;
listen [::]:80;
server_name your-main-domain.com your-sandbox-domain.com;
access_log /dev/null;
error_log /dev/null emerg;
# Let's Encrypt webroot
include letsencrypt-webroot;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;

View File

@ -8,6 +8,21 @@
# installation (http server by the Nodejs process). If you are using CryptPad
# in production and require professional support please contact sales@cryptpad.fr
server {
listen 80;
listen [::]:80;
server_name your-main-domain.com your-sandbox-domain.com;
access_log /dev/null;
error_log /dev/null emerg;
# Let's Encrypt webroot
include letsencrypt-webroot;
# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;

View File

@ -190,6 +190,9 @@ nThen(function (w) {
removed++;
}
});
if (Env.store) {
Env.store.closeInactiveChannels(active);
}
if (removed) {
Env.Log.info("CLEANED_ACTIVE_CHANNELS_MAP", {removed});
}

28
lib/crypto.js Normal file
View File

@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
//
// SPDX-License-Identifier: AGPL-3.0-or-later
const Nacl = require('tweetnacl/nacl-fast');
const CPCrypto = module.exports;
const plugins = require('./plugin-manager');
CPCrypto.init = (cb) => {
const crypto = {};
crypto.open = (signedMsg, validateKey) => {
return Nacl.sign.open(signedMsg, validateKey);
};
crypto.detachedVerify = (signedBuffer, signatureBuffer, validateKey) => {
return Nacl.sign.detached.verify(signedBuffer, signatureBuffer, validateKey);
};
if (plugins.SODIUM && plugins.SODIUM.crypto) {
let c = plugins.SODIUM.crypto;
if (c.open) { crypto.open = c.open; }
if (c.detachedVerify) { crypto.detachedVerify = c.detachedVerify; }
}
// Make async because we might need it later with libsodium's promise
// libsodium.ready.then(() => {});
setTimeout(() => {
cb(void 0, crypto);
});
};

View File

@ -146,6 +146,7 @@ const dropChannel = HK.dropChannel = function (Env, chanName) {
expireChannel(Env, chanName);
}, TEMPORARY_CHANNEL_LIFETIME);
}
if (Env.store) { Env.store.closeChannel(chanName, function () {}); }
};
/* checkExpired

View File

@ -286,6 +286,16 @@ var closeChannel = function (env, channelName, cb) {
}
};
var closeInactiveChannels = function (env, schedule, active) {
Object.keys(env.channels).forEach(channelName => {
if (!active.includes(channelName)) {
schedule.ordered(channelName, function (next) {
closeChannel(env, channelName, next);
});
}
});
};
var clearOffset = function (env, channelId, cb) {
var path = mkOffsetPath(env, channelId);
// we should always be able to recover from invalid offsets, so failure to delete them
@ -429,7 +439,27 @@ How to proceed
*/
let requiresChannel = true;
let all = [];
nThen(function (w) {
let first = true;
getDedicatedMetadata(env, channelId, (err, line) => {
if (first && !err) {
if (!Array.isArray(line)) {
requiresChannel = false;
}
first = false;
}
all.push({err, line});
}, w(function (err) {
if (err) {
// stream errors?
w.abort();
return void cb(err);
}
}));
}).nThen(function (w) {
if (!requiresChannel) { return; }
// returns the first line of a channel, parsed...
getChannelMetadata(env, channelId, w(function (err, data) {
if (err) {
@ -445,13 +475,10 @@ How to proceed
handler(null, data);
}));
}).nThen(function () {
getDedicatedMetadata(env, channelId, handler, function (err) {
if (err) {
// stream errors?
return void cb(err);
}
cb();
all.forEach(({err, line}) => {
handler(err, line);
});
cb();
});
};
@ -1445,6 +1472,9 @@ module.exports.create = function (conf, _cb) {
closeChannel(env, channelName, Util.both(cb, next));
});
},
closeInactiveChannels: function (active) {
closeInactiveChannels(env, schedule, active);
},
// write to a log file
log: function (channelName, content, cb) {
// you probably want the events in your log to be in the correct order.

View File

@ -16,6 +16,7 @@ const Logger = require("../log");
const Tasks = require("../storage/tasks");
const Nacl = require('tweetnacl/nacl-fast');
const Eviction = require("../eviction");
const CPCrypto = require('../crypto');
const Env = {
Log: {},
@ -101,6 +102,10 @@ const init = function (config, _cb) {
}
Env.tasks = tasks;
}));
}).nThen(function (w) {
CPCrypto.init(w(function (err, crypto) {
Env.crypto = crypto;
}));
}).nThen(function () {
cb();
});
@ -680,7 +685,8 @@ COMMANDS.INLINE = function (data, cb) {
return void cb("E_BADKEY");
}
// validate the message
const validated = Nacl.sign.open(signedMsg, validateKey);
//const validated = Nacl.sign.open(signedMsg, validateKey);
const validated = Env.crypto.open(signedMsg, validateKey);
if (!validated) {
return void cb("FAILED");
}
@ -720,7 +726,8 @@ const checkDetachedSignature = function (signedMsg, signature, publicKey) {
throw new Error("INVALID_SIGNATURE_LENGTH");
}
if (Nacl.sign.detached.verify(signedBuffer, signatureBuffer, pubBuffer) !== true) {
//if (Nacl.sign.detached.verify(signedBuffer, signatureBuffer, pubBuffer) !== true) {
if (Env.crypto.detachedVerify(signedBuffer, signatureBuffer, pubBuffer) !== true) {
throw new Error("FAILED");
}
};

558
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "cryptpad",
"version": "2024.6.1",
"version": "2024.9.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cryptpad",
"version": "2024.6.1",
"version": "2024.9.0",
"license": "AGPL-3.0+",
"dependencies": {
"@mcrowe/minibloom": "^0.2.0",
@ -19,7 +19,7 @@
"chainpad-crypto": "^0.2.5",
"chainpad-listmap": "^1.1.0",
"chainpad-netflux": "^1.2.0",
"chainpad-server": "^5.2.0",
"chainpad-server": "^5.2.2",
"ckeditor": "npm:ckeditor4@~4.22.1",
"codemirror": "^5.19.0",
"components-font-awesome": "^4.6.3",
@ -27,12 +27,12 @@
"croppie": "^2.5.0",
"dragula": "3.7.2",
"drawio": "github:cryptpad/drawio-npm#npm-21.8.2+5",
"express": "~4.19.2",
"express": "~4.21.0",
"file-saver": "1.3.1",
"fs-extra": "^7.0.0",
"get-folder-size": "^2.0.1",
"html2canvas": "^1.4.0",
"http-proxy-middleware": "^2.0.6",
"http-proxy-middleware": "^3.0.2",
"hyper-json": "~1.4.0",
"jquery": "3.6.0",
"json.sortify": "~2.1.0",
@ -41,7 +41,7 @@
"localforage": "^1.5.2",
"marked": "^4.3.0",
"mathjax": "3.0.5",
"netflux-websocket": "^1.2.0",
"netflux-websocket": "^1.2.1",
"notp": "^2.0.3",
"nthen": "0.1.8",
"open-sans-fontface": "^1.4.0",
@ -50,7 +50,7 @@
"prompt-confirm": "^2.0.4",
"pull-stream": "^3.6.1",
"require-css": "0.1.10",
"requirejs": "2.3.5",
"requirejs": "2.3.7",
"requirejs-plugins": "^1.0.2",
"saferphore": "0.0.1",
"scrypt-async": "1.2.0",
@ -66,7 +66,7 @@
"devDependencies": {
"eslint": "^8.57.0",
"eslint-plugin-compat": "^4.2.0",
"stylelint": "^16.6.1",
"stylelint": "^16.9.0",
"stylelint-config-standard-less": "^3.0.1"
},
"funding": {
@ -192,9 +192,9 @@
}
},
"node_modules/@csstools/css-parser-algorithms": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.3.tgz",
"integrity": "sha512-xI/tL2zxzEbESvnSxwFgwvy5HS00oCXxL4MLs6HUiDcYfwowsoQaABKxUElp1ARITrINzBnsECOc1q0eg2GOrA==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.1.tgz",
"integrity": "sha512-lSquqZCHxDfuTg/Sk2hiS0mcSFCEBuj49JfzPHJogDBT0mGCyY5A1AQzBWngitrp7i1/HAZpIgzF/VjhOEIJIg==",
"dev": true,
"funding": [
{
@ -207,16 +207,16 @@
}
],
"engines": {
"node": "^14 || ^16 || >=18"
"node": ">=18"
},
"peerDependencies": {
"@csstools/css-tokenizer": "^2.3.1"
"@csstools/css-tokenizer": "^3.0.1"
}
},
"node_modules/@csstools/css-tokenizer": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.3.1.tgz",
"integrity": "sha512-iMNHTyxLbBlWIfGtabT157LH9DUx9X8+Y3oymFEuMj8HNc+rpE3dPFGFgHjpKfjeFDjLjYIAIhXPGvS2lKxL9g==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.1.tgz",
"integrity": "sha512-UBqaiu7kU0lfvaP982/o3khfXccVlHPWp0/vwwiIgDF0GmqqqxoiXC/6FCjlS9u92f7CoEz6nXKQnrn1kIAkOw==",
"dev": true,
"funding": [
{
@ -229,13 +229,13 @@
}
],
"engines": {
"node": "^14 || ^16 || >=18"
"node": ">=18"
}
},
"node_modules/@csstools/media-query-list-parser": {
"version": "2.1.11",
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.11.tgz",
"integrity": "sha512-uox5MVhvNHqitPP+SynrB1o8oPxPMt2JLgp5ghJOWf54WGQ5OKu47efne49r1SWqs3wRP8xSWjnO9MBKxhB1dA==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz",
"integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==",
"dev": true,
"funding": [
{
@ -248,11 +248,33 @@
}
],
"engines": {
"node": "^14 || ^16 || >=18"
"node": ">=18"
},
"peerDependencies": {
"@csstools/css-parser-algorithms": "^2.6.3",
"@csstools/css-tokenizer": "^2.3.1"
"@csstools/css-parser-algorithms": "^3.0.1",
"@csstools/css-tokenizer": "^3.0.1"
}
},
"node_modules/@csstools/selector-specificity": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-4.0.0.tgz",
"integrity": "sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/csstools"
},
{
"type": "opencollective",
"url": "https://opencollective.com/csstools"
}
],
"engines": {
"node": ">=18"
},
"peerDependencies": {
"postcss-selector-parser": "^6.1.0"
}
},
"node_modules/@dual-bundle/import-meta-resolve": {
@ -335,15 +357,6 @@
}
}
},
"node_modules/@eslint/eslintrc/node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/@eslint/eslintrc/node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -605,9 +618,9 @@
"integrity": "sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA=="
},
"node_modules/@types/http-proxy": {
"version": "1.17.14",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz",
"integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==",
"version": "1.17.15",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz",
"integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==",
"dependencies": {
"@types/node": "*"
}
@ -1203,9 +1216,9 @@
}
},
"node_modules/body-parser": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
@ -1215,7 +1228,7 @@
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
@ -1326,22 +1339,27 @@
}
},
"node_modules/call-bind": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz",
"integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.1",
"set-function-length": "^1.1.1"
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001591",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001591.tgz",
"integrity": "sha512-PCzRMei/vXjJyL5mJtzNiUCKP59dm8Apqc3PH8gJkMnMXZGox93RbE76jHsmLwmIo6/3nsYIpJtx0O7u5PqFuQ==",
"version": "1.0.30001660",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz",
"integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==",
"dev": true,
"funding": [
{
@ -1396,9 +1414,9 @@
}
},
"node_modules/chainpad-server": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/chainpad-server/-/chainpad-server-5.2.1.tgz",
"integrity": "sha512-r6kNMCbMuwUMxsFIZJgyXtdGxwoXm+gFVIUBxKLOzhvbeMm0RSBYa6BJ5qgzYIwUhYgqyUxmm9tXzYecmPUHIA==",
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/chainpad-server/-/chainpad-server-5.2.2.tgz",
"integrity": "sha512-fUCffhnd8PlO92A6cYH5lSIiiI6bpJymP0yC3O2KI+4NPyxFK7I2iuadMrC7RzK3eAI1w72Y1nbMN8rQImppoQ==",
"dependencies": {
"nthen": "0.1.8",
"pull-stream": "^3.6.9",
@ -1654,6 +1672,18 @@
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/custom-event": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.0.tgz",
@ -1684,16 +1714,19 @@
"dev": true
},
"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==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dependencies": {
"get-intrinsic": "^1.2.1",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-property": {
@ -1825,6 +1858,25 @@
"node": ">=0.10.0"
}
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
@ -1999,15 +2051,6 @@
"node": ">=10.13.0"
}
},
"node_modules/eslint/node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/eslint/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@ -2144,36 +2187,36 @@
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
},
"node_modules/express": {
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.2.0",
"finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.1",
"merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"path-to-regexp": "0.1.10",
"proxy-addr": "~2.0.7",
"qs": "6.11.0",
"qs": "6.13.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
"serve-static": "1.15.0",
"send": "0.19.0",
"serve-static": "1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
@ -2184,6 +2227,14 @@
"node": ">= 0.10.0"
}
},
"node_modules/express/node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"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",
@ -2265,12 +2316,12 @@
}
},
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
@ -2281,6 +2332,14 @@
"node": ">= 0.8"
}
},
"node_modules/finalhandler/node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/find-up": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@ -2416,15 +2475,19 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
"integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@ -2588,20 +2651,20 @@
}
},
"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==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dependencies": {
"get-intrinsic": "^1.2.2"
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"engines": {
"node": ">= 0.4"
},
@ -2684,28 +2747,50 @@
}
},
"node_modules/http-proxy-middleware": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz",
"integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.2.tgz",
"integrity": "sha512-fBLFpmvDzlxdckwZRjM0wWtwDZ4KBtQ8NFqhrFKoEtK4myzuiumBuNTxD+F4cVbXfOZljIbrynmvByofDzT7Ag==",
"dependencies": {
"@types/http-proxy": "^1.17.8",
"@types/http-proxy": "^1.17.15",
"debug": "^4.3.6",
"http-proxy": "^1.18.1",
"is-glob": "^4.0.1",
"is-plain-obj": "^3.0.0",
"micromatch": "^4.0.2"
"is-glob": "^4.0.3",
"is-plain-object": "^5.0.0",
"micromatch": "^4.0.8"
},
"engines": {
"node": ">=12.0.0"
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/http-proxy-middleware/node_modules/debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dependencies": {
"ms": "^2.1.3"
},
"peerDependencies": {
"@types/express": "^4.17.13"
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"@types/express": {
"supports-color": {
"optional": true
}
}
},
"node_modules/http-proxy-middleware/node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/http-proxy-middleware/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/hyper-json": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/hyper-json/-/hyper-json-1.4.0.tgz",
@ -2722,6 +2807,15 @@
"node": ">=0.10.0"
}
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
@ -2870,17 +2964,6 @@
"node": ">=8"
}
},
"node_modules/is-plain-obj": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
"integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@ -3076,9 +3159,9 @@
}
},
"node_modules/known-css-properties": {
"version": "0.31.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz",
"integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==",
"version": "0.34.0",
"resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz",
"integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==",
"dev": true
},
"node_modules/koalas": {
@ -3326,9 +3409,12 @@
}
},
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/merge2": {
"version": "1.4.1",
@ -3353,9 +3439,9 @@
"integrity": "sha512-YtNUgIojy1brPWluzA/lE+vf21Tf4qgfs9vqbgY0tFZTsLqKkc+P/UHjf1UrLjB0RSqmPbNm3dihC/HvkqZnTg=="
},
"node_modules/micromatch": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
@ -3520,9 +3606,9 @@
}
},
"node_modules/netflux-websocket": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/netflux-websocket/-/netflux-websocket-1.2.0.tgz",
"integrity": "sha512-CNQF1wd/UOCmnfaWDATi5vTMfIpMm0Zghy1Fkvr5p7Q70wJdT85RdtnQvsqfLU5AXMUKwjeP1GgxMyAAdRUeJA=="
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/netflux-websocket/-/netflux-websocket-1.2.1.tgz",
"integrity": "sha512-8oQOyEyh0MCnifNIfyvkNXpEELlVRzDleRivRgsDGh+5ZDG109axweVZ0RIOIpkQmTZk4/xVsBk/oLXpMSWEOw=="
},
"node_modules/node-releases": {
"version": "2.0.14",
@ -3791,14 +3877,14 @@
}
},
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w=="
},
"node_modules/picocolors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
"dev": true
},
"node_modules/picomatch": {
@ -3832,9 +3918,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.38",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"version": "8.4.47",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"dev": true,
"funding": [
{
@ -3852,8 +3938,8 @@
],
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.2.0"
"picocolors": "^1.1.0",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@ -3872,9 +3958,9 @@
}
},
"node_modules/postcss-resolve-nested-selector": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
"integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz",
"integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==",
"dev": true
},
"node_modules/postcss-safe-parser": {
@ -3903,6 +3989,19 @@
"postcss": "^8.4.31"
}
},
"node_modules/postcss-selector-parser": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@ -4124,11 +4223,11 @@
}
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dependencies": {
"side-channel": "^1.0.4"
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
@ -4273,9 +4372,9 @@
}
},
"node_modules/requirejs": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz",
"integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.7.tgz",
"integrity": "sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==",
"bin": {
"r_js": "bin/r.js",
"r.js": "bin/r.js"
@ -4401,9 +4500,9 @@
}
},
"node_modules/send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
@ -4429,28 +4528,38 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"dependencies": {
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.18.0"
"send": "0.19.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/serve-static/node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"engines": {
"node": ">= 0.8"
}
},
"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==",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dependencies": {
"define-data-property": "^1.1.1",
"get-intrinsic": "^1.2.1",
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0"
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@ -4512,13 +4621,17 @@
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -4576,9 +4689,9 @@
}
},
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@ -4681,9 +4794,9 @@
}
},
"node_modules/stylelint": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz",
"integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==",
"version": "16.9.0",
"resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.9.0.tgz",
"integrity": "sha512-31Nm3WjxGOBGpQqF43o3wO9L5AC36TPIe6030Lnm13H3vDMTcS21DrLh69bMX+DBilKqMMVLian4iG6ybBoNRQ==",
"dev": true,
"funding": [
{
@ -4696,17 +4809,17 @@
}
],
"dependencies": {
"@csstools/css-parser-algorithms": "^2.6.3",
"@csstools/css-tokenizer": "^2.3.1",
"@csstools/media-query-list-parser": "^2.1.11",
"@csstools/selector-specificity": "^3.1.1",
"@csstools/css-parser-algorithms": "^3.0.1",
"@csstools/css-tokenizer": "^3.0.1",
"@csstools/media-query-list-parser": "^3.0.1",
"@csstools/selector-specificity": "^4.0.0",
"@dual-bundle/import-meta-resolve": "^4.1.0",
"balanced-match": "^2.0.0",
"colord": "^2.9.3",
"cosmiconfig": "^9.0.0",
"css-functions-list": "^3.2.2",
"css-tree": "^2.3.1",
"debug": "^4.3.4",
"debug": "^4.3.6",
"fast-glob": "^3.3.2",
"fastest-levenshtein": "^1.0.16",
"file-entry-cache": "^9.0.0",
@ -4714,24 +4827,24 @@
"globby": "^11.1.0",
"globjoin": "^0.1.4",
"html-tags": "^3.3.1",
"ignore": "^5.3.1",
"ignore": "^5.3.2",
"imurmurhash": "^0.1.4",
"is-plain-object": "^5.0.0",
"known-css-properties": "^0.31.0",
"known-css-properties": "^0.34.0",
"mathml-tag-names": "^2.1.3",
"meow": "^13.2.0",
"micromatch": "^4.0.7",
"micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"picocolors": "^1.0.1",
"postcss": "^8.4.38",
"postcss-resolve-nested-selector": "^0.1.1",
"postcss": "^8.4.41",
"postcss-resolve-nested-selector": "^0.1.6",
"postcss-safe-parser": "^7.0.0",
"postcss-selector-parser": "^6.1.0",
"postcss-selector-parser": "^6.1.2",
"postcss-value-parser": "^4.2.0",
"resolve-from": "^5.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^7.1.0",
"supports-hyperlinks": "^3.0.0",
"supports-hyperlinks": "^3.1.0",
"svg-tags": "^1.0.0",
"table": "^6.8.2",
"write-file-atomic": "^5.0.1"
@ -4833,28 +4946,6 @@
"stylelint": "^16.0.2"
}
},
"node_modules/stylelint/node_modules/@csstools/selector-specificity": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz",
"integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/csstools"
},
{
"type": "opencollective",
"url": "https://opencollective.com/csstools"
}
],
"engines": {
"node": "^14 || ^16 || >=18"
},
"peerDependencies": {
"postcss-selector-parser": "^6.0.13"
}
},
"node_modules/stylelint/node_modules/@nodelib/fs.stat": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
@ -4923,25 +5014,13 @@
}
}
},
"node_modules/stylelint/node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true,
"bin": {
"cssesc": "bin/cssesc"
},
"engines": {
"node": ">=4"
}
},
"node_modules/stylelint/node_modules/debug": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@ -5025,15 +5104,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/stylelint/node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
"dev": true,
"engines": {
"node": ">= 4"
}
},
"node_modules/stylelint/node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -5090,9 +5160,9 @@
}
},
"node_modules/stylelint/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==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
"node_modules/stylelint/node_modules/parse-json": {
@ -5122,19 +5192,6 @@
"node": ">=8"
}
},
"node_modules/stylelint/node_modules/postcss-selector-parser": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
"integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/stylelint/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@ -5224,9 +5281,9 @@
}
},
"node_modules/supports-hyperlinks": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
"integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz",
"integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0",
@ -5234,6 +5291,9 @@
},
"engines": {
"node": ">=14.18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/svg-tags": {

View File

@ -1,7 +1,7 @@
{
"name": "cryptpad",
"description": "a collaborative office suite that is end-to-end encrypted and open-source",
"version": "2024.6.1",
"version": "2024.9.0",
"license": "AGPL-3.0+",
"repository": {
"type": "git",
@ -22,7 +22,7 @@
"chainpad-crypto": "^0.2.5",
"chainpad-listmap": "^1.1.0",
"chainpad-netflux": "^1.2.0",
"chainpad-server": "^5.2.0",
"chainpad-server": "^5.2.2",
"ckeditor": "npm:ckeditor4@~4.22.1",
"codemirror": "^5.19.0",
"components-font-awesome": "^4.6.3",
@ -30,12 +30,12 @@
"croppie": "^2.5.0",
"dragula": "3.7.2",
"drawio": "github:cryptpad/drawio-npm#npm-21.8.2+5",
"express": "~4.19.2",
"express": "~4.21.0",
"file-saver": "1.3.1",
"fs-extra": "^7.0.0",
"get-folder-size": "^2.0.1",
"html2canvas": "^1.4.0",
"http-proxy-middleware": "^2.0.6",
"http-proxy-middleware": "^3.0.2",
"hyper-json": "~1.4.0",
"jquery": "3.6.0",
"json.sortify": "~2.1.0",
@ -44,7 +44,7 @@
"localforage": "^1.5.2",
"marked": "^4.3.0",
"mathjax": "3.0.5",
"netflux-websocket": "^1.2.0",
"netflux-websocket": "^1.2.1",
"notp": "^2.0.3",
"nthen": "0.1.8",
"open-sans-fontface": "^1.4.0",
@ -53,7 +53,7 @@
"prompt-confirm": "^2.0.4",
"pull-stream": "^3.6.1",
"require-css": "0.1.10",
"requirejs": "2.3.5",
"requirejs": "2.3.7",
"requirejs-plugins": "^1.0.2",
"saferphore": "0.0.1",
"scrypt-async": "1.2.0",
@ -69,7 +69,7 @@
"devDependencies": {
"eslint": "^8.57.0",
"eslint-plugin-compat": "^4.2.0",
"stylelint": "^16.6.1",
"stylelint": "^16.9.0",
"stylelint-config-standard-less": "^3.0.1"
},
"overrides": {
@ -82,6 +82,7 @@
"install:components": "node scripts/copy-components.js",
"start": "node server.js",
"dev": "DEV=1 node server.js",
"windev": "set DEV=1& node server.js",
"fresh": "FRESH=1 node server.js",
"offline": "FRESH=1 OFFLINE=1 node server.js",
"offlinedev": "DEV=1 OFFLINE=1 node server.js",

View File

@ -28,8 +28,7 @@ The most recent version and all past release notes can be found on [releases pag
## Setup using Docker
You can find the `Dockerfile`, `docker-compose.yml` and `docker-entrypoint.sh` files at the root of this repository. We also publish every release on [Docker Hub](https://hub.docker.com/r/cryptpad/cryptpad) as AMD64 & ARM64 official images.
You can find `Dockerfile`, `docker-compose.yml` and `docker-entrypoint.sh` files at the root of this repository. We also publish every release on [Docker Hub](https://hub.docker.com/r/cryptpad/cryptpad) as AMD64 & ARM64 official images.
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.

View File

@ -5,6 +5,6 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
for f in ../customize.dist/favicon/*.png; do
base="$(basename $f ".png")"
magick convert $f -define icon:auto-resize=16,24,32,48,64,72,96,128,256 "$base.ico"
base="$(basename $f ".png")"
magick convert $f -define icon:auto-resize=16,24,32,48,64,72,96,128,256 "$base.ico"
done

65
scripts/testcrypto.js Normal file
View File

@ -0,0 +1,65 @@
// SPDX-FileCopyrightText: 2024 XWiki CryptPad Team <contact@cryptpad.org> and contributors
//
// SPDX-License-Identifier: AGPL-3.0-or-later
let SodiumNative = require('sodium-native');
let Nacl = require('tweetnacl/nacl-fast');
let LibSodium = require('libsodium-wrappers');
let msgStr = "This is a test";
let keys = Nacl.sign.keyPair();
let pub = keys.publicKey;
let msg = Nacl.util.decodeUTF8(msgStr);
let signedMsg = Nacl.sign(msg, keys.secretKey);
let sig = signedMsg.subarray(0, 64);
LibSodium.ready.then(() => {
/*
console.log('tweetnacl open');
console.log(!!Nacl.sign.open(signedMsg, pub));
console.log('tweetnacl detached');
console.log(Nacl.sign.detached.verify(msg, sig, pub));
console.log('sodium-native open');
console.log(SodiumNative.crypto_sign_open(msg, signedMsg, pub));
console.log('sodium-native detached');
console.log(SodiumNative.crypto_sign_verify_detached(sig, msg, pub));
LibSodium.ready.then(() => {
console.log('libsodium open');
console.log(!!LibSodium.crypto_sign_open(signedMsg, pub));
console.log('libsodium detached');
console.log(LibSodium.crypto_sign_verify_detached(sig, msg, pub));
});
*/
const n = 10000;
let a;
console.log('start sodium-native');
a = +new Date();
for (let i = 0; i < n; i++) {
SodiumNative.crypto_sign_open(msg, signedMsg, pub);
SodiumNative.crypto_sign_verify_detached(sig, msg, pub);
}
console.log('end sodium-native ', (+new Date() - a), ' ms');
console.log('start libsodium');
a = +new Date();
for (let i = 0; i < n; i++) {
LibSodium.crypto_sign_open(signedMsg, pub);
LibSodium.crypto_sign_verify_detached(sig, msg, pub);
}
console.log('end libsodium ', (+new Date() - a), ' ms');
console.log('start tweetnacl');
a = +new Date();
for (let i = 0; i < n; i++) {
Nacl.sign.open(signedMsg, pub);
Nacl.sign.detached.verify(msg, sig, pub);
}
console.log('end tweetnacl ', (+new Date() - a), ' ms');
});

View File

@ -0,0 +1,7 @@
{"owners":["TestOwner"],"validateKey":"TestKey","channel":"0","created":1721035117462}
[0,"test","MSG","test",1721035117969]
[0,"test","MSG","test2",1721035117969]
[0,"test","MSG","test3",1721035117969]
[0,"test","MSG","test4",1721035117969]
[0,"test","MSG","test5",1721035117969]
[0,"test","MSG","test6",1721035117969]

View File

@ -0,0 +1,5 @@
["RESTRICT_ACCESS",[true],1721035145090]
["ADD_ALLOWED",["NewAllowedKeyNewAllowedKeyNewAllowedKeyNewAl"],1721035148115]
["ADD_PENDING_OWNERS",["PendingOwner"],1721035151295]
["RESTRICT_ACCESS",[false],1721035155836]
["RESTRICT_ACCESS",[true],1721035156728]

View File

@ -0,0 +1,7 @@
{"owners":["TestOwner"],"validateKey":"TestKey","channel":"0","created":1721035117462}
[0,"test","MSG","test",1721035117969]
[0,"test","MSG","test2",1721035117969]
[0,"test","MSG","test3",1721035117969]
[0,"test","MSG","test4",1721035117969]
[0,"test","MSG","test5",1721035117969]
[0,"test","MSG","test6",1721035117969]

View File

@ -0,0 +1 @@
{"owners":["TestOwner"],"validateKey":"TestKey","channel":"0","created":1721035117462}

View File

@ -0,0 +1,6 @@
[0,"test","MSG","test",1721035117969]
[0,"test","MSG","test2",1721035117969]
[0,"test","MSG","test3",1721035117969]
[0,"test","MSG","test4",1721035117969]
[0,"test","MSG","test5",1721035117969]
[0,"test","MSG","test6",1721035117969]

View File

@ -0,0 +1,6 @@
{"owners":["TestOwner"],"validateKey":"TestKey","channel":"0","created":1721035117462}
["RESTRICT_ACCESS",[true],1721035145090]
["ADD_ALLOWED",["NewAllowedKeyNewAllowedKeyNewAllowedKeyNewAl"],1721035148115]
["ADD_PENDING_OWNERS",["PendingOwner"],1721035151295]
["RESTRICT_ACCESS",[false],1721035155836]
["RESTRICT_ACCESS",[true],1721035156728]

View File

@ -0,0 +1,6 @@
[0,"test","MSG","test",1721035117969]
[0,"test","MSG","test2",1721035117969]
[0,"test","MSG","test3",1721035117969]
[0,"test","MSG","test4",1721035117969]
[0,"test","MSG","test5",1721035117969]
[0,"test","MSG","test6",1721035117969]

View File

@ -0,0 +1,6 @@
[0,"test","MSG","test",1721035117969]
[0,"test","MSG","test2",1721035117969]
[0,"test","MSG","test3",1721035117969]
[0,"test","MSG","test4",1721035117969]
[0,"test","MSG","test5",1721035117969]
[0,"test","MSG","test6",1721035117969]

View File

@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
//
// SPDX-License-Identifier: AGPL-3.0-or-later
const Store = require("../../lib/storage/file");
const Meta = require("../../lib/metadata");
const nThen = require('nthen');
let chanOld = '00000000000000000000000000000000';
let chanOldUpdated = '00000000000000000000000000000001';
let chanNew = '00000000000000000000000000000002';
let chanNewUpdated = '00000000000000000000000000000003';
let chanNoMeta = '00000000000000000000000000000004';
Store.create({
filePath: './test-data/'
}, (err, store) => {
if (err) { return void console.error(err); }
const readMetadata = (channel, cb) => {
const ref = {};
const h = Meta.createLineHandler(ref, console.error);
store.readChannelMetadata(channel, h, () => {
cb(ref && ref.meta);
});
};
nThen(w => {
readMetadata(chanOld, w(meta => {
if (!meta || meta.validateKey !== "TestKey") {
console.log('OldChanNoUpdate', meta);
throw new Error("Error with old channel without metadata update");
}
}));
readMetadata(chanOldUpdated, w(meta => {
if (!meta || meta.validateKey !== "TestKey" || !meta.restricted || !meta.allowed.includes('NewAllowedKeyNewAllowedKeyNewAllowedKeyNewAl')) {
console.log('OldChanUpdate', meta);
throw new Error("Error with old channel with metadata updates");
}
}));
readMetadata(chanNew, w(meta => {
if (!meta || meta.validateKey !== "TestKey") {
console.log('NewChanNoUpdate', meta);
throw new Error("Error with new channel without metadata update");
}
}));
readMetadata(chanNewUpdated, w(meta => {
if (!meta || meta.validateKey !== "TestKey" || !meta.restricted || !meta.allowed.includes('NewAllowedKeyNewAllowedKeyNewAllowedKeyNewAl')) {
console.log('NewChanUpdate', meta);
throw new Error("Error with new channel with metadata updates");
}
}));
readMetadata(chanNoMeta, w(meta => {
if (meta && Object.keys(meta).length) {
console.log('NoMetadataChan', meta);
throw new Error("Error with channel without metadata");
}
}));
}).nThen(() => {
console.log('Success');
process.exit(1);
});
});

View File

@ -22,12 +22,48 @@
flex-flow: column;
font: @colortheme_app-font;
input, textarea, .cp-appblock {
&:focus-visible {
outline: @variables_focus_style;
}
}
.cp-admin-customize-logo {
padding: 1em;
img {
max-height: 250px;
}
}
#cp-sidebarlayout-container {
#cp-sidebarlayout-rightside {
.cp-sidebarlayout-element[data-item] {
div#cp-admin-table-container {
overflow-x: auto;
.cp-sidebar-table#cp-admin-table {
tr {
display: flex;
}
th, td {
flex: 1;
word-wrap: break-word;
white-space: normal;
min-width: 13rem;
margin-right: 0px;
}
@media (max-width: @browser_media-not-small) {
width: 100%;
tr {
width: 100%;
}
th, td {
margin-right: 0;
min-width: 7rem;
}
}
}
}
}
}
}
.cp-admin-color-current {
width: 20px;
height: 20px;

View File

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta name="referrer" content="no-referrer" />
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
<link href="/customize/src/outer.css?ver=1.3.2" rel="stylesheet" type="text/css">
</head>
<body>

View File

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/admin/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/admin/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.7"></script>
<style>
.loading-hidden { display: none; }
</style>

View File

@ -578,23 +578,38 @@ define([
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);
flushCache();
var isChecked = APP.instanceStatus.enforceMFA;
function showConfirmation(isChecked, setState) {
const confirmationContent = isChecked ? Messages.admin_mfa_confirm_disable : Messages.admin_mfa_confirm_enable;
UI.confirm(confirmationContent, function (confirmed) {
if (!confirmed) {
// User canceled their changes, restore the checkbox value
setState(isChecked);
return;
}
// User confirmed their changes, call the command and update the state
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);
} else {
APP.updateStatus(function () {
setState(APP.instanceStatus.enforceMFA);
flushCache();
});
}
});
});
});
},
}
showConfirmation(isChecked, setState);
}
});
var getInstanceString = function (attr) {
var val = APP.instanceStatus[attr];
var type = typeof(val);
@ -1101,6 +1116,9 @@ define([
""
];
var list = blocks.table(header, []);
list.setAttribute('id', 'cp-admin-table');
let div = blocks.block([list]);
div.setAttribute('id', 'cp-admin-table-container');
var nav = blocks.nav([button, refreshButton]);
var form = blocks.form([
@ -1201,7 +1219,7 @@ define([
});
});
cb([form, list]);
cb([form, div]);
});
var getBlockId = (val) => {
@ -1413,6 +1431,9 @@ define([
""
];
var list = blocks.table(header, []);
list.setAttribute('id', 'cp-admin-table');
let div = blocks.block([list]);
div.setAttribute('id', 'cp-admin-table-container');
var nav = blocks.nav([button, refreshButton]);
@ -1581,7 +1602,7 @@ define([
});
});
cb([form, list]);
cb([form, div]);
});
// Msg.admin_defaultlimitHint, .admin_defaultlimitTitle
@ -1741,6 +1762,9 @@ define([
Messages.admin_note
];
var table = blocks.table(header, []);
table.setAttribute('id', 'cp-admin-table');
let div = blocks.block([table]);
div.setAttribute('id', 'cp-admin-table-container');
let $table = $(table).hide();
APP.refreshLimits = function () {
@ -1798,7 +1822,7 @@ define([
});
};
APP.refreshLimits();
cb(table);
cb(div);
});
// Msg.admin_accountMetadataHint.admin_accountMetadataTitle
@ -3594,6 +3618,9 @@ define([
];
var table = blocks.table(header, []);
table.setAttribute('id', 'cp-admin-table');
let div = blocks.block([table]);
div.setAttribute('id', 'cp-admin-table-container');
const onRefresh = function () {
sFrameChan.query('Q_ADMIN_RPC', {
@ -3626,7 +3653,7 @@ define([
onRefresh();
onRefreshPerformance.reg(onRefresh);
cb(table);
cb(div);
});

View File

@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js"></script>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js?ver=2.3.7"></script>
<style>
.report {

View File

@ -9,6 +9,6 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js"></script>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body>

View File

@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" href="/customize/favicon/main-favicon.png" id="favicon"/>
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="html">
<noscript></noscript>

View File

@ -39,7 +39,7 @@
.tui-full-calendar-confirm {
span, i {
padding: 0.5rem;
padding: 0 0.5rem;
}
span {
padding-left: 0;
@ -133,6 +133,13 @@
width: 540px;
max-width: 100%;
max-height: 100%;
border-radius: @variables_radius_L;
@media screen and (max-width : @browser_media-medium-screen){
position: fixed;
top: 5.5rem;
overflow-y: auto;
max-height: calc(100% - 6rem);
}
}
}
#tui-full-calendar-popup-arrow {
@ -153,10 +160,12 @@
border-color: @cp_calendar-border !important;
}
.tui-full-calendar-popup {
border-radius: @variables_radius_L;
}
.tui-full-calendar-popup-container {
.tui-full-calendar-section-allday{
&:focus {
outline: @cryptpad_color_brand solid 2px;
}
}
min-width: 100%;
background: @cp_flatpickr-bg;
color: @cryptpad_text_col;
@ -208,6 +217,9 @@
text-overflow: ellipsis;
font: @colortheme_app-font;
padding: 0 10px;
&:focus{
outline: @cryptpad_color_brand solid 2px;
}
}
input { flex: 1; }
}
@ -403,14 +415,16 @@
& > input {
height: 40px;
}
.tui-full-calendar-content{
&:focus{
outline: @cryptpad_color_brand solid 2px;
}
}
}
// margin-bottom: 20px;
input {
width: 80px;
margin-right: 0.3rem;
}
.fa-plus{
margin-left:0.3rem;
margin-right: 0.5rem;
}
}
}
@ -633,6 +647,9 @@
color: @cp_sidebar-left-active-fg;
border: 0px;
}
&:focus-visible {
outline: @variables_focus_style;
}
i {
margin-left: 5px;
}

View File

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta name="referrer" content="no-referrer" />
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
<link href="/customize/src/outer.css?ver=1.3.2" rel="stylesheet" type="text/css">
</head>
<body>

View File

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/calendar/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/calendar/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.7"></script>
<style>
.loading-hidden { display: none; }
</style>

View File

@ -2063,6 +2063,15 @@ APP.recurrenceRule = {
editor.setOption('readOnly', false);
editor.setOption('autoRefresh', true);
editor.setOption('gutters', []);
editor.on('keydown', function (editor, e) {
if (e.which === 27) {
let $next = $(e.target).closest('.tui-full-calendar-popup-section').next();
if ($next.length) {
$next.find('#tui-full-calendar-schedule-start-date').focus();
}
e.stopPropagation();
}
});
cm.configureTheme(common, function () {});
editor.setValue(oldEventBody);
@ -2147,6 +2156,13 @@ APP.recurrenceRule = {
$el.find('input').attr('autocomplete', 'off');
$el.find('.tui-full-calendar-dropdown-button').addClass('btn btn-secondary');
$el.find('.tui-full-calendar-popup-close').addClass('btn btn-cancel fa fa-times cp-calendar-close').empty();
$el.find('.tui-full-calendar-section-allday').attr('tabindex', 0);
$el.find('.cp-calendar-close').attr('tabindex',-1);
$el.find('.tui-full-calendar-section-allday').keydown(function (e) {
if (e.which === 13) {
$(this).click();
}
});
var $container = $el.closest('.tui-full-calendar-floating-layer');
$container.addClass('cp-calendar-popup-flex');
@ -2209,6 +2225,7 @@ APP.recurrenceRule = {
setFormat(allDay);
});
});
UI.addTabListener(el);
};
var onCalendarEditPopup = function (el) {
var $el = $(el);
@ -2244,6 +2261,7 @@ APP.recurrenceRule = {
var data = ev.schedule || {};
var id = data.id;
UI.addTabListener(el);
if (!id) { return; }
if (id.indexOf('|') === -1) { return; } // Original event ID doesn't contain |

View File

@ -15,5 +15,5 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<div id="cp-progress"></div>
<iframe-placeholder>
<script type="text/javascript" src="/checkup/dependency-warning.js?ver=1.0.1"></script>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js"></script>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js?ver=2.3.7"></script>

View File

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<html class="cp-app-noscroll cp-app-print">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/checkup/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/checkup/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body class="cp-app-checkup">
</body>

View File

@ -574,7 +574,7 @@ define([
});
assert(function (cb, msg) {
var support = ApiConfig.supportMailbox;
var support = ApiConfig.supportMailboxKey;
setWarningClass(msg);
msg.appendChild(h('span', [
"This instance's encrypted support ticket functionality has not been enabled. This can make it difficult for its users to safely report issues that concern sensitive information. ",

View File

@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js"></script>
<script data-bootload="main.js" data-main="/common/boot.js" src="/components/requirejs/require.js?ver=2.3.7"></script>
</head>
<body>
<div id="cp-progress"></div>

View File

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta name="referrer" content="no-referrer" />
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/common/sframe-app-outer.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/common/sframe-app-outer.js" data-main="/common/boot.js?ver=1.0" src="/components/requirejs/require.js?ver=2.3.7"></script>
<link href="/customize/src/outer.css?ver=1.3.2" rel="stylesheet" type="text/css">
<link id="favicon-ico" type="image/x-icon" rel="icon"
data-main-favicon="/customize/favicon/main-favicon-code.ico"

View File

@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script src="/customize/pre-loading.js?ver=1.1"></script>
<link href="/customize/src/pre-loading.css?ver=1.0" rel="stylesheet" type="text/css">
<script async data-bootload="/code/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/code/inner.js" data-main="/common/sframe-boot.js?ver=1.11" src="/components/requirejs/require.js?ver=2.3.7"></script>
<style>
.loading-hidden { display: none; }
#editor1 { display: none; }

View File

@ -164,12 +164,12 @@ define([
dialog.okButton = function (content, classString) {
var sel = typeof(classString) === 'string'? 'button.ok.' + classString:'button.btn.ok.primary';
return h(sel, { tabindex: '2', }, content || Messages.okButton);
return h(sel, content || Messages.okButton);
};
dialog.cancelButton = function (content, classString) {
var sel = typeof(classString) === 'string'? 'button.' + classString:'button.btn.cancel';
return h(sel, { tabindex: '1'}, content || Messages.cancelButton);
return h(sel, content || Messages.cancelButton);
};
dialog.message = function (text) {
@ -577,7 +577,7 @@ define([
return frame;
};
let addTabListener = frame => {
let addTabListener = UI.addTabListener = frame => {
// find focusable elements
let modalElements = $(frame).find('a, button, input, [tabindex]:not([tabindex="-1"]), textarea').filter(':visible').filter(':not(:disabled)');
@ -670,6 +670,7 @@ define([
$modal: $blockContainer,
show: function () {
$blockContainer.css('display', 'flex');
addTabListener($blockContainer);
},
hide: hide
};
@ -719,6 +720,7 @@ define([
Notifier.notify();
});
addTabListener(frame);
return {
element: frame,
delete: close
@ -770,7 +772,7 @@ define([
document.body.appendChild(frame);
setTimeout(function () {
$(input).select().focus();
addTabListener(frame);
Notifier.notify();
});
};
@ -778,7 +780,6 @@ define([
UI.confirm = function (msg, cb, opt, force) {
cb = cb || function () {};
opt = opt || {};
var message;
if (typeof(msg) === 'string') {
if (!force) { msg = Util.fixHTML(msg); }

View File

@ -623,13 +623,22 @@ define([
var appType = (common.getMetadataMgr().getMetadata().type || 'pad').toUpperCase();
data = data || {};
if (!callback && data.callback) { callback = data.callback; }
let makeButton = function(iconClasses, buttonClasses, title, text) {
const ariaLabel = title || text || '';
return $(h('button', {
class: buttonClasses,
title: title,
'aria-label': ariaLabel
}, [
iconClasses ? h('i', { class: iconClasses }) : null,
text ? h('span', { class: 'cp-toolbar-drawer-element' }, text) : null
]));
};
switch (type) {
case 'export':
button = $('<button>', {
'class': 'fa fa-download cp-toolbar-icon-export',
title: Messages.exportButtonTitle,
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.exportButton));
button = makeButton('fa fa-download', 'cp-toolbar-icon-export', Messages.exportButtonTitle, Messages.exportButton);
button
.click(common.prepareFeedback(type))
.click(UI.clearTooltipsDelay);
@ -638,34 +647,28 @@ define([
}
break;
case 'import':
button = $('<button>', {
'class': 'fa fa-upload cp-toolbar-icon-import',
title: Messages.importButtonTitle,
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.importButton));
var importer = importContent((data && data.binary) ? 'application/octet-stream' : 'text/plain', callback, {
accept: data ? data.accept : undefined,
binary: data ? data.binary : undefined
});
button = makeButton('fa fa-upload', 'cp-toolbar-icon-import', Messages.importButtonTitle, Messages.importButton);
var importer = importContent((data && data.binary) ? 'application/octet-stream' : 'text/plain', callback, {
accept: data ? data.accept : undefined,
binary: data ? data.binary : undefined
});
var handler = data.first? function () {
data.first(function () {
importer(); // Make sure we don't pass arguments to importer
});
}: importer; //importContent;
button
.click(common.prepareFeedback(type))
.click(function () {
handler();
UI.clearTooltipsDelay();
var handler = data.first? function () {
data.first(function () {
importer(); // Make sure we don't pass arguments to importer
});
}: importer; //importContent;
button
.click(common.prepareFeedback(type))
.click(function () {
handler();
UI.clearTooltipsDelay();
});
//}
break;
case 'upload':
button = $('<button>', {
'class': 'btn btn-primary new',
title: Messages.uploadButtonTitle,
}).append($('<span>', {'class':'fa fa-upload'})).append(' '+Messages.uploadButton);
button = makeButton('fa fa-upload', 'btn btn-primary new', Messages.uploadButtonTitle, Messages.uploadButton);
if (!data.FM) { return; }
var $input = $('<input>', {
'type': 'file',
@ -697,9 +700,7 @@ define([
});
break;
case 'copy':
button = $('<button>', {
'class': 'fa fa-files-o cp-toolbar-icon-import',
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.makeACopy));
button = makeButton('fa fa-files-o', 'cp-toolbar-icon-import', '', Messages.makeACopy);
button
.click(common.prepareFeedback(type))
.click(function () {
@ -710,9 +711,7 @@ define([
case 'importtemplate':
if (!AppConfig.enableTemplates) { return; }
if (!common.isLoggedIn()) { return; }
button = $('<button>', {
'class': 'fa fa-upload cp-toolbar-icon-import',
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.template_import));
button = makeButton('fa fa-upload', 'cp-toolbar-icon-import', '', Messages.template_import);
button
.click(common.prepareFeedback(type))
.click(function () {
@ -724,9 +723,7 @@ define([
case 'template':
if (!AppConfig.enableTemplates) { return; }
if (!common.isLoggedIn()) { return; }
button = $('<button>', {
'class': 'cptools cptools-new-template cp-toolbar-icon-template',
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.saveTemplateButton));
button = makeButton('cptools cptools-new-template', 'cp-toolbar-icon-template', '', Messages.saveTemplateButton);
if (data.rt || data.callback) {
button
.click(function () {
@ -774,9 +771,7 @@ define([
}
break;
case 'forget':
button = $('<button>', {
'class': "fa fa-trash cp-toolbar-icon-forget"
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.fc_delete));
button = makeButton('fa fa-trash', 'cp-toolbar-icon-forget', '', Messages.fc_delete);
callback = typeof callback === "function" ? callback : function () {};
button
.click(common.prepareFeedback(type))
@ -837,25 +832,16 @@ define([
])).click(common.prepareFeedback(type));
break;
case 'print':
button = $('<button>', {
title: Messages.printButtonTitle2,
'class': "fa fa-print cp-toolbar-icon-print",
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.printText));
button = makeButton('fa fa-print', 'cp-toolbar-icon-print', Messages.printButtonTitle2, Messages.printText);
break;
case 'history':
if (!AppConfig.enableHistory) {
button = $('<span>');
break;
}
button = $('<button>', {
title: Messages.historyButton,
'aria-label': Messages.historyButton,
'class': "fa fa-history cp-toolbar-icon-history",
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.historyText));
button = makeButton('fa fa-history', 'cp-toolbar-icon-history', Messages.historyButton, Messages.historyText, Messages.historyButton);
if (data.histConfig) {
button
.click(common.prepareFeedback(type))
.on('click', function () {
button.click(common.prepareFeedback(type)).on('click', function () {
common.getHistory(data.histConfig);
UI.clearTooltipsDelay();
});
@ -879,9 +865,10 @@ define([
if (callback) { button.click(callback); }
break;
case 'storeindrive':
button = $(h('button.cp-toolbar-storeindrive.fa.fa-hdd-o', {
button = $(h('button.cp-toolbar-storeindrive', {
style: 'display:none;'
}, [
h('i.fa.fa-hdd-o'),
h('span.cp-toolbar-name.cp-toolbar-drawer-element', Messages.toolbar_storeInDrive)
])).click(common.prepareFeedback(type)).click(function () {
$(button).hide();
@ -902,10 +889,7 @@ define([
});
break;
case 'hashtag':
button = $('<button>', {
'class': 'fa fa-hashtag cp-toolbar-icon-hashtag',
title: Messages.tags_title,
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.fc_hashtag));
button = makeButton('fa fa-hashtag', 'cp-toolbar-icon-hashtag', Messages.tags_title, Messages.fc_hashtag);
button.click(common.prepareFeedback(type))
.click(function () {
common.isPadStored(function (err, data) {
@ -950,11 +934,8 @@ define([
//updateIcon(data.element.is(':visible'));
break;
case 'properties':
button = $('<button>', {
'class': 'fa fa-info-circle cp-toolbar-icon-properties',
title: Messages.propertiesButtonTitle,
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'})
.text(Messages.propertiesButton))
button = makeButton('fa fa-info-circle', 'cp-toolbar-icon-properties', Messages.propertiesButtonTitle, Messages.propertiesButton);
button
.click(common.prepareFeedback(type))
.click(function () {
var isTop;
@ -970,11 +951,8 @@ define([
});
break;
case 'save': // OnlyOffice save
button = $('<button>', {
'class': 'fa fa-save',
title: Messages.settings_save,
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'})
.text(Messages.settings_save))
button = makeButton('fa fa-save', '', Messages.settings_save, Messages.settings_save);
button
.click(function() {
common.prepareFeedback(type);
UI.clearTooltipsDelay();
@ -982,10 +960,7 @@ define([
if (callback) { button.click(callback); }
break;
case 'newpad':
button = $('<button>', {
title: Messages.newButtonTitle,
'class': 'fa fa-plus cp-toolbar-icon-newpad',
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.newButton));
button = makeButton('fa fa-plus', 'cp-toolbar-icon-newpad', Messages.newButtonTitle, Messages.newButton);
button
.click(common.prepareFeedback(type))
.click(function () {
@ -994,10 +969,7 @@ define([
});
break;
case 'snapshots':
button = $('<button>', {
title: Messages.snapshots_button,
'class': 'fa fa-camera cp-toolbar-icon-snapshots',
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.snapshots_button));
button = makeButton('fa fa-camera', 'cp-toolbar-icon-snapshots', Messages.snapshots_button,Messages.snapshots_button);
button
.click(common.prepareFeedback(type))
.click(function () {
@ -1280,6 +1252,7 @@ define([
kanban: 'kanban',
form: 'form',
whiteboard: 'whiteboard',
diagram: 'diagram',
};
var href = "https://docs.cryptpad.org/en/user_guide/applications.html";
@ -1607,10 +1580,10 @@ define([
]));
if (config.caretDown) {
$button.append(h('i.fa.fa-caret-down'));
$button.prepend(h('i.fa.fa-caret-down'));
}
if (config.angleDown) {
$button.append(h('i.fa.fa-angle-down'));
$button.prepend(h('i.fa.fa-angle-down'));
}
// Menu
@ -2510,10 +2483,21 @@ define([
});
var selected = -1;
var previous = function () {
selected = (selected === 0 ? types.length : selected) - 1;
$container.find('.cp-icons-element-selected').removeClass('cp-icons-element-selected');
let element = $container.find('#cp-newpad-icons-'+selected).addClass('cp-icons-element-selected');
if (element.hasClass('cp-app-disabled')) {
previous();
}
};
var next = function () {
selected = ++selected % types.length;
$container.find('.cp-icons-element-selected').removeClass('cp-icons-element-selected');
$container.find('#cp-newpad-icons-'+selected).addClass('cp-icons-element-selected');
let element = $container.find('#cp-newpad-icons-'+selected).addClass('cp-icons-element-selected');
if (element.hasClass('cp-app-disabled')) {
next();
}
};
$modal.off('keydown');
@ -2521,7 +2505,11 @@ define([
if (e.which === 9) {
e.preventDefault();
e.stopPropagation();
next();
if (e.shiftKey) {
previous();
} else {
next();
}
return;
}
if (e.which === 13) {
@ -3559,7 +3547,7 @@ define([
$(link).click(function (e) {
e.preventDefault();
e.stopPropagation();
var obj = { pw: msg.content.password || '' };
var obj = { pw: msg.content.password || '', f: 1 };
common.openURL(Hash.getNewPadURL(msg.content.href, obj));
});
@ -3615,7 +3603,7 @@ define([
// Add the pad to your drive
// This command will also add your mailbox to the metadata log
// The callback is called when the pad is stored, independantly of the metadata command
// The callback is called when the pad is stored, independently of the metadata command
if (data.calendar) {
var calendarModule = common.makeUniversal('calendar');
var calendarData = data.calendar;

View File

@ -2619,7 +2619,8 @@ define([
disableCache: localStorage['CRYPTPAD_STORE|disableCache'],
driveEvents: !rdyCfg.noDrive, //rdyCfg.driveEvents // Boolean
lastVisit: Number(localStorage.lastVisit) || undefined,
blockId: blockId
blockId: blockId,
blockHash: blockHash
};
common.userHash = userHash || LocalStore.getUserHash();

View File

@ -3568,7 +3568,8 @@ define([
if (APP.$content.data('readOnlyFolder') || !APP.editable) { return; }
var isInRoot = currentPath[0] === ROOT;
var $element = $('<li>', {
'class': 'cp-app-drive-element-row cp-app-drive-new-ghost'
'class': 'cp-app-drive-element-row cp-app-drive-new-ghost',
'tabindex': 0
}).prepend($addIcon.clone()).appendTo($list);
$element.append($('<span>', {'class': 'cp-app-drive-element-name'})
.text(Messages.fm_newButton));
@ -3587,6 +3588,12 @@ define([
window.setTimeout(function () { modal.show(); });
addNewPadHandlers($modal, isInRoot);
});
$element.keydown(function(){
if (event.which === 13) {
event.stopPropagation();
$element.click();
}
});
};
// Drive content toolbar

View File

@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<!DOCTYPE html>
<head>
<title>About our feedback api</title>
<script data-bootload="feedback-main.js" data-main="/common/boot.js" src="/components/requirejs/require.js"></script>
<script data-bootload="feedback-main.js" data-main="/common/boot.js" src="/components/requirejs/require.js?ver=2.3.7"></script>
<style>
body {
max-width: 60vw;

View File

@ -123,8 +123,19 @@ define([
if (!seed) { return; }
return ANIMALS[seed % ANIMALS.length] || '';
};
//this regex identifies both discord and unicode emojis (with optional skin tone modifiers) and complex zwj emoji sequences
const emojiWithZWJRegex = /(?:\p{Extended_Pictographic}(?:\p{Emoji_Modifier}|\uFE0F)?(?:\u200D\p{Extended_Pictographic}(?:\p{Emoji_Modifier}|\uFE0F)?)*|\p{Extended_Pictographic})/gu;
var getPrettyInitials = MT.getPrettyInitials = function (name) {
let matches = name.match(emojiWithZWJRegex);
if (matches && name.startsWith(matches[0])) {
return matches[0];
}
else {
//this is for removing all trailing white characters and unnecessary/redundant emojis
name = name.replace(emojiWithZWJRegex, '');
name = name.replace(/\uFE0F/g, '').replace(/\u200D/g, '').replace(/\u2060/g, '');
name = name.trim();
}
var parts = name.split(/\s+/);
var text;
if (parts.length > 1) {

View File

@ -48,7 +48,8 @@ define([
data.password = priv.password;
// Access modal and the pad is not stored: get the hashes from outer
var hashes = priv.hashes || {};
data.href = Hash.hashToHref(hashes.editHash || hashes.fileHash, priv.app);
// For calendars, individual href is passed via opts
data.href = ((priv.app === 'calendar') && opts.href) || Hash.hashToHref(hashes.editHash || hashes.fileHash, priv.app);
if (hashes.viewHash) {
data.roHref = Hash.hashToHref(hashes.viewHash, priv.app);
}

View File

@ -129,6 +129,7 @@ define([
var obj = {
p: msg.content.isTemplate ? ['template'] : undefined,
t: teamNotification || undefined,
f: 1,
pw: msg.content.password || ''
};
common.openURL(Hash.getNewPadURL(msg.content.href, obj));

View File

@ -252,7 +252,7 @@ define([
list.push(userChannel);
if (store.data && store.data.blockId) {
//list.push(`${store.data.blockId}#block`); // NEXT 5.7.0?
list.push(`${store.data.blockId}#block`);
}
list.sort();
@ -2671,6 +2671,7 @@ define([
};
*/
var loadOnlyOffice = function () {
if (store.onlyoffice) { return; }
store.onlyoffice = OnlyOffice.init(store, function (ev, data, clients) {
clients.forEach(function (cId) {
postMessage(cId, 'OO_EVENT', {

View File

@ -62,6 +62,19 @@ define([
return channels;
};
let getTeamChannels = function (ctx, teamId) {
let team = Util.find(ctx.store, ['proxy', 'teams', teamId]);
if (!team) { return []; }
let channels = [team.channel];
let roster = team.keys.roster;
channels.push({
channel: roster.channel,
lastKnownHash: roster.lastKnownHash
});
return channels;
};
var getEdPublic = function (ctx, teamId) {
if (!teamId) { return Util.find(ctx.store, ['proxy', 'edPublic']); }
@ -155,6 +168,8 @@ define([
// If account trim history, get the correct channels here
if (data.account) {
channels = getAccountChannels(ctx);
} else if (data.team) {
channels = getTeamChannels(ctx, data.team);
}
var size = 0;

View File

@ -8,7 +8,8 @@ define([
'/common/common-hash.js',
'/common/common-util.js',
'/components/chainpad-crypto/crypto.js',
], function (ApiConfig, Messaging, Hash, Util, Crypto) {
'/common/outer/login-block.js',
], function (ApiConfig, Messaging, Hash, Util, Crypto, Block) {
// Random timeout between 10 and 30 times your sync time (lag + chainpad sync)
var getRandomTimeout = function (ctx) {
@ -237,6 +238,14 @@ define([
cb(true);
};
// Encrypt the password under the right key before sending it via URL hash
var encryptPassword = function(ctx, password) {
let uHash = ctx.store.data.blockHash;
let uSecret = Block.parseBlockHash(uHash);
let key = uSecret.keys.symmetric;
return Crypto.encrypt(password, key);
};
// Hide duplicates when receiving a SHARE_PAD notification:
// Keep only one notification per channel: the stronger and more recent one
var channels = {};
@ -265,8 +274,7 @@ define([
}
if (content.password) {
var key = ctx.store.driveSecret.keys.cryptKey;
content.password = Crypto.encrypt(content.password, key);
content.password = encryptPassword(ctx, content.password);
}
// Update the data
@ -384,8 +392,8 @@ define([
var channel = content.channel || content.teamChannel;
if (content.password) {
var key = ctx.store.driveSecret.keys.cryptKey;
content.password = Crypto.encrypt(content.password, key);
content.pw = content.password;
content.password = encryptPassword(ctx, content.password);
}
if (addOwners[channel]) { return void cb(true); }

View File

@ -111,7 +111,7 @@ define([
var removeClient = function (ctx, cId) {
var idx = ctx.clients.indexOf(cId);
ctx.clients.splice(idx, 1);
if (idx !== -1) { ctx.clients.splice(idx, 1); }
};
Profile.init = function (cfg, waitFor, emit) {

View File

@ -694,7 +694,7 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto, Feedback)
// but since multiple users who can and should might be online at once
// and since they'll all trigger this process at the same time...
// we want to stagger attempts at random intervals
setTimeout(function () {
ref.internal.checkpointTimeout = setTimeout(function () {
ref.internal.pendingCheckpointId = roster.checkpoint(function (err) {
if (err) { console.error(err); }
});
@ -730,7 +730,10 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto, Feedback)
//console.log("Sending with id [%s]", id, msg);
//console.log();
response.expect(id, cb, TIMEOUT_INTERVAL);
response.expect(id, function (err, state) {
if (err) { return void cb(err); }
cb(void 0, state, id);
}, TIMEOUT_INTERVAL);
anon_rpc.send('WRITE_PRIVATE_MESSAGE', [
channel,
ciphertext

View File

@ -4,7 +4,7 @@
/* global importScripts, tabs */
importScripts('/components/requirejs/require.js');
importScripts('/components/requirejs/require.js?ver=2.3.7');
window = self; // eslint-disable-line no-global-assign
localStorage = { // eslint-disable-line no-global-assign

View File

@ -4,7 +4,7 @@
/* global importScripts */
importScripts('/components/requirejs/require.js');
importScripts('/components/requirejs/require.js?ver=2.3.7');
window = self; // eslint-disable-line no-global-assign
localStorage = { // eslint-disable-line no-global-assign

View File

@ -4,7 +4,7 @@
/* global importScripts */
importScripts('/components/requirejs/require.js');
importScripts('/components/requirejs/require.js?ver=2.3.7');
window = self; // eslint-disable-line no-global-assign
localStorage = { // eslint-disable-line no-global-assign

View File

@ -1083,7 +1083,7 @@ define([
Cryptpad.addSharedFolder(null, secret, cb);
} else {
var _data = {
password: data.password,
password: data.pw || data.password,
href: data.href,
channel: data.channel,
title: data.title,
@ -1359,7 +1359,7 @@ define([
var viewH = Utils.Hash.getViewHashFromKeys(_secret);
var href = Utils.Hash.hashToHref(editH, parsed.type);
var roHref = Utils.Hash.hashToHref(viewH, parsed.type);
Cryptpad.setPadAttribute('password', password, w(), parsed.getUrl());
Cryptpad.setPadAttribute('password', pw, w(), parsed.getUrl());
Cryptpad.setPadAttribute('channel', chan, w(), parsed.getUrl());
Cryptpad.setPadAttribute('href', href, w(), parsed.getUrl());
Cryptpad.setPadAttribute('roHref', roHref, w(), parsed.getUrl());

View File

@ -446,5 +446,26 @@
"settings_changePasswordPending": "Вашата парола се обновява. Моля, не затваряйте и не презареждайте тази страница, докато процесът не приключи.",
"settings_cursorColorTitle": "Цвят на курсора",
"settings_changePasswordError": "Възникна неочаквана грешка. Ако не можете да влезете или да промените паролата си, свържете се с администраторите на CryptPad.",
"settings_changePasswordNewPasswordSameAsOld": "Вашата нова парола трябва да е различна от настоящата."
"settings_changePasswordNewPasswordSameAsOld": "Вашата нова парола трябва да е различна от настоящата.",
"settings_cursorShareTitle": "Споделяне на позицията на курсора ми",
"settings_cursorShareLabel": "Споделяне на позицията",
"settings_cursorShowTitle": "Показване на позицията на курсора на другите потребители",
"settings_cursorShowHint": "Можете да изберете дали искате да виждате курсора на другите потребители в документите за съвместната работа.",
"settings_cursorShowLabel": "Показване на курсорите",
"upload_title": "Качване на файла",
"upload_modal_filename": "Име на файла (разширението <em>{0}</em> се добавя автоматично)",
"upload_modal_owner": "Личен файл",
"uploadFolder_modal_filesPassword": "Парола на файловете",
"uploadFolder_modal_owner": "Лични файлове",
"uploadFolder_modal_forceSave": "Съхраняване на файлове във вашия CryptDrive",
"upload_uploadPending": "В момента качвате. Искате ли да го отмените и да качите новия си файл?",
"upload_notEnoughSpace": "Няма достатъчно място за този файл във вашия CryptDrive.",
"upload_notEnoughSpaceBrief": "Няма достатъчно място",
"settings_cursorColorHint": "Променете цвета, свързан с вашия потребител в документите за съвместната работа.",
"settings_cursorShareHint": "Можете да решите дали искате други потребители да виждат позицията на курсора ви в документите за съвместната работа.",
"uploadFolder_modal_title": "Опции за качване на папка",
"upload_modal_title": "Опции за качване на файлове",
"upload_tooLarge": "Този файл надвишава максималния разрешен размер на качване за вашия акаунт.",
"upload_serverError": "Грешка в сървъра: файлът ви не може да бъде качен в момента.",
"upload_success": "Вашият файл ({0}) бе успешно качен и е добавен към устройството ви."
}

View File

@ -1129,7 +1129,7 @@
"admin_updateLimitTitle": "Actualitzar les quotes d'usuari",
"admin_updateLimitButton": "Actualitzar les quotes",
"admin_flushCacheTitle": "Neteja la memòria cau HTTP",
"admin_flushCacheHint": "Força als usuaris a descarregar els últims actius del client (només si el servidor està en mode nou)",
"admin_flushCacheHint": "Força tots els usuaris a baixar els últims actius després d'un canvi en la configuració o la personalització. Evita reiniciar el servidor, però fa que cada usuari actiu restableixi la connexió, utilitzeu-ho amb moderació.",
"admin_flushCacheButton": "Neteja la memòria cau",
"footer_donate": "Donació",
"contact_admin": "Contacteu amb l'administració de: {0}",
@ -1340,7 +1340,7 @@
"snapshots_ooPickVersion": "Heu de seleccionar una versió abans de crear una instantània",
"snapshot_error_exists": "Ja hi ha una instantània d'aquesta versió",
"snapshots_notFound": "Aquesta instantània ja no existeix perquè s'ha suprimit l'historial del document.",
"admin_registrationHint": "No permetis que cap usuari nou es registri",
"admin_registrationHint": "Els visitants de la instància no poden crear comptes. Els administradors poden crear invitacions.",
"admin_registrationTitle": "Tanca el registre",
"admin_defaultlimitHint": "Límit màxim d'emmagatzematge per a CryptDrives (usuaris i equips) quan no s'apliqui cap regla personalitzada",
"admin_setlimitButton": "Estableix el límit",
@ -1717,5 +1717,50 @@
"admin_usersHint": "Llista dels comptes coneguts d'aquesta instància. Seleccioneu a continuació per a afegir comptes automàticament, o introduïu la informació manualment amb el formulari.",
"admin_usersBlock": "URL de blocatge d'inici de sessió de l'usuari (opcional)",
"ssoauth_form_hint_register": "Afegiu una contrasenya CryptPad per a més seguretat, o deixeu-la buida i continueu. Si no afegiu una contrasenya, els administradors de la instància tindran a l'abast les claus que protegeixen les vostres dades.",
"admin_storeInvitedLabel": "Desa automàticament els usuaris convidats"
"admin_storeInvitedLabel": "Desa automàticament els usuaris convidats",
"admin_supportAdd": "Afegiu un contacte a l'equip d'assistència",
"admin_supportConfirm": "N'esteu segur? Això eliminarà tots els tiquets existents i blocarà l'accés a tots els moderadors.",
"support_cat_settings": "Configuració",
"admin_supportDelete": "Desactiva l'assistència",
"admin_supportMembers": "Equip d'assistència",
"admin_supportRotateNotify": "Atenció: les claus noves s'han generat, però un error inesperat ha evitat que el sistema les enviés als moderadors. Elimineu i reafegiu a tots els moderadors de l'equip d'administració",
"support_cat_closed": "Tancats",
"support_cat_search": "Cerca",
"support_cat_open": "Safata d'entrada",
"support_openTicketTitle": "Obre un tiquet amb un usuari",
"admin_supportTeamTitle": "Gestiona l'equip d'assistència",
"support_cat_legacy": "Compatibilitat",
"support_pending": "Tiquets arxivats:",
"support_privacyHint": "Marqueu aquesta opció per a respondre com a «Equip d'assistència» en compte d'amb el vostre nom d'usuari",
"support_pending_tag": "Arxivat",
"support_active_tag": "Safata d'entrada",
"support_closed_tag": "Tancat",
"support_privacyTitle": "Resposta anònima",
"support_notificationsHint": "Marqueu aquesta opció per a desactivar les notificacions de tiquets i respostes nous",
"support_notificationsTitle": "Desactiva les notificacions",
"support_userChannel": "ID del canal de notificacions de l'usuari",
"support_openTicketHint": "Copia les dades de l'usuari destinatari des de la seva pàgina de perfil o des d'un tiquet existent. Rebran una notificació del CryptPad sobre aquest missatge.",
"support_userKey": "Clau pública de l'usuari",
"support_invalChan": "Canal de notificacions no vàlid",
"admin_supportTeamHint": "Afegiu i elimina gent de la instància de l'equip d'assistència",
"support_pasteUserData": "Enganxeu les dades de l'usuari aquí",
"support_legacyButton": "Recupera els tiquets actius",
"support_recordedHint": "Emmagatzema el text comú com a dreceres d'un clic per a inserir-los a missatges d'assistència.",
"support_recordedContent": "Contingut",
"support_legacyTitle": "Mostra les dades d'assistència antigues",
"support_searchLabel": "Cerca (títol o ID del tiquet)",
"support_team": "L'Equip d'assistència",
"support_legacyHint": "Mostra els tiquets del sistema d'assistència antic i els recrea en el sistema nou.",
"support_legacyDump": "Exporta-ho tot",
"support_legacyClear": "Elimina d'aquest compte",
"support_moveActive": "Mou a l'arxiu",
"support_answerAs": "Es respon com a <b>{0}</b>",
"support_movePending": "Mou a l'arxiu",
"admin_supportOpen": "Obre el servei d'assistència",
"moderationPage": "Servei d'assistència",
"support_copyUserData": "Copia les dades d'usuari",
"support_userNotification": "Tiquet d'assistència o resposta nou: {0}",
"install_instance": "Creeu el primer compte d'administrador, després personalitzeu la instància",
"install_header": "Instal·lació",
"install_launch": "Configuració de la instància"
}

View File

@ -1 +1,25 @@
{}
{
"type": {
"slide": "Markdown slides",
"media": "Media",
"pad": "Rich tekst",
"poll": "Afstemning",
"file": "Fil",
"todo": "Todo",
"contacts": "Kontakter",
"code": "Kode",
"drive": "CryptDrive",
"form": "Form",
"teams": "Hold",
"doc": "Dokument",
"presentation": "Præsentation",
"diagram": "Diagram",
"kanban": "Kanban",
"sheet": "Ark",
"whiteboard": "Whiteboard"
},
"typeError": "Dette dokument er ikke kompatibelt med det valgte program",
"main_title": "CryptPad: Zero Knowledge, Collaborative Real Time Editing",
"common_connectionLost": "<b>Serverforbindelse afbrudt</b><br>Du er nu i skrivebeskyttet tilstand, indtil forbindelsen er tilbage.",
"onLogout": "Du er logget ud, {0}klik her{1} for at logge ind<br>eller tryk på Esc for at få adgang til dit dokument i skrivebeskyttet tilstand."
}

View File

@ -1780,5 +1780,8 @@
"admin_onboardingNamePlaceholder": "Name der Instanz",
"admin_onboardingDescPlaceholder": "Beschreibungstext für die Instanz",
"admin_onboardingOptionsHint": "Bitte wähle die geeignete Option für deine Instanz.<br>Diese Einstellungen können später im Administrationsbereich geändert werden.",
"admin_onboardingNameHint": "Bitte wähle einen Namen, eine Beschreibung, eine Akzentfarbe und ein Logo (alle Angaben sind optional)"
"admin_onboardingNameHint": "Bitte wähle einen Namen, eine Beschreibung, eine Akzentfarbe und ein Logo (alle Angaben sind optional)",
"team_autoTrim": "Verlauf des Team-Drives wird gelöscht... Bitte warten.",
"admin_mfa_confirm_enable": "Bist du sicher, dass du die Multi-Faktor-Authentifizierung aktivieren möchtest?",
"admin_mfa_confirm_disable": "Bist du sicher, dass du die Multi-Faktor-Authentifizierung deaktivieren möchtest?"
}

View File

@ -589,8 +589,8 @@
"properties_passwordWarning": "La contraseña ha sido cambiada con éxito pero fue incapaz de actualizar tu CryptDrive con los nuevos datos. Es posible que tenga que eliminar la versión antigua del documento manualmente.<br>Pulse OK para recargar y actualizar sus derechos de acceso.",
"properties_passwordSuccess": "La contraseña ha sido cambiada con éxito.<br>Pulsa OK para recargar y actualizar tus derechos de acceso.",
"admin_updateLimitTitle": "Actualizar cuotas de usuarios",
"admin_registeredHint": "Número de usuarios registrados en tu instancia",
"admin_registeredTitle": "Usuarios registrados",
"admin_registeredHint": "Número de unidades activas en tu instancia",
"admin_registeredTitle": "Unidades de usuario y de equipo",
"admin_activePadsHint": "Número de documentos únicos que se están viendo o editando ahora",
"admin_activePadsTitle": "Documentos activos",
"admin_activeSessionsHint": "Número de conexiones websocket activas (y direcciones IP únicas conectadas)",
@ -1556,5 +1556,22 @@
"calendar_rec_warn_updateall": "La regla para repetir este evento ha sido modificada. El primer evento en {0} será mantenido, todos los demás serán sustituidos.",
"calendar_rec_warn_update": "La regla para repetir este evento ha sido modificada. Los eventos futuros serán sustituidos.",
"calendar_rec_warn_delall": "Este evento ya no se va a repetir. El primer evento en {0} se mantendrá, todos los demás serán eliminados.",
"calendar_rec_warn_del": "Este evento ya no se va a repetir. Los eventos futuros serán eliminados."
"calendar_rec_warn_del": "Este evento ya no se va a repetir. Los eventos futuros serán eliminados.",
"continue": "Continuar",
"team_inviteRole": "Rol inicial",
"team_inviteUses": "Uso(s) permitido(s) para este enlace (0 = sin límite)",
"form_exportJSON": "Exportar a JSON",
"form_alreadyAnsweredMult": "Ha respondido a este formulario el:",
"form_deleteAll": "Borrar todo",
"form_answer_new": "Enviar de nuevo",
"form_allowNotifications": "Notificaciones de nuevas respuestas",
"form_editable_off": "Sólo una vez",
"form_editable_on_del": "Una vez y editar/borrar",
"form_multiple": "Múltiples veces",
"form_multiple_edit": "Múltiples veces y editar/borrar",
"form_editable_str": "Envío",
"team_linkUsesInfinite": "(sin límite de usos)",
"form_settingsButton": "Configuración del formulario",
"form_editable_on": "Una vez y editar",
"form_responseNotification": "Nuevas respuestas a la forma: <b>{0}</b>"
}

File diff suppressed because it is too large Load Diff

View File

@ -594,8 +594,8 @@
"features_f_storage1": "Biltegiratze pertsonala ({0})",
"features_f_file1_note": "Gorde fitxategiak zure CryptDrive-an: irudiak, PDFak, bideoak eta abar. Partekatu itzazu zure kontaktuekin edo txertatu dokumentuetan. (gehienez {0}MB)",
"admin_updateLimitTitle": "Eguneratu erabiltzaileen kuotak",
"admin_registeredHint": "Zure instantzian erregistratutako erabiltzaile kopurua",
"admin_registeredTitle": "Erabiltzaile erregistratuak",
"admin_registeredHint": "Zure instantziako unitate aktibo kopurua",
"admin_registeredTitle": "Erabiltzaile eta taldeko gidak",
"admin_activePadsHint": "Une honetan ikusten edo editatzen ari diren dokumentu bakarrak",
"admin_activePadsTitle": "Dokumentu aktiboak",
"admin_activeSessionsHint": "Websocket konexio aktiboen kopurua (eta konektatutako IP helbide bakarrak)",
@ -1205,7 +1205,7 @@
"admin_defaultlimitTitle": "Biltegiratze muga (MB)",
"admin_defaultlimitHint": "CryptDrive edo unitatearen (erabiltzaileren zein talderen) biltegiratzeko gehienezko muga, arau pertsonalizatua aplikatzen ez denean",
"admin_registrationTitle": "Itxi izena ematea",
"admin_registrationHint": "Ez utzi erabiltzaile berririk izena ematen",
"admin_registrationHint": "Instantziaren bisitariek ezin dute konturik sortu. Gonbidapenak administratzaileek sor ditzakete.",
"snapshots_notFound": "Babeskopia hau jada ez dago dokumentuaren historia ezabatu delako.",
"snapshot_error_exists": "Dagoeneko badago bertsio honen babeskopia bat",
"snapshots_ooPickVersion": "Bertsio bat hautatu behar duzu babeskopia bat sortu aurretik",
@ -1668,7 +1668,7 @@
"calendar_rec_change": "Errepikatzen den gertaera bat beste egutegi batera eramatea.. Aldaketa hau gertaera honetan edo errepikatzen diren gertaera guztietan soilik aplika dezakezu.",
"access_passwordUsed": "Pasahitz hau dagoeneko erabili da dokumentu honetarako. Ezin da berriro erabili.",
"calendar_rec_change_first": "Lehenengo errepikapena beste egutegi batera mugitzea. Errepikatzen diren gertaera guztiak ere mugituko dira.",
"admin_forcemfaHint": "Instantzia honetako erabiltzaile guztiei bi faktoreko autentifikazioa konfiguratzeko eskatuko zaie beren kontuan saioa hasteko.",
"admin_forcemfaHint": "Instantzia honetako erabiltzaile guztiei bi faktoreko autentifikazioa konfiguratzeko eskatuko zaie beren kontuan saioa hasteko. Kontuan izan lehendik dauden erabiltzaileek ezin izango dutela beren kontua erabiltzen jarraitu TOTP aplikazioa konfiguratu gabe.",
"ssoauth_form_hint_login": "Sartu zure CryptPad pasahitza",
"status": "Egoera orria",
"calendar_desc": "Deskribapena",
@ -1763,5 +1763,25 @@
"admin_supportOpen": "Ireki laguntza tresnak",
"support_copyUserData": "Kopiatu erabiltzailearen datuak",
"support_userNotification": "Laguntza-txartel edo erantzun berria: {0}",
"admin_supportTeamHint": "Gehitu eta kendu jendea instantziako laguntza-taldetik"
"admin_supportTeamHint": "Gehitu eta kendu jendea instantziako laguntza-taldetik",
"install_token": "Instalazioaren tokena",
"install_header": "Instalazioa",
"admin_appSelection": "Aplikazioaren konfigurazioa",
"install_instance": "Sortu lehen administratzailearen kontua, eta jarraitu instantzia hau pertsonalizatzen",
"install_launch": "Instantziaren konfigurazioa",
"install_notes": "<ul class=\"cp-notes-list\"><li>Sortu zure lehen administratzaile kontua orrialde honetan. Administratzaileek instantzia-ezarpenak kudeatzen dituzte biltegiratze-kuotak barne, eta moderazio-tresnetarako sarbidea dute.</li><li>Zure pasahitza instantzia honetako dokumentu eta administratzaile-pribilegio guztiak enkriptatzen dituen gako sekretua da. <span class=\"red\">Galtzen baduzu, ezin dugu zure datuak berreskuratu.</span></li><li>Partekatutako ordenagailu bat erabiltzen ari bazara, <span class=\"red\">gogoratu amaitutakoan saioa ixtea</span>. Nabigatzailearen leihoa ixteak bakarrik utziko du zure kontua agerian. </li></ul>",
"admin_appsTitle": "Instantziaren aplikazioak",
"admin_appsHint": "Aukeratu zein aplikazio aktibatu instantzia honetan.",
"admin_cat_apps": "Aplikazioak",
"onboarding_upload": "Hautatu logoa",
"onboarding_save_error": "Aukera batzuk ezin izan dira behar bezala gorde. Mesedez, bisitatu administrazio panelera balioak egiaztatzeko.",
"admin_onboardingNameHint": "Mesedez, aukeratu izenburua, deskribapena, nabarmentzeko kolorea eta logotipoa (guztiak aukerakoak dira)",
"admin_onboardingNameTitle": "Ongi etorri zure CryptPad instantziara",
"admin_onboardingOptionsTitle": "Instantziaren aukerak",
"admin_onboardingNamePlaceholder": "Instantziaren izenburua",
"admin_onboardingDescPlaceholder": "Instantziaren deskribapen testua",
"admin_onboardingOptionsHint": "Mesedez, hautatu aukera egokia zure instantziarako.<br>Ezarpen hauek geroago alda daitezke administrazio panelean.",
"admin_mfa_confirm_disable": "Ziur faktore anitzeko autentifikazioa desgaitu nahi duzula?",
"admin_mfa_confirm_enable": "Ziur faktore anitzeko autentifikazioa gaitu nahi duzula?",
"team_autoTrim": "Taldeko diskoen historia mozten... Itxaron mesedez."
}

View File

@ -1780,5 +1780,8 @@
"admin_onboardingNamePlaceholder": "Nom de l'instance",
"admin_onboardingOptionsHint": "Veuillez sélectionner les options appropriées pour votre instance.<br>Ces paramètres peuvent être changés plus tard depuis l'espace d'administration.",
"admin_onboardingDescPlaceholder": "Texte de description de l'instance",
"install_notes": "<ul class=\"cp-notes-list\"><li>Créez votre premier compte administrateur·ice sur cette page. Les administrateur·ices peuvent paramétrer l'instance, ceci incluant les quotas de stockage, et ont accès aux outils de modération.</li><li>Votre mot de passe est la clé secrète qui chiffre l'ensemble de vos documents et vos privilèges d'administration sur l'instance. <span class=\"red\">Si vous le perdez il n'est pas possible de récupérer vos données.</span></li><li>Si vous utilisez un ordinateur partagé, <span class=\"red\">n'oubliez pas de vous déconnecter</span> quand vous aurez terminé. Simplement fermer la fenêtre du navigateur web laisse votre compte exposé à des risques de sécurité. </li></ul>"
"install_notes": "<ul class=\"cp-notes-list\"><li>Créez votre premier compte administrateur·ice sur cette page. Les administrateur·ices peuvent paramétrer l'instance, ceci incluant les quotas de stockage, et ont accès aux outils de modération.</li><li>Votre mot de passe est la clé secrète qui chiffre l'ensemble de vos documents et vos privilèges d'administration sur l'instance. <span class=\"red\">Si vous le perdez il n'est pas possible de récupérer vos données.</span></li><li>Si vous utilisez un ordinateur partagé, <span class=\"red\">n'oubliez pas de vous déconnecter</span> quand vous aurez terminé. Simplement fermer la fenêtre du navigateur web laisse votre compte exposé à des risques de sécurité. </li></ul>",
"team_autoTrim": "Suppression de l'historique du drive d'équipe... Veuillez patienter.",
"admin_mfa_confirm_disable": "Êtes-vous sûr de vouloir désactiver l'authentification multi-facteur ?",
"admin_mfa_confirm_enable": "Êtes-vous sûr de vouloir activer l'authentification multi-facteur ?"
}

Some files were not shown because too many files have changed in this diff Show More