mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-07-20 21:32:39 +03:00
Compare commits
65 Commits
MilnerMart
...
mfa_key
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c01217827c | ||
|
|
f01bb749ab | ||
|
|
d421a19193 | ||
|
|
67529dd883 | ||
|
|
c26b66887f | ||
|
|
17b76bb876 | ||
|
|
0de1196b62 | ||
|
|
99e405f80f | ||
|
|
d7ba0dc430 | ||
|
|
2c49502345 | ||
|
|
ef82119226 | ||
|
|
1b9ec75903 | ||
|
|
c58eb91893 | ||
|
|
49aa025012 | ||
|
|
5ebfa65a46 | ||
|
|
b5d3ba2726 | ||
|
|
0cd773a5d3 | ||
|
|
dfc91d533b | ||
|
|
39a14cff8f | ||
|
|
321271e7bd | ||
|
|
c87abbd23f | ||
|
|
c5c066c3e7 | ||
|
|
ddb0a22504 | ||
|
|
9f4afac7bc | ||
|
|
5d429ea9bb | ||
|
|
2aba39b176 | ||
|
|
6367f007c1 | ||
|
|
e982443988 | ||
|
|
16a50b0ca9 | ||
|
|
5f306801d7 | ||
|
|
b53499932b | ||
|
|
1ef9b7d48f | ||
|
|
7254dc3ab5 | ||
|
|
dc8f80365c | ||
|
|
d6b114de74 | ||
|
|
b794f749dd | ||
|
|
df831a0564 | ||
|
|
0eed869735 | ||
|
|
f1452ebe2a | ||
|
|
6917eaf7bd | ||
|
|
50d3be4c95 | ||
|
|
85baa6e9c8 | ||
|
|
966bc3de8c | ||
|
|
1532a99d4e | ||
|
|
ccbeefe674 | ||
|
|
cf648906e9 | ||
|
|
3ddfa9b948 | ||
|
|
fddeb9030b | ||
|
|
99a704698d | ||
|
|
fc220dea39 | ||
|
|
55317039ac | ||
|
|
24e6087ef8 | ||
|
|
7c1d30bc8f | ||
|
|
c1610c4532 | ||
|
|
2e2f59fa0f | ||
|
|
cc6e9e0546 | ||
|
|
0f59981932 | ||
|
|
a37f903dc7 | ||
|
|
74aa897626 | ||
|
|
4b624596c8 | ||
|
|
00239bb6c8 | ||
|
|
241563e8fc | ||
|
|
e91747785b | ||
|
|
e42fda893c | ||
|
|
e3fcd26f12 |
@@ -395,6 +395,19 @@ ALLOWED_IFRAME_HOSTS=null
|
|||||||
# Current host and source for the "DRAWIO" setting will be auto-appended to the sources configured.
|
# Current host and source for the "DRAWIO" setting will be auto-appended to the sources configured.
|
||||||
ALLOWED_IFRAME_SOURCES="https://*.draw.io https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com"
|
ALLOWED_IFRAME_SOURCES="https://*.draw.io https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com"
|
||||||
|
|
||||||
|
# A list of sources/hostnames that can be loaded as CSS styles within BookStack.
|
||||||
|
# Space separated if multiple. BookStack host domain is auto-inferred.
|
||||||
|
# Defaults to a permissive set if not provided.
|
||||||
|
# Example: ALLOWED_STYLE_SOURCES="https://fonts.googleapis.com"
|
||||||
|
ALLOWED_STYLE_SOURCES=null
|
||||||
|
|
||||||
|
# A list of sources/hostnames that can be loaded as image content within BookStack.
|
||||||
|
# Space separated if multiple. BookStack host domain is auto-inferred, in addition to
|
||||||
|
# data and blob images, due to their use for various functionality.
|
||||||
|
# Defaults to a permissive set if not provided.
|
||||||
|
# Example: ALLOWED_IMAGE_SOURCES="https://images.example.com"
|
||||||
|
ALLOWED_IMAGE_SOURCES=null
|
||||||
|
|
||||||
# A list of the sources/hostnames that can be reached by application SSR calls.
|
# A list of the sources/hostnames that can be reached by application SSR calls.
|
||||||
# This is used wherever users can provide URLs/hosts in-platform, like for webhooks.
|
# This is used wherever users can provide URLs/hosts in-platform, like for webhooks.
|
||||||
# Host-specific functionality (usually controlled via other options) like auth
|
# Host-specific functionality (usually controlled via other options) like auth
|
||||||
|
|||||||
2
.forgejo/CODE_OF_CONDUCT.md
Normal file
2
.forgejo/CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Please find our community rules on our website here:
|
||||||
|
https://www.bookstackapp.com/about/community-rules/
|
||||||
4
.forgejo/FUNDING.yml
Normal file
4
.forgejo/FUNDING.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: [ssddanbrown]
|
||||||
|
ko_fi: ssddanbrown
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: New API Endpoint or API Ability
|
name: New API Endpoint or API Ability
|
||||||
description: Request a new endpoint or API feature be added
|
description: Request a new endpoint or API feature be added
|
||||||
labels: [":nut_and_bolt: API Request"]
|
labels: ["Type/API Request"]
|
||||||
body:
|
body:
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: feature
|
id: feature
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Bug Report
|
name: Bug Report
|
||||||
description: Create a report to help us fix bugs & issues in existing supported functionality
|
description: Create a report to help us fix bugs & issues in existing supported functionality
|
||||||
labels: [":bug: Bug"]
|
labels: ["Type/Bug Report"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
13
.forgejo/ISSUE_TEMPLATE/config.yml
Normal file
13
.forgejo/ISSUE_TEMPLATE/config.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Community Forum Support
|
||||||
|
url: https://community.bookstackapp.com
|
||||||
|
about: Get support by talking with the BookStack team & community.
|
||||||
|
|
||||||
|
- name: Debugging & Common Issues
|
||||||
|
url: https://www.bookstackapp.com/docs/admin/debugging/
|
||||||
|
about: Find details on how to debug issues and view common issues with their resolutions.
|
||||||
|
|
||||||
|
- name: Official Support Plans
|
||||||
|
url: https://www.bookstackapp.com/support/
|
||||||
|
about: View our official support plans that offer assured support for business.
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Feature Request
|
name: Feature Request
|
||||||
description: Request a new feature or idea to be added to BookStack
|
description: Request a new feature or idea to be added to BookStack
|
||||||
labels: [":hammer: Feature Request"]
|
labels: ["Type/Feature Request"]
|
||||||
body:
|
body:
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: description
|
id: description
|
||||||
@@ -33,7 +33,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: Have you searched for an existing open/closed issue?
|
label: Have you searched for an existing open/closed issue?
|
||||||
description: |
|
description: |
|
||||||
To help us keep these issues under control, please ensure you have first [searched our issue list](https://github.com/BookStackApp/BookStack/issues?q=is%3Aissue) for any existing issues that cover the fundamental benefit/goal of your request.
|
To help us keep these issues under control, please ensure you have first [searched our issue list](https://codeberg.org/bookstack/bookstack/issues) for any existing issues that cover the fundamental benefit/goal of your request.
|
||||||
options:
|
options:
|
||||||
- label: I have searched for existing issues and none cover my fundamental request
|
- label: I have searched for existing issues and none cover my fundamental request
|
||||||
required: true
|
required: true
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Language Request
|
name: Language Request
|
||||||
description: Request a new language to be added to Crowdin for you to translate
|
description: Request a new language to be added to Crowdin for you to translate
|
||||||
labels: [":earth_africa: Translations"]
|
labels: ["Focus: Translations"]
|
||||||
assignees:
|
assignees:
|
||||||
- ssddanbrown
|
- ssddanbrown
|
||||||
body:
|
body:
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
name: Support Request
|
name: Support Request
|
||||||
description: Request support for a specific problem you have not been able to solve yourself
|
description: Request support for a specific problem you have not been able to solve yourself
|
||||||
labels: [":dog2: Support"]
|
labels: ["Type/Support"]
|
||||||
body:
|
body:
|
||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: useddocs
|
id: useddocs
|
||||||
@@ -15,11 +15,11 @@ body:
|
|||||||
- type: checkboxes
|
- type: checkboxes
|
||||||
id: searchissue
|
id: searchissue
|
||||||
attributes:
|
attributes:
|
||||||
label: Searched GitHub Issues
|
label: Searched Existing Issues
|
||||||
description: |
|
description: |
|
||||||
I have searched for the issue and potential resolutions within the [project's GitHub issue list](https://github.com/BookStackApp/BookStack/issues)
|
I have searched for the issue and potential resolutions within the [project's issue list](https://codeberg.org/bookstack/bookstack/issues)
|
||||||
options:
|
options:
|
||||||
- label: I have searched GitHub for the issue.
|
- label: I have searched for the issue.
|
||||||
required: true
|
required: true
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: scenario
|
id: scenario
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
|
|
||||||
Only the [latest version](https://github.com/BookStackApp/BookStack/releases) of BookStack is supported.
|
Only the [latest version](https://codeberg.org/bookstack/bookstack/releases) of BookStack is supported.
|
||||||
We generally don't support older versions of BookStack due to maintenance effort and
|
We generally don't support older versions of BookStack due to maintenance effort and
|
||||||
since we aim to provide a fairly stable upgrade path for new versions.
|
since we aim to provide a fairly stable upgrade path for new versions.
|
||||||
|
|
||||||
@@ -12,16 +12,14 @@ If you'd like to be notified of new potential security concerns you can [sign-up
|
|||||||
|
|
||||||
## Reporting a Vulnerability
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
If you've found an issue that likely has no impact to existing users (For example, in a development-only branch)
|
If you've found an issue that likely has no impact to existing users (For example, an issue only in the development branch)
|
||||||
feel free to raise it via a standard GitHub bug report issue.
|
feel free to raise it via a standard Codeberg bug report issue.
|
||||||
|
|
||||||
If the issue could have a security impact to BookStack instances,
|
If the issue could have a security impact to BookStack instances,
|
||||||
please directly contact the lead maintainer [@ssddanbrown](https://github.com/ssddanbrown).
|
please directly contact the lead maintainer via email Dan Brown using the [details found here](https://www.bookstackapp.com/links/contact/).
|
||||||
You will need to log in to be able to see the email address on the [GitHub profile page](https://github.com/ssddanbrown).
|
|
||||||
Alternatively you can send a DM via Mastodon to [@danb@fosstodon.org](https://fosstodon.org/@danb).
|
|
||||||
|
|
||||||
Please be patient while the vulnerability is being reviewed. Deploying the fix to address the vulnerability
|
Please be patient while the vulnerability is being reviewed. Deploying the fix to address the vulnerability
|
||||||
can often take a little time due to the amount of preparation required, to ensure the vulnerability has
|
can often take a little time due to the amount of preparation required, to ensure the vulnerability has
|
||||||
been covered, and to create the content required to adequately notify the user-base.
|
been covered, and to create the content required to adequately notify the user-base.
|
||||||
|
|
||||||
Thank you for keeping BookStack instances safe!
|
Thank you for keeping BookStack instances safe!
|
||||||
11
.forgejo/pull_request_template.md
Normal file
11
.forgejo/pull_request_template.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
## Details
|
||||||
|
|
||||||
|
<!-- Write details of your pull request in here -->
|
||||||
|
<!-- Include references to any relevant issues/discussions -->
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!-- Put an 'x' in between the brackets below to confirm these elements -->
|
||||||
|
|
||||||
|
- [ ] I have read the [BookStack community rules](https://www.bookstackapp.com/about/community-rules/).
|
||||||
|
- [ ] This PR does not feature significant use of LLM/AI generation as per the community rules above.
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: analyse-php
|
name: analyse-php
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '**.php'
|
- '**.php'
|
||||||
@@ -11,14 +12,16 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/library/node:24-trixie
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: https://github.com/shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.3
|
php-version: 8.5
|
||||||
extensions: gd, mbstring, json, curl, xml, mysql, ldap
|
extensions: gd, mbstring, json, curl, xml, mysql, ldap
|
||||||
|
|
||||||
- name: Get Composer Cache Directory
|
- name: Get Composer Cache Directory
|
||||||
@@ -27,14 +30,16 @@ jobs:
|
|||||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Cache composer packages
|
- name: Cache composer packages
|
||||||
uses: actions/cache@v4
|
uses: https://code.forgejo.org/actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-composer-8.3
|
key: ${{ runner.os }}-composer-8.5
|
||||||
restore-keys: ${{ runner.os }}-composer-
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
- name: Install composer dependencies
|
- name: Install composer dependencies
|
||||||
run: composer install --prefer-dist --no-interaction --ansi
|
run: composer install --prefer-dist --no-interaction --ansi
|
||||||
|
env:
|
||||||
|
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GH_TOKEN }}"}}'
|
||||||
|
|
||||||
- name: Run static analysis check
|
- name: Run static analysis check
|
||||||
run: composer check-static
|
run: composer check-static
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: lint-js
|
name: lint-js
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '**.js'
|
- '**.js'
|
||||||
@@ -13,9 +14,11 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/library/node:24-trixie
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
- name: Install NPM deps
|
- name: Install NPM deps
|
||||||
run: npm ci
|
run: npm ci
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: lint-php
|
name: lint-php
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '**.php'
|
- '**.php'
|
||||||
@@ -11,14 +12,16 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/library/node:24-trixie
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: https://github.com/shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.3
|
php-version: 8.5
|
||||||
tools: phpcs
|
tools: phpcs
|
||||||
|
|
||||||
- name: Run formatting check
|
- name: Run formatting check
|
||||||
34
.forgejo/workflows/sync-translations.yml
Normal file
34
.forgejo/workflows/sync-translations.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: Crowdin Action
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ development ]
|
||||||
|
paths:
|
||||||
|
- 'lang/**.php'
|
||||||
|
schedule:
|
||||||
|
- cron: '30 4 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
synchronize-with-crowdin:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/library/node:24-trixie
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
|
- name: crowdin action
|
||||||
|
uses: https://github.com/crowdin/github-action@v2
|
||||||
|
with:
|
||||||
|
crowdin_branch_name: development
|
||||||
|
upload_sources: true
|
||||||
|
upload_translations: false
|
||||||
|
download_translations: true
|
||||||
|
localization_branch_name: l10n_development
|
||||||
|
create_pull_request: false
|
||||||
|
github_base_url: codeberg.org
|
||||||
|
env:
|
||||||
|
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||||
|
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: test-js
|
name: test-js
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '**.js'
|
- '**.js'
|
||||||
@@ -15,9 +16,11 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/library/node:24-trixie
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
- name: Install NPM deps
|
- name: Install NPM deps
|
||||||
run: npm ci
|
run: npm ci
|
||||||
@@ -26,4 +29,4 @@ jobs:
|
|||||||
run: npm run ts:lint
|
run: npm run ts:lint
|
||||||
|
|
||||||
- name: Run JavaScript tests
|
- name: Run JavaScript tests
|
||||||
run: npm run test
|
run: npm run test:ci
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: test-migrations
|
name: test-migrations
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '**.php'
|
- '**.php'
|
||||||
@@ -13,15 +14,25 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/library/node:24-trixie
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php: ['8.2', '8.3', '8.4', '8.5']
|
php: ['8.2', '8.3', '8.4', '8.5']
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: docker.io/library/mariadb:12.2.2-noble
|
||||||
|
env:
|
||||||
|
MARIADB_USER: bookstack-test
|
||||||
|
MARIADB_PASSWORD: bookstack-test
|
||||||
|
MARIADB_DATABASE: bookstack-test
|
||||||
|
MARIADB_ROOT_PASSWORD: password
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: https://github.com/shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
extensions: gd, mbstring, json, curl, xml, mysql, ldap
|
extensions: gd, mbstring, json, curl, xml, mysql, ldap
|
||||||
@@ -32,34 +43,31 @@ jobs:
|
|||||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Cache composer packages
|
- name: Cache composer packages
|
||||||
uses: actions/cache@v4
|
uses: https://code.forgejo.org/actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-composer-${{ matrix.php }}
|
key: ${{ runner.os }}-composer-${{ matrix.php }}
|
||||||
restore-keys: ${{ runner.os }}-composer-
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
- name: Start MySQL
|
|
||||||
run: |
|
|
||||||
sudo systemctl start mysql
|
|
||||||
|
|
||||||
- name: Create database & user
|
|
||||||
run: |
|
|
||||||
mysql -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS `bookstack-test`;'
|
|
||||||
mysql -uroot -proot -e "CREATE USER 'bookstack-test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'bookstack-test';"
|
|
||||||
mysql -uroot -proot -e "GRANT ALL ON \`bookstack-test\`.* TO 'bookstack-test'@'localhost';"
|
|
||||||
mysql -uroot -proot -e 'FLUSH PRIVILEGES;'
|
|
||||||
|
|
||||||
- name: Install composer dependencies
|
- name: Install composer dependencies
|
||||||
run: composer install --prefer-dist --no-interaction --ansi
|
run: composer install --prefer-dist --no-interaction --ansi
|
||||||
|
env:
|
||||||
|
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GH_TOKEN }}"}}'
|
||||||
|
|
||||||
- name: Start migration test
|
- name: Start migration test
|
||||||
|
env:
|
||||||
|
TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@mysql/bookstack-test'
|
||||||
run: |
|
run: |
|
||||||
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
|
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
|
||||||
|
|
||||||
- name: Start migration:rollback test
|
- name: Start migration:rollback test
|
||||||
|
env:
|
||||||
|
TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@mysql/bookstack-test'
|
||||||
run: |
|
run: |
|
||||||
php${{ matrix.php }} artisan migrate:rollback --force -n --database=mysql_testing
|
php${{ matrix.php }} artisan migrate:rollback --force -n --database=mysql_testing
|
||||||
|
|
||||||
- name: Start migration rerun test
|
- name: Start migration rerun test
|
||||||
|
env:
|
||||||
|
TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@mysql/bookstack-test'
|
||||||
run: |
|
run: |
|
||||||
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
|
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: test-php
|
name: test-php
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- '**.php'
|
- '**.php'
|
||||||
@@ -13,18 +14,38 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
if: ${{ github.ref != 'refs/heads/l10n_development' }}
|
||||||
runs-on: ubuntu-24.04
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: docker.io/setupphp/node:noble
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php: ['8.2', '8.3', '8.4', '8.5']
|
php: ['8.2', '8.3', '8.4', '8.5']
|
||||||
|
env:
|
||||||
|
phpextensions: gd, mbstring, json, curl, xml, mysql, ldap, gmp
|
||||||
|
phpextensioncachekey: cache-v1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: https://code.forgejo.org/actions/checkout@v6
|
||||||
|
|
||||||
- name: Setup PHP
|
- name: Setup cache environment
|
||||||
uses: shivammathur/setup-php@v2
|
id: extcache
|
||||||
|
uses: https://github.com/shivammathur/cache-extensions@v1
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
extensions: gd, mbstring, json, curl, xml, mysql, ldap, gmp
|
extensions: ${{ env.phpextensions }}
|
||||||
|
key: ${{ env.phpextensioncachekey }}
|
||||||
|
|
||||||
|
- name: Cache extensions
|
||||||
|
uses: https://code.forgejo.org/actions/cache@v5
|
||||||
|
with:
|
||||||
|
path: ${{ steps.extcache.outputs.dir }}
|
||||||
|
key: ${{ steps.extcache.outputs.key }}
|
||||||
|
restore-keys: ${{ steps.extcache.outputs.key }}
|
||||||
|
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: https://github.com/shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php }}
|
||||||
|
extensions: ${{ env.phpextensions }}
|
||||||
|
|
||||||
- name: Get Composer Cache Directory
|
- name: Get Composer Cache Directory
|
||||||
id: composer-cache
|
id: composer-cache
|
||||||
@@ -32,30 +53,36 @@ jobs:
|
|||||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Cache composer packages
|
- name: Cache composer packages
|
||||||
uses: actions/cache@v4
|
uses: https://code.forgejo.org/actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
key: ${{ runner.os }}-composer-${{ matrix.php }}
|
key: ${{ runner.os }}-composer-${{ matrix.php }}
|
||||||
restore-keys: ${{ runner.os }}-composer-
|
restore-keys: ${{ runner.os }}-composer-
|
||||||
|
|
||||||
- name: Start Database
|
- name: Install composer dependencies
|
||||||
|
run: composer install --prefer-dist --no-interaction --ansi
|
||||||
|
env:
|
||||||
|
COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GH_TOKEN }}"}}'
|
||||||
|
|
||||||
|
- name: Start MySQL
|
||||||
run: |
|
run: |
|
||||||
sudo systemctl start mysql
|
sudo systemctl start mysql
|
||||||
|
|
||||||
- name: Setup Database
|
- name: Create database & user
|
||||||
run: |
|
run: |
|
||||||
mysql -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS `bookstack-test`;'
|
mysql -uroot -proot -e 'CREATE DATABASE IF NOT EXISTS `bookstack-test`;'
|
||||||
mysql -uroot -proot -e "CREATE USER 'bookstack-test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'bookstack-test';"
|
mysql -uroot -proot -e "CREATE USER 'bookstack-test'@'localhost' IDENTIFIED WITH mysql_native_password BY 'bookstack-test';"
|
||||||
mysql -uroot -proot -e "GRANT ALL ON \`bookstack-test\`.* TO 'bookstack-test'@'localhost';"
|
mysql -uroot -proot -e "GRANT ALL ON \`bookstack-test\`.* TO 'bookstack-test'@'localhost';"
|
||||||
mysql -uroot -proot -e 'FLUSH PRIVILEGES;'
|
mysql -uroot -proot -e 'FLUSH PRIVILEGES;'
|
||||||
|
|
||||||
- name: Install composer dependencies
|
|
||||||
run: composer install --prefer-dist --no-interaction --ansi
|
|
||||||
|
|
||||||
- name: Migrate and seed the database
|
- name: Migrate and seed the database
|
||||||
|
env:
|
||||||
|
TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@localhost/bookstack-test'
|
||||||
run: |
|
run: |
|
||||||
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
|
php${{ matrix.php }} artisan migrate --force -n --database=mysql_testing
|
||||||
php${{ matrix.php }} artisan db:seed --force -n --class=DummyContentSeeder --database=mysql_testing
|
php${{ matrix.php }} artisan db:seed --force -n --class=DummyContentSeeder --database=mysql_testing
|
||||||
|
|
||||||
- name: Run PHP tests
|
- name: Run PHP tests
|
||||||
|
env:
|
||||||
|
TEST_DATABASE_URL: 'mysql://bookstack-test:bookstack-test@localhost/bookstack-test'
|
||||||
run: php${{ matrix.php }} ./vendor/bin/phpunit
|
run: php${{ matrix.php }} ./vendor/bin/phpunit
|
||||||
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,8 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Discord Chat Support
|
- name: Open Issues Here Instead
|
||||||
url: https://discord.gg/ztkBqR2
|
url: https://codeberg.org/bookstack/bookstack/issues
|
||||||
about: Realtime support & chat with the BookStack community and the team.
|
about: This project has migrated to Codeberg, please open issues there instead.
|
||||||
|
|
||||||
- name: Debugging & Common Issues
|
- name: Debugging & Common Issues
|
||||||
url: https://www.bookstackapp.com/docs/admin/debugging/
|
url: https://www.bookstackapp.com/docs/admin/debugging/
|
||||||
|
|||||||
13
.github/pull_request_template.md
vendored
13
.github/pull_request_template.md
vendored
@@ -1,11 +1,10 @@
|
|||||||
## Details
|
**Warning:**
|
||||||
|
|
||||||
<!-- Write details of your pull request in here -->
|
This project has migrated to Codeberg:
|
||||||
<!-- Include references to any relevant issues/discussions -->
|
https://codeberg.org/bookstack/bookstack
|
||||||
|
|
||||||
## Checklist
|
Please open pull requests here instead.
|
||||||
|
|
||||||
<!-- Put an 'x' in between the brackets below to confirm these elements -->
|
ANY PULL REQUESTS OPENED HERE WILL BE CLOSED WITHOUT COMMENT OR MERGE.
|
||||||
|
|
||||||
- [ ] I have read the [BookStack community rules](https://www.bookstackapp.com/about/community-rules/).
|
---
|
||||||
- [ ] This PR does not feature significant use of LLM/AI generation as per the community rules above.
|
|
||||||
9
.github/translators.txt
vendored
9
.github/translators.txt
vendored
@@ -533,7 +533,14 @@ JanDziaslo :: Polish
|
|||||||
Charllys Fernandes (CharllysFernandes) :: Portuguese, Brazilian
|
Charllys Fernandes (CharllysFernandes) :: Portuguese, Brazilian
|
||||||
Ilgiz Zigangirov (inov8) :: Russian
|
Ilgiz Zigangirov (inov8) :: Russian
|
||||||
Max Israelsson (Blezie) :: Swedish
|
Max Israelsson (Blezie) :: Swedish
|
||||||
Skiddybison5924 (chris-devel0per) :: German
|
Skiddybison5924 (chris-devel0per) :: German Informal; German
|
||||||
Veyilla Nightwhisper (Veyilla) :: German
|
Veyilla Nightwhisper (Veyilla) :: German
|
||||||
João Barbosa (hypeedd) :: Portuguese
|
João Barbosa (hypeedd) :: Portuguese
|
||||||
Abcdefg Hijklmn (collatek) :: Korean
|
Abcdefg Hijklmn (collatek) :: Korean
|
||||||
|
Suthep Yonphimai (tomztt) :: Thai
|
||||||
|
MrClock (MrClock8163) :: Hungarian
|
||||||
|
Elena0875 :: Russian
|
||||||
|
FelixFrizzy :: German
|
||||||
|
Pedro de Mattia (pdmtt) :: Portuguese, Brazilian
|
||||||
|
lonestan :: Russian
|
||||||
|
Paul Kernstock (kernstock) :: German
|
||||||
|
|||||||
@@ -22,4 +22,10 @@ trait HandlesPartialLogins
|
|||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function clearLastAttemptedUser(): void
|
||||||
|
{
|
||||||
|
$loginService = app()->make(LoginService::class);
|
||||||
|
$loginService->clearLastLoginAttempted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use BookStack\Access\LoginService;
|
|||||||
use BookStack\Access\Mfa\BackupCodeService;
|
use BookStack\Access\Mfa\BackupCodeService;
|
||||||
use BookStack\Access\Mfa\MfaSession;
|
use BookStack\Access\Mfa\MfaSession;
|
||||||
use BookStack\Access\Mfa\MfaValue;
|
use BookStack\Access\Mfa\MfaValue;
|
||||||
|
use BookStack\Access\Mfa\MfaVerificationLimiter;
|
||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
@@ -19,6 +20,11 @@ class MfaBackupCodesController extends Controller
|
|||||||
|
|
||||||
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-backup-codes';
|
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-backup-codes';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected MfaVerificationLimiter $limiter,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a view that generates and displays backup codes.
|
* Show a view that generates and displays backup codes.
|
||||||
*/
|
*/
|
||||||
@@ -71,6 +77,12 @@ class MfaBackupCodesController extends Controller
|
|||||||
public function verify(Request $request, BackupCodeService $codeService, MfaSession $mfaSession, LoginService $loginService)
|
public function verify(Request $request, BackupCodeService $codeService, MfaSession $mfaSession, LoginService $loginService)
|
||||||
{
|
{
|
||||||
$user = $this->currentOrLastAttemptedUser();
|
$user = $this->currentOrLastAttemptedUser();
|
||||||
|
$this->limiter->incrementAttempts($user, $request);
|
||||||
|
if ($this->limiter->hasHitLimit($user, $request)) {
|
||||||
|
$this->clearLastAttemptedUser();
|
||||||
|
$this->limiter->throwException();
|
||||||
|
}
|
||||||
|
|
||||||
$codes = MfaValue::getValueForUser($user, MfaValue::METHOD_BACKUP_CODES) ?? '[]';
|
$codes = MfaValue::getValueForUser($user, MfaValue::METHOD_BACKUP_CODES) ?? '[]';
|
||||||
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
@@ -89,6 +101,7 @@ class MfaBackupCodesController extends Controller
|
|||||||
|
|
||||||
$mfaSession->markVerifiedForUser($user);
|
$mfaSession->markVerifiedForUser($user);
|
||||||
$loginService->reattemptLoginFor($user);
|
$loginService->reattemptLoginFor($user);
|
||||||
|
$this->limiter->decrementAttempts($user, $request);
|
||||||
|
|
||||||
if ($codeService->countCodesInSet($updatedCodes) < 5) {
|
if ($codeService->countCodesInSet($updatedCodes) < 5) {
|
||||||
$this->showWarningNotification(trans('auth.mfa_backup_codes_usage_limit_warning'));
|
$this->showWarningNotification(trans('auth.mfa_backup_codes_usage_limit_warning'));
|
||||||
|
|||||||
133
app/Access/Controllers/MfaHardwareKeyController.php
Normal file
133
app/Access/Controllers/MfaHardwareKeyController.php
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Access\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Access\LoginService;
|
||||||
|
use BookStack\Access\Mfa\BackupCodeService;
|
||||||
|
use BookStack\Access\Mfa\MfaSession;
|
||||||
|
use BookStack\Access\Mfa\MfaValue;
|
||||||
|
use BookStack\Access\Mfa\MfaVerificationLimiter;
|
||||||
|
use BookStack\Activity\ActivityType;
|
||||||
|
use BookStack\Exceptions\NotFoundException;
|
||||||
|
use BookStack\Http\Controller;
|
||||||
|
use Cose\Algorithms;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Symfony\Component\Serializer\Encoder\JsonEncode;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
|
||||||
|
use Webauthn\AttestationStatement\AttestationStatementSupportManager;
|
||||||
|
use Webauthn\AttestationStatement\NoneAttestationStatementSupport;
|
||||||
|
use Webauthn\AuthenticatorSelectionCriteria;
|
||||||
|
use Webauthn\Denormalizer\WebauthnSerializerFactory;
|
||||||
|
use Webauthn\PublicKeyCredentialCreationOptions;
|
||||||
|
use Webauthn\PublicKeyCredentialOptions;
|
||||||
|
use Webauthn\PublicKeyCredentialParameters;
|
||||||
|
use Webauthn\PublicKeyCredentialRpEntity;
|
||||||
|
use Webauthn\PublicKeyCredentialUserEntity;
|
||||||
|
|
||||||
|
class MfaHardwareKeyController extends Controller
|
||||||
|
{
|
||||||
|
use HandlesPartialLogins;
|
||||||
|
|
||||||
|
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-hardware-key-secret';
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected MfaVerificationLimiter $limiter,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a view that allows configuration of a hardware key.
|
||||||
|
*/
|
||||||
|
public function generate(BackupCodeService $codeService)
|
||||||
|
{
|
||||||
|
|
||||||
|
$domain = parse_url(url('/'), PHP_URL_HOST);
|
||||||
|
$rpEntity = PublicKeyCredentialRpEntity::create(
|
||||||
|
setting('app-name'),
|
||||||
|
$domain,
|
||||||
|
);
|
||||||
|
|
||||||
|
$user = $this->currentOrLastAttemptedUser();
|
||||||
|
// TODO - Ensure user ID is somewhat long and random
|
||||||
|
// See: https://webauthn-doc.spomky-labs.com/prerequisites/user-entity
|
||||||
|
// Maybe hash of (app-id from settings + user id)
|
||||||
|
// Or maybe a UUID/random_string which we connect via DB entry?
|
||||||
|
$userEntity = PublicKeyCredentialUserEntity::create(
|
||||||
|
$user->slug,
|
||||||
|
$user->id,
|
||||||
|
$user->name,
|
||||||
|
);
|
||||||
|
|
||||||
|
$publicKeyCredentialParametersList = [
|
||||||
|
PublicKeyCredentialParameters::create('public-key', Algorithms::COSE_ALGORITHM_ES256K), // More interesting algorithm
|
||||||
|
PublicKeyCredentialParameters::create('public-key', Algorithms::COSE_ALGORITHM_ES256), // ||
|
||||||
|
PublicKeyCredentialParameters::create('public-key', Algorithms::COSE_ALGORITHM_RS256), // ||
|
||||||
|
PublicKeyCredentialParameters::create('public-key', Algorithms::COSE_ALGORITHM_PS256), // \/
|
||||||
|
PublicKeyCredentialParameters::create('public-key', Algorithms::COSE_ALGORITHM_ED256), // Less interesting algorithm
|
||||||
|
];
|
||||||
|
|
||||||
|
$credentialOptions = PublicKeyCredentialCreationOptions::create(
|
||||||
|
$rpEntity,
|
||||||
|
$userEntity,
|
||||||
|
random_bytes(32),
|
||||||
|
$publicKeyCredentialParametersList,
|
||||||
|
hints: [
|
||||||
|
PublicKeyCredentialOptions::HINT_SECURITY_KEY,
|
||||||
|
],
|
||||||
|
timeout: 60000, // 1 minute
|
||||||
|
authenticatorSelection: AuthenticatorSelectionCriteria::create(
|
||||||
|
userVerification: AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_DISCOURAGED,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$attestationStatementSupportManager = AttestationStatementSupportManager::create();
|
||||||
|
$attestationStatementSupportManager->add(NoneAttestationStatementSupport::create());
|
||||||
|
$factory = new WebauthnSerializerFactory($attestationStatementSupportManager);
|
||||||
|
$serializer = $factory->create();
|
||||||
|
$jsonOptions = $serializer->serialize(
|
||||||
|
$credentialOptions,
|
||||||
|
'json',
|
||||||
|
[
|
||||||
|
AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
|
||||||
|
JsonEncode::OPTIONS => JSON_THROW_ON_ERROR,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO - Change
|
||||||
|
$this->setPageTitle(trans('auth.mfa_gen_hardware_key_title'));
|
||||||
|
|
||||||
|
return view('mfa.hardware-key-generate', [
|
||||||
|
'options' => $jsonOptions,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm the setup of a hardware key, storing the key value against the user.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function confirm()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return redirect('/mfa/setup');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the MFA method submission on check.
|
||||||
|
*
|
||||||
|
* @throws NotFoundException
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function verify(Request $request, MfaSession $mfaSession, LoginService $loginService)
|
||||||
|
{
|
||||||
|
$user = $this->currentOrLastAttemptedUser();
|
||||||
|
$this->limiter->incrementAttempts($user, $request);
|
||||||
|
if ($this->limiter->hasHitLimit($user, $request)) {
|
||||||
|
$this->clearLastAttemptedUser();
|
||||||
|
$this->limiter->throwException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ namespace BookStack\Access\Controllers;
|
|||||||
use BookStack\Access\LoginService;
|
use BookStack\Access\LoginService;
|
||||||
use BookStack\Access\Mfa\MfaSession;
|
use BookStack\Access\Mfa\MfaSession;
|
||||||
use BookStack\Access\Mfa\MfaValue;
|
use BookStack\Access\Mfa\MfaValue;
|
||||||
|
use BookStack\Access\Mfa\MfaVerificationLimiter;
|
||||||
use BookStack\Access\Mfa\TotpService;
|
use BookStack\Access\Mfa\TotpService;
|
||||||
use BookStack\Access\Mfa\TotpValidationRule;
|
use BookStack\Access\Mfa\TotpValidationRule;
|
||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
@@ -20,7 +21,8 @@ class MfaTotpController extends Controller
|
|||||||
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret';
|
protected const SETUP_SECRET_SESSION_KEY = 'mfa-setup-totp-secret';
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected TotpService $totp
|
protected TotpService $totp,
|
||||||
|
protected MfaVerificationLimiter $limiter,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +88,12 @@ class MfaTotpController extends Controller
|
|||||||
public function verify(Request $request, LoginService $loginService, MfaSession $mfaSession)
|
public function verify(Request $request, LoginService $loginService, MfaSession $mfaSession)
|
||||||
{
|
{
|
||||||
$user = $this->currentOrLastAttemptedUser();
|
$user = $this->currentOrLastAttemptedUser();
|
||||||
|
$this->limiter->incrementAttempts($user, $request);
|
||||||
|
if ($this->limiter->hasHitLimit($user, $request)) {
|
||||||
|
$this->clearLastAttemptedUser();
|
||||||
|
$this->limiter->throwException();
|
||||||
|
}
|
||||||
|
|
||||||
$totpSecret = MfaValue::getValueForUser($user, MfaValue::METHOD_TOTP);
|
$totpSecret = MfaValue::getValueForUser($user, MfaValue::METHOD_TOTP);
|
||||||
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
@@ -98,6 +106,7 @@ class MfaTotpController extends Controller
|
|||||||
|
|
||||||
$mfaSession->markVerifiedForUser($user);
|
$mfaSession->markVerifiedForUser($user);
|
||||||
$loginService->reattemptLoginFor($user);
|
$loginService->reattemptLoginFor($user);
|
||||||
|
$this->limiter->decrementAttempts($user, $request);
|
||||||
|
|
||||||
return redirect()->intended();
|
return redirect()->intended();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ class LoginService
|
|||||||
/**
|
/**
|
||||||
* Clear the last login attempted session value.
|
* Clear the last login attempted session value.
|
||||||
*/
|
*/
|
||||||
protected function clearLastLoginAttempted(): void
|
public function clearLastLoginAttempted(): void
|
||||||
{
|
{
|
||||||
session()->remove(self::LAST_LOGIN_ATTEMPTED_SESSION_KEY);
|
session()->remove(self::LAST_LOGIN_ATTEMPTED_SESSION_KEY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,14 @@ class MfaValue extends Model
|
|||||||
|
|
||||||
const METHOD_TOTP = 'totp';
|
const METHOD_TOTP = 'totp';
|
||||||
const METHOD_BACKUP_CODES = 'backup_codes';
|
const METHOD_BACKUP_CODES = 'backup_codes';
|
||||||
|
const METHOD_HARDWARE_KEY = 'hardware_key';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the MFA methods available.
|
* Get all the MFA methods available.
|
||||||
*/
|
*/
|
||||||
public static function allMethods(): array
|
public static function allMethods(): array
|
||||||
{
|
{
|
||||||
return [self::METHOD_TOTP, self::METHOD_BACKUP_CODES];
|
return [self::METHOD_TOTP, self::METHOD_BACKUP_CODES, self::METHOD_HARDWARE_KEY];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
62
app/Access/Mfa/MfaVerificationLimiter.php
Normal file
62
app/Access/Mfa/MfaVerificationLimiter.php
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BookStack\Access\Mfa;
|
||||||
|
|
||||||
|
use BookStack\Exceptions\NotifyException;
|
||||||
|
use BookStack\Users\Models\User;
|
||||||
|
use Illuminate\Cache\RateLimiter;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A rate limit specifically for MFA verification.
|
||||||
|
* Limits across both the attempted user (on a tight limit) and the
|
||||||
|
* request IP (on a less strict limit).
|
||||||
|
*/
|
||||||
|
class MfaVerificationLimiter
|
||||||
|
{
|
||||||
|
protected int $maxUserAttemptsPerMinute = 5;
|
||||||
|
protected int $maxIpAttemptsPerMinute = 60;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
protected RateLimiter $rateLimiter
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function throwException(): never
|
||||||
|
{
|
||||||
|
throw new NotifyException(
|
||||||
|
trans('auth.mfa_throttle', ['seconds' => 60]),
|
||||||
|
'/login',
|
||||||
|
Response::HTTP_TOO_MANY_REQUESTS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function incrementAttempts(User $user, Request $request): void
|
||||||
|
{
|
||||||
|
$this->rateLimiter->hit($this->getUserKey($user));
|
||||||
|
$this->rateLimiter->hit($this->getRequestKey($request));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decrementAttempts(User $user, Request $request): void
|
||||||
|
{
|
||||||
|
$this->rateLimiter->decrement($this->getUserKey($user));
|
||||||
|
$this->rateLimiter->decrement($this->getRequestKey($request));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasHitLimit(User $user, Request $request): bool
|
||||||
|
{
|
||||||
|
return $this->rateLimiter->tooManyAttempts($this->getUserKey($user), $this->maxUserAttemptsPerMinute + 1)
|
||||||
|
|| $this->rateLimiter->tooManyAttempts($this->getRequestKey($request), $this->maxIpAttemptsPerMinute + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getUserKey(User $user): string
|
||||||
|
{
|
||||||
|
return "mfa-attempt::user::{$user->id}";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRequestKey(Request $request): string
|
||||||
|
{
|
||||||
|
return "mfa-attempt::request::{$request->ip()}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ class ActivityType
|
|||||||
const USER_CREATE = 'user_create';
|
const USER_CREATE = 'user_create';
|
||||||
const USER_UPDATE = 'user_update';
|
const USER_UPDATE = 'user_update';
|
||||||
const USER_DELETE = 'user_delete';
|
const USER_DELETE = 'user_delete';
|
||||||
|
const USER_MFA_RESET = 'user_mfa_reset';
|
||||||
|
|
||||||
const API_TOKEN_CREATE = 'api_token_create';
|
const API_TOKEN_CREATE = 'api_token_create';
|
||||||
const API_TOKEN_UPDATE = 'api_token_update';
|
const API_TOKEN_UPDATE = 'api_token_update';
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class PwaManifestBuilder
|
|||||||
// does not start a session, so we won't have current user context.
|
// does not start a session, so we won't have current user context.
|
||||||
// This was attempted but removed since manifest calls could affect user session
|
// This was attempted but removed since manifest calls could affect user session
|
||||||
// history tracking and back redirection.
|
// history tracking and back redirection.
|
||||||
// Context: https://github.com/BookStackApp/BookStack/issues/4649
|
// Context: https://codeberg.org/bookstack/bookstack/issues/4649
|
||||||
$darkMode = (bool) setting()->getForCurrentUser('dark-mode-enabled');
|
$darkMode = (bool) setting()->getForCurrentUser('dark-mode-enabled');
|
||||||
$appName = setting('app-name');
|
$appName = setting('app-name');
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,17 @@ return [
|
|||||||
// Current host and source for the "DRAWIO" setting will be auto-appended to the sources configured.
|
// Current host and source for the "DRAWIO" setting will be auto-appended to the sources configured.
|
||||||
'iframe_sources' => env('ALLOWED_IFRAME_SOURCES', 'https://*.draw.io https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com'),
|
'iframe_sources' => env('ALLOWED_IFRAME_SOURCES', 'https://*.draw.io https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com'),
|
||||||
|
|
||||||
|
// A list of style sources/hostnames that can be loaded styles within BookStack.
|
||||||
|
// Space separated if multiple. BookStack host domain is auto-inferred.
|
||||||
|
// If not set, a permissive default set is used to reduce potential breakage.
|
||||||
|
'style_sources' => env('ALLOWED_STYLE_SOURCES', null),
|
||||||
|
|
||||||
|
// A list of sources/hostnames that can be loaded as image content within BookStack.
|
||||||
|
// Space separated if multiple. BookStack host domain is auto-inferred, in addition to
|
||||||
|
// data and blob images, due to their use for various functionality.
|
||||||
|
// If not set, a permissive default set is used to reduce potential breakage.
|
||||||
|
'image_sources' => env('ALLOWED_IMAGE_SOURCES', null),
|
||||||
|
|
||||||
// A list of the sources/hostnames that can be reached by application SSR calls.
|
// A list of the sources/hostnames that can be reached by application SSR calls.
|
||||||
// This is used wherever users can provide URLs/hosts in-platform, like for webhooks.
|
// This is used wherever users can provide URLs/hosts in-platform, like for webhooks.
|
||||||
// Host-specific functionality (usually controlled via other options) like auth
|
// Host-specific functionality (usually controlled via other options) like auth
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ return [
|
|||||||
'strict' => false,
|
'strict' => false,
|
||||||
'engine' => null,
|
'engine' => null,
|
||||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||||
// @phpstan-ignore class.notFound
|
|
||||||
(PHP_VERSION_ID >= 80500 ? \Pdo\Mysql::ATTR_SSL_CA : \PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),
|
(PHP_VERSION_ID >= 80500 ? \Pdo\Mysql::ATTR_SSL_CA : \PDO::MYSQL_ATTR_SSL_CA) => env('MYSQL_ATTR_SSL_CA'),
|
||||||
]) : [],
|
]) : [],
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ return [
|
|||||||
* Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
|
* Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,
|
||||||
* Symbol, ZapfDingbats.
|
* Symbol, ZapfDingbats.
|
||||||
*/
|
*/
|
||||||
'font_dir' => storage_path('fonts/'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)
|
'font_dir' => storage_path('fonts/dompdf'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The location of the DOMPDF font cache directory.
|
* The location of the DOMPDF font cache directory.
|
||||||
@@ -78,7 +78,7 @@ return [
|
|||||||
*
|
*
|
||||||
* Note: This directory must exist and be writable by the webserver process.
|
* Note: This directory must exist and be writable by the webserver process.
|
||||||
*/
|
*/
|
||||||
'font_cache' => storage_path('fonts/'),
|
'font_cache' => storage_path('fonts/dompdf/cache'),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The location of a temporary directory.
|
* The location of a temporary directory.
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ namespace BookStack\Exports;
|
|||||||
|
|
||||||
use BookStack\Exceptions\PdfExportException;
|
use BookStack\Exceptions\PdfExportException;
|
||||||
use Dompdf\Dompdf;
|
use Dompdf\Dompdf;
|
||||||
|
use FontLib\Font;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Knp\Snappy\Pdf as SnappyPdf;
|
use Knp\Snappy\Pdf as SnappyPdf;
|
||||||
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
@@ -60,12 +62,65 @@ class PdfGenerator
|
|||||||
$domPdf = new Dompdf($options);
|
$domPdf = new Dompdf($options);
|
||||||
$domPdf->setBasePath(base_path('public'));
|
$domPdf->setBasePath(base_path('public'));
|
||||||
|
|
||||||
|
$fontMetrics = $domPdf->getFontMetrics();
|
||||||
|
$userFontfamilies = $this->getUserDomPdfFontFamilies();
|
||||||
|
foreach ($userFontfamilies as $fontFamily => $fonts) {
|
||||||
|
try {
|
||||||
|
$fontMetrics->setFontFamily($fontFamily, $fonts);
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
$expectedPath = storage_path('fonts/dompdf');
|
||||||
|
throw new PdfExportException("Failed to create required font data in {$expectedPath}, Ensure all content in this location is writable by the web server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$domPdf->loadHTML($this->convertEntities($html));
|
$domPdf->loadHTML($this->convertEntities($html));
|
||||||
$domPdf->render();
|
$domPdf->render();
|
||||||
|
|
||||||
return (string) $domPdf->output();
|
return (string) $domPdf->output();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, array<string, string>>
|
||||||
|
*/
|
||||||
|
protected function getUserDomPdfFontFamilies(): array
|
||||||
|
{
|
||||||
|
$fontStore = storage_path('fonts/dompdf');
|
||||||
|
if (!is_dir($fontStore)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fontFamilies = [];
|
||||||
|
$fontFiles = glob($fontStore . DIRECTORY_SEPARATOR . '*.ttf');
|
||||||
|
foreach ($fontFiles as $fontFile) {
|
||||||
|
$fontFileName = basename($fontFile, '.ttf');
|
||||||
|
$expectedUfm = $fontStore . DIRECTORY_SEPARATOR . $fontFileName . '.ufm';
|
||||||
|
if (!file_exists($expectedUfm)) {
|
||||||
|
$font = Font::load($fontFile);
|
||||||
|
$font->parse();
|
||||||
|
try {
|
||||||
|
$font->saveAdobeFontMetrics($expectedUfm);
|
||||||
|
} catch (\Exception $exception) {
|
||||||
|
throw new PdfExportException("Failed to create required font data at $expectedUfm, Ensure this location is writable by the web server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$nameParts = explode('-', $fontFileName);
|
||||||
|
if (count($nameParts) === 1 || $nameParts[1] === 'Regular') {
|
||||||
|
$nameParts[1] = 'Normal';
|
||||||
|
}
|
||||||
|
|
||||||
|
$family = trim(strtolower(preg_replace('/([A-Z])/', ' $1', $nameParts[0])));
|
||||||
|
$variation = Str::snake($nameParts[1]);
|
||||||
|
if (!isset($fontFamilies[$family])) {
|
||||||
|
$fontFamilies[$family] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fontFamilies[$family][$variation] = $fontStore . DIRECTORY_SEPARATOR . $fontFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fontFamilies;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws PdfExportException
|
* @throws PdfExportException
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class SearchIndex
|
|||||||
* Create a scored term array from the given text, where the keys are the terms
|
* Create a scored term array from the given text, where the keys are the terms
|
||||||
* and the values are their scores.
|
* and the values are their scores.
|
||||||
*
|
*
|
||||||
* @return array<string, int>
|
* @return array<string, float>
|
||||||
*/
|
*/
|
||||||
protected function generateTermScoreMapFromText(string $text, float $scoreAdjustment = 1): array
|
protected function generateTermScoreMapFromText(string $text, float $scoreAdjustment = 1): array
|
||||||
{
|
{
|
||||||
@@ -136,7 +136,7 @@ class SearchIndex
|
|||||||
* Create a scored term array from the given HTML, where the keys are the terms
|
* Create a scored term array from the given HTML, where the keys are the terms
|
||||||
* and the values are their scores.
|
* and the values are their scores.
|
||||||
*
|
*
|
||||||
* @return array<string, int>
|
* @return array<string, float>
|
||||||
*/
|
*/
|
||||||
protected function generateTermScoreMapFromHtml(string $html): array
|
protected function generateTermScoreMapFromHtml(string $html): array
|
||||||
{
|
{
|
||||||
@@ -177,7 +177,7 @@ class SearchIndex
|
|||||||
*
|
*
|
||||||
* @param Tag[] $tags
|
* @param Tag[] $tags
|
||||||
*
|
*
|
||||||
* @return array<string, int>
|
* @return array<string, float>
|
||||||
*/
|
*/
|
||||||
protected function generateTermScoreMapFromTags(array $tags): array
|
protected function generateTermScoreMapFromTags(array $tags): array
|
||||||
{
|
{
|
||||||
@@ -277,9 +277,9 @@ class SearchIndex
|
|||||||
* For the given term data arrays, Merge their contents by term
|
* For the given term data arrays, Merge their contents by term
|
||||||
* while combining any scores.
|
* while combining any scores.
|
||||||
*
|
*
|
||||||
* @param array<string, int>[] ...$scoreMaps
|
* @param array<string, float>[] ...$scoreMaps
|
||||||
*
|
*
|
||||||
* @return array<string, int>
|
* @return array<string, float>
|
||||||
*/
|
*/
|
||||||
protected function mergeTermScoreMaps(...$scoreMaps): array
|
protected function mergeTermScoreMaps(...$scoreMaps): array
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,8 +120,14 @@ class SearchRunner
|
|||||||
$filter = function (EloquentBuilder $query) use ($exact) {
|
$filter = function (EloquentBuilder $query) use ($exact) {
|
||||||
$inputTerm = str_replace('\\', '\\\\', $exact->value);
|
$inputTerm = str_replace('\\', '\\\\', $exact->value);
|
||||||
$query->where('name', 'like', '%' . $inputTerm . '%')
|
$query->where('name', 'like', '%' . $inputTerm . '%')
|
||||||
->orWhere('description', 'like', '%' . $inputTerm . '%')
|
->orWhere(function (EloquentBuilder $query) use ($inputTerm) {
|
||||||
->orWhere('text', 'like', '%' . $inputTerm . '%');
|
$query->whereNotNull('description')
|
||||||
|
->where('description', 'like', '%' . $inputTerm . '%');
|
||||||
|
})
|
||||||
|
->orWhere(function (EloquentBuilder $query) use ($inputTerm) {
|
||||||
|
$query->whereNotNull('text')
|
||||||
|
->where('text', 'like', '%' . $inputTerm . '%');
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$exact->negated ? $entityQuery->whereNot($filter) : $entityQuery->where($filter);
|
$exact->negated ? $entityQuery->whereNot($filter) : $entityQuery->where($filter);
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ class LocaleManager
|
|||||||
'sq' => 'sq_AL',
|
'sq' => 'sq_AL',
|
||||||
'sr' => 'sr_RS',
|
'sr' => 'sr_RS',
|
||||||
'sv' => 'sv_SE',
|
'sv' => 'sv_SE',
|
||||||
|
'th' => 'th_TH',
|
||||||
'tk' => 'tk_TM',
|
'tk' => 'tk_TM',
|
||||||
'tr' => 'tr_TR',
|
'tr' => 'tr_TR',
|
||||||
'uk' => 'uk_UA',
|
'uk' => 'uk_UA',
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ class AttachmentController extends Controller
|
|||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'order' => ['required', 'array'],
|
'order' => ['required', 'array'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
$page = $this->pageQueries->findVisibleByIdOrFail($pageId);
|
||||||
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
@@ -221,8 +222,6 @@ class AttachmentController extends Controller
|
|||||||
throw new NotFoundException(trans('errors.attachment_not_found'));
|
throw new NotFoundException(trans('errors.attachment_not_found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission(Permission::PageView, $page);
|
|
||||||
|
|
||||||
if ($attachment->external) {
|
if ($attachment->external) {
|
||||||
return redirect($attachment->path);
|
return redirect($attachment->path);
|
||||||
}
|
}
|
||||||
@@ -247,6 +246,13 @@ class AttachmentController extends Controller
|
|||||||
{
|
{
|
||||||
/** @var Attachment $attachment */
|
/** @var Attachment $attachment */
|
||||||
$attachment = Attachment::query()->findOrFail($attachmentId);
|
$attachment = Attachment::query()->findOrFail($attachmentId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->pageQueries->findVisibleByIdOrFail($attachment->uploaded_to);
|
||||||
|
} catch (NotFoundException $exception) {
|
||||||
|
throw new NotFoundException(trans('errors.attachment_not_found'));
|
||||||
|
}
|
||||||
|
|
||||||
$this->checkOwnablePermission(Permission::AttachmentDelete, $attachment);
|
$this->checkOwnablePermission(Permission::AttachmentDelete, $attachment);
|
||||||
$this->attachmentService->deleteFile($attachment);
|
$this->attachmentService->deleteFile($attachment);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Uploads\Controllers;
|
namespace BookStack\Uploads\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Entities\Queries\PageQueries;
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
use BookStack\Permissions\Permission;
|
use BookStack\Permissions\Permission;
|
||||||
@@ -14,7 +15,8 @@ use Illuminate\Http\Request;
|
|||||||
class DrawioImageController extends Controller
|
class DrawioImageController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected ImageRepo $imageRepo
|
protected ImageRepo $imageRepo,
|
||||||
|
protected PageQueries $pageQueries,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,16 +55,18 @@ class DrawioImageController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->checkPermission(Permission::ImageCreateAll);
|
||||||
|
$validated = $this->validate($request, [
|
||||||
'image' => ['required', 'string'],
|
'image' => ['required', 'string'],
|
||||||
'uploaded_to' => ['required', 'integer'],
|
'uploaded_to' => ['required', 'integer'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->checkPermission(Permission::ImageCreateAll);
|
$imageBase64Data = $validated['image'];
|
||||||
$imageBase64Data = $request->input('image');
|
$uploadedTo = $validated['uploaded_to'];
|
||||||
|
$targetPage = $this->pageQueries->findVisibleByIdOrFail($uploadedTo);
|
||||||
|
$this->checkOwnablePermission(Permission::PageUpdate, $targetPage);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$uploadedTo = $request->input('uploaded_to', 0);
|
|
||||||
$image = $this->imageRepo->saveDrawing($imageBase64Data, $uploadedTo);
|
$image = $this->imageRepo->saveDrawing($imageBase64Data, $uploadedTo);
|
||||||
} catch (ImageUploadException $e) {
|
} catch (ImageUploadException $e) {
|
||||||
return response($e->getMessage(), 500);
|
return response($e->getMessage(), 500);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace BookStack\Uploads\Controllers;
|
namespace BookStack\Uploads\Controllers;
|
||||||
|
|
||||||
|
use BookStack\Entities\Queries\PageQueries;
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
use BookStack\Permissions\Permission;
|
use BookStack\Permissions\Permission;
|
||||||
@@ -14,7 +15,8 @@ use Illuminate\Validation\ValidationException;
|
|||||||
class GalleryImageController extends Controller
|
class GalleryImageController extends Controller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected ImageRepo $imageRepo
|
protected ImageRepo $imageRepo,
|
||||||
|
protected PageQueries $pageQueries,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,20 +58,26 @@ class GalleryImageController extends Controller
|
|||||||
$this->checkPermission(Permission::ImageCreateAll);
|
$this->checkPermission(Permission::ImageCreateAll);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->validate($request, [
|
$validated = $this->validate($request, [
|
||||||
'file' => $this->getImageValidationRules(),
|
'file' => $this->getImageValidationRules(),
|
||||||
|
'uploaded_to' => ['required', 'integer'],
|
||||||
]);
|
]);
|
||||||
} catch (ValidationException $exception) {
|
} catch (ValidationException $exception) {
|
||||||
return $this->jsonError(implode("\n", $exception->errors()['file']));
|
$errors = $exception->errors();
|
||||||
|
$messages = array_merge($errors['file'] ?? [], $errors['uploaded_to'] ?? []);
|
||||||
|
return $this->jsonError(implode("\n", $messages));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$uploadedTo = intval($validated['uploaded_to']);
|
||||||
|
$targetPage = $this->pageQueries->findVisibleByIdOrFail($uploadedTo);
|
||||||
|
$this->checkOwnablePermission(Permission::PageUpdate, $targetPage);
|
||||||
|
|
||||||
new OutOfMemoryHandler(function () {
|
new OutOfMemoryHandler(function () {
|
||||||
return $this->jsonError(trans('errors.image_upload_memory_limit'));
|
return $this->jsonError(trans('errors.image_upload_memory_limit'));
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$imageUpload = $request->file('file');
|
$imageUpload = $validated['file'];
|
||||||
$uploadedTo = $request->input('uploaded_to', 0);
|
|
||||||
$image = $this->imageRepo->saveNew($imageUpload, 'gallery', $uploadedTo);
|
$image = $this->imageRepo->saveNew($imageUpload, 'gallery', $uploadedTo);
|
||||||
} catch (ImageUploadException $e) {
|
} catch (ImageUploadException $e) {
|
||||||
return response($e->getMessage(), 500);
|
return response($e->getMessage(), 500);
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class ImageGalleryApiController extends ApiController
|
|||||||
$this->checkPermission(Permission::ImageCreateAll);
|
$this->checkPermission(Permission::ImageCreateAll);
|
||||||
$data = $this->validate($request, $this->rules()['create']);
|
$data = $this->validate($request, $this->rules()['create']);
|
||||||
$page = $this->pageQueries->findVisibleByIdOrFail($data['uploaded_to']);
|
$page = $this->pageQueries->findVisibleByIdOrFail($data['uploaded_to']);
|
||||||
|
$this->checkOwnablePermission(Permission::PageUpdate, $page);
|
||||||
|
|
||||||
$image = $this->imageRepo->saveNew($data['image'], $data['type'], $page->id);
|
$image = $this->imageRepo->saveNew($data['image'], $data['type'], $page->id);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace BookStack\Users\Controllers;
|
|||||||
|
|
||||||
use BookStack\Access\SocialDriverManager;
|
use BookStack\Access\SocialDriverManager;
|
||||||
use BookStack\Access\UserInviteException;
|
use BookStack\Access\UserInviteException;
|
||||||
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\Exceptions\ImageUploadException;
|
use BookStack\Exceptions\ImageUploadException;
|
||||||
use BookStack\Exceptions\UserUpdateException;
|
use BookStack\Exceptions\UserUpdateException;
|
||||||
use BookStack\Http\Controller;
|
use BookStack\Http\Controller;
|
||||||
@@ -208,4 +209,20 @@ class UserController extends Controller
|
|||||||
|
|
||||||
return redirect('/settings/users');
|
return redirect('/settings/users');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset MFA for the specified user.
|
||||||
|
*/
|
||||||
|
public function resetMfa(Request $request, int $id)
|
||||||
|
{
|
||||||
|
$this->preventAccessInDemoMode();
|
||||||
|
$this->checkPermission(Permission::UsersManage);
|
||||||
|
|
||||||
|
$user = $this->userRepo->getById($id);
|
||||||
|
$user->mfaValues()->delete();
|
||||||
|
|
||||||
|
$this->logActivity(ActivityType::USER_MFA_RESET, $user);
|
||||||
|
|
||||||
|
return redirect("/settings/users/{$user->id}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ class CspService
|
|||||||
$this->getFrameAncestors(),
|
$this->getFrameAncestors(),
|
||||||
$this->getFrameSrc(),
|
$this->getFrameSrc(),
|
||||||
$this->getScriptSrc(),
|
$this->getScriptSrc(),
|
||||||
|
$this->getStyleSrc(),
|
||||||
|
$this->getImgSrc(),
|
||||||
$this->getObjectSrc(),
|
$this->getObjectSrc(),
|
||||||
$this->getBaseUri(),
|
$this->getBaseUri(),
|
||||||
];
|
];
|
||||||
@@ -45,6 +47,8 @@ class CspService
|
|||||||
$headers = [
|
$headers = [
|
||||||
$this->getFrameSrc(),
|
$this->getFrameSrc(),
|
||||||
$this->getScriptSrc(),
|
$this->getScriptSrc(),
|
||||||
|
$this->getStyleSrc(),
|
||||||
|
$this->getImgSrc(),
|
||||||
$this->getObjectSrc(),
|
$this->getObjectSrc(),
|
||||||
$this->getBaseUri(),
|
$this->getBaseUri(),
|
||||||
];
|
];
|
||||||
@@ -115,6 +119,22 @@ class CspService
|
|||||||
return "object-src 'self'";
|
return "object-src 'self'";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates CSP 'style-src' rule to restrict where styles can be loaded from.
|
||||||
|
*/
|
||||||
|
protected function getStyleSrc(): string
|
||||||
|
{
|
||||||
|
return 'style-src ' . implode(' ', $this->getAllowedStyleSources());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates CSP 'img-src' rule to restrict where images can be loaded from.
|
||||||
|
*/
|
||||||
|
protected function getImgSrc(): string
|
||||||
|
{
|
||||||
|
return 'img-src ' . implode(' ', $this->getAllowedImageSources());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates CSP 'base-uri' rule to restrict what base tags can be set on
|
* Creates CSP 'base-uri' rule to restrict what base tags can be set on
|
||||||
* the page to prevent manipulation of relative links.
|
* the page to prevent manipulation of relative links.
|
||||||
@@ -144,6 +164,59 @@ class CspService
|
|||||||
return array_filter($sources);
|
return array_filter($sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get allowed style sources for the style-src directive.
|
||||||
|
*/
|
||||||
|
protected function getAllowedStyleSources(): array
|
||||||
|
{
|
||||||
|
$configured = config('app.style_sources');
|
||||||
|
|
||||||
|
if (is_string($configured)) {
|
||||||
|
$sources = array_filter(explode(' ', $configured));
|
||||||
|
array_unshift($sources, "'self'");
|
||||||
|
|
||||||
|
// Ensure 'unsafe-inline' is quoted if present
|
||||||
|
// This is done as attempting to pass this in env values with quotes can either
|
||||||
|
// be awkward or cause issues.
|
||||||
|
$unsafeInlineIndex = array_search('unsafe-inline', $sources, true);
|
||||||
|
if ($unsafeInlineIndex !== false) {
|
||||||
|
$sources[$unsafeInlineIndex] = "'unsafe-inline'";
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_values(array_unique($sources));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"'self'",
|
||||||
|
"'unsafe-inline'",
|
||||||
|
'http:',
|
||||||
|
'https:',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get allowed image sources for the img-src directive.
|
||||||
|
*/
|
||||||
|
protected function getAllowedImageSources(): array
|
||||||
|
{
|
||||||
|
$configured = config('app.image_sources');
|
||||||
|
|
||||||
|
if (is_string($configured)) {
|
||||||
|
$sources = array_filter(explode(' ', $configured));
|
||||||
|
array_unshift($sources, "'self'", 'blob:', 'data:');
|
||||||
|
|
||||||
|
return array_values(array_unique($sources));
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"'self'",
|
||||||
|
'data:',
|
||||||
|
'blob:',
|
||||||
|
'http:',
|
||||||
|
'https:',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the host name of the configured drawio URL for use in CSP.
|
* Extract the host name of the configured drawio URL for use in CSP.
|
||||||
* Returns empty string if not in use.
|
* Returns empty string if not in use.
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ use BookStack\Exceptions\HttpFetchException;
|
|||||||
* Validate the host we're connecting to when making a server-side-request.
|
* Validate the host we're connecting to when making a server-side-request.
|
||||||
* Will use the given hosts config if given during construction otherwise
|
* Will use the given hosts config if given during construction otherwise
|
||||||
* will look to the app configured config.
|
* will look to the app configured config.
|
||||||
|
*
|
||||||
|
* The config format is a space-seperated list of URL prefixes which should contain the
|
||||||
|
* protocol and host. It can optionally define a path prefix as part of the URL.
|
||||||
|
* Wildcards, via a '*', can be used within these elements to match anything but a '/'.
|
||||||
*/
|
*/
|
||||||
class SsrUrlValidator
|
class SsrUrlValidator
|
||||||
{
|
{
|
||||||
@@ -48,15 +52,34 @@ class SsrUrlValidator
|
|||||||
{
|
{
|
||||||
$pattern = rtrim(trim($pattern), '/');
|
$pattern = rtrim(trim($pattern), '/');
|
||||||
$url = trim($url);
|
$url = trim($url);
|
||||||
|
$urlParts = parse_url($url);
|
||||||
|
|
||||||
if (empty($pattern) || empty($url)) {
|
if (empty($pattern) || empty($url) || $urlParts === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$quoted = preg_quote($pattern, '/');
|
// Prevent potential tricks using percent encoded slashes
|
||||||
$regexPattern = str_replace('\*', '.*', $quoted);
|
if (str_contains(strtolower($urlParts['host'] ?? ''), '%2f')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return preg_match('/^' . $regexPattern . '($|\/.*$|#.*$)/i', $url);
|
// Disregard query and fragment
|
||||||
|
$url = explode('?', $url, 2)[0];
|
||||||
|
$url = explode('#', $url, 2)[0];
|
||||||
|
|
||||||
|
// Disregard userinfo if existing
|
||||||
|
if (!empty($urlParts['user']) || !empty($urlParts['pass'])) {
|
||||||
|
[$start, $postUserinfo] = explode('@', $url, 2);
|
||||||
|
$preUserinfo = explode('//', $start, 2)[0];
|
||||||
|
$url = ($preUserinfo ? $preUserinfo . '//' : '') . $postUserinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare pattern
|
||||||
|
$quoted = preg_quote($pattern, '/');
|
||||||
|
$regexPattern = str_replace('\*', '[^\/]*', $quoted);
|
||||||
|
|
||||||
|
// Check against our URL
|
||||||
|
return preg_match('/^' . $regexPattern . '($|\/.*$)/i', $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
"socialiteproviders/okta": "^4.2",
|
"socialiteproviders/okta": "^4.2",
|
||||||
"socialiteproviders/twitch": "^5.3",
|
"socialiteproviders/twitch": "^5.3",
|
||||||
"ssddanbrown/htmldiff": "^2.0.0",
|
"ssddanbrown/htmldiff": "^2.0.0",
|
||||||
|
"web-auth/webauthn-lib": "^5.3",
|
||||||
"xemlock/htmlpurifier-html5": "^0.1.12"
|
"xemlock/htmlpurifier-html5": "^0.1.12"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
1709
composer.lock
generated
1709
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,13 @@
|
|||||||
project_id: "377219"
|
project_id: "377219"
|
||||||
project_identifier: bookstack
|
project_identifier: bookstack
|
||||||
|
api_token_env: CROWDIN_PERSONAL_TOKEN
|
||||||
|
|
||||||
base_path: .
|
base_path: .
|
||||||
preserve_hierarchy: false
|
preserve_hierarchy: false
|
||||||
pull_request_title: Updated translations with latest Crowdin changes
|
pull_request_title: Updated translations with latest Crowdin changes
|
||||||
pull_request_labels:
|
pull_request_labels:
|
||||||
- ":earth_africa: Translations"
|
- "Translations"
|
||||||
|
|
||||||
files:
|
files:
|
||||||
- source: /lang/en/*.php
|
- source: /lang/en/*.php
|
||||||
translation: /lang/%two_letters_code%/%original_file_name%
|
translation: /lang/%two_letters_code%/%original_file_name%
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ ARG BRANCH=development
|
|||||||
|
|
||||||
# Download BookStack & install PHP deps
|
# Download BookStack & install PHP deps
|
||||||
RUN mkdir -p /var/www && \
|
RUN mkdir -p /var/www && \
|
||||||
git clone https://github.com/bookstackapp/bookstack.git --branch "$BRANCH" --single-branch /var/www/bookstack && \
|
git clone https://codeberg.org/bookstack/bookstack.git --branch "$BRANCH" --single-branch /var/www/bookstack && \
|
||||||
cd /var/www/bookstack && \
|
cd /var/www/bookstack && \
|
||||||
wget https://raw.githubusercontent.com/composer/getcomposer.org/f3108f64b4e1c1ce6eb462b159956461592b3e3e/web/installer -O - -q | php -- --quiet --filename=composer && \
|
wget https://raw.githubusercontent.com/composer/getcomposer.org/f3108f64b4e1c1ce6eb462b159956461592b3e3e/web/installer -O - -q | php -- --quiet --filename=composer && \
|
||||||
php composer install
|
php composer install
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ Theme::registerCommand(new SayHelloCommand());
|
|||||||
|
|
||||||
## Available Events
|
## Available Events
|
||||||
|
|
||||||
All available events dispatched by BookStack are exposed as static properties on the `\BookStack\Theming\ThemeEvents` class, which can be found within the file `app/Theming/ThemeEvents.php` relative to your root BookStack folder. Alternatively, the events for the latest release can be [seen on GitHub here](https://github.com/BookStackApp/BookStack/blob/release/app/Theming/ThemeEvents.php).
|
All available events dispatched by BookStack are exposed as static properties on the `\BookStack\Theming\ThemeEvents` class, which can be found within the file `app/Theming/ThemeEvents.php` relative to your root BookStack folder. Alternatively, the events for the latest release can be [seen on Codeberg here](https://codeberg.org/bookstack/bookstack/src/branch/release/app/Theming/ThemeEvents.php).
|
||||||
|
|
||||||
The comments above each constant with the `ThemeEvents.php` file describe the dispatch conditions of the event, in addition to the arguments the action will receive. The comments may also describe any ways the return value of the action may be used.
|
The comments above each constant with the `ThemeEvents.php` file describe the dispatch conditions of the event, in addition to the arguments the action will receive. The comments may also describe any ways the return value of the action may be used.
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ Feature releases are generally larger, bringing new features in addition to fixe
|
|||||||
|
|
||||||
### Release Planning Process
|
### Release Planning Process
|
||||||
|
|
||||||
Each BookStack release will have a [milestone](https://github.com/BookStackApp/BookStack/milestones) created with issues & pull requests assigned to it to define what will be in that release. Milestones are built up then worked through until complete at which point, after some testing and documentation updates, the release will be deployed.
|
Each BookStack release will have a [milestone](https://codeberg.org/bookstack/bookstack/milestones) created with issues & pull requests assigned to it to define what will be in that release. Milestones are built up then worked through until complete at which point, after some testing and documentation updates, the release will be deployed.
|
||||||
|
|
||||||
### Release Announcements
|
### Release Announcements
|
||||||
|
|
||||||
Feature releases, and some patch releases, will be accompanied by a post on the [BookStack blog](https://www.bookstackapp.com/blog/) which will provide additional detail on features, changes & updates otherwise the [GitHub release page](https://github.com/BookStackApp/BookStack/releases) will show a list of changes. You can sign up to be alerted to new BookStack blog posts (once per week maximum) [at this link](https://updates.bookstackapp.com/signup/bookstack-news-and-updates).
|
Feature releases, and some patch releases, will be accompanied by a post on the [BookStack blog](https://www.bookstackapp.com/blog/) which will provide additional detail on features, changes & updates otherwise the [Codeberg release page](https://codeberg.org/bookstack/bookstack/releases) will show a list of changes. You can sign up to be alerted to new BookStack blog posts (once per week maximum) [at this link](https://updates.bookstackapp.com/signup/bookstack-news-and-updates).
|
||||||
|
|
||||||
### Release Technical Process
|
### Release Technical Process
|
||||||
|
|
||||||
Deploying a release, at a high level, simply involves merging the development branch into the release branch before then building & committing any release-only assets.
|
Deploying a release, at a high level, simply involves merging the development branch into the release branch before then building & committing any release-only assets.
|
||||||
A helper script [can be found in our](https://github.com/BookStackApp/devops/blob/main/meta-scripts/bookstack-release-steps) devops repo which provides the steps and commands for deploying a new release.
|
A helper script [can be found in our](https://codeberg.org/bookstack/devops/src/branch/main/meta-scripts/bookstack-release-steps) devops repo which provides the steps and commands for deploying a new release.
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
**Warning: This API is currently in development and may change without notice.**
|
**Warning: This API is currently in development and may change without notice.**
|
||||||
|
|
||||||
Feedback is very much welcomed via this issue: https://github.com/BookStackApp/BookStack/issues/5937
|
Feedback is very much welcomed via this issue: https://codeberg.org/bookstack/bookstack/issues/5937
|
||||||
|
|
||||||
This document covers the JavaScript API for the (newer Lexical-based) WYSIWYG editor.
|
This document covers the JavaScript API for the (newer Lexical-based) WYSIWYG editor.
|
||||||
This API is built and designed to abstract the internals of the editor away
|
This API is built and designed to abstract the internals of the editor away
|
||||||
|
|||||||
@@ -69,8 +69,9 @@ Source: zeit/arg
|
|||||||
Link: zeit/arg
|
Link: zeit/arg
|
||||||
-----------
|
-----------
|
||||||
argparse
|
argparse
|
||||||
License: Python-2.0
|
License: MIT
|
||||||
License File: node_modules/argparse/LICENSE
|
License File: node_modules/argparse/LICENSE
|
||||||
|
Copyright: Copyright (C) 2012 by Vitaly Puzrin
|
||||||
Source: nodeca/argparse
|
Source: nodeca/argparse
|
||||||
Link: nodeca/argparse
|
Link: nodeca/argparse
|
||||||
-----------
|
-----------
|
||||||
@@ -81,34 +82,6 @@ Copyright: Copyright (c) 2023 Inspect JS
|
|||||||
Source: git+https://github.com/inspect-js/array-buffer-byte-length.git
|
Source: git+https://github.com/inspect-js/array-buffer-byte-length.git
|
||||||
Link: https://github.com/inspect-js/array-buffer-byte-length#readme
|
Link: https://github.com/inspect-js/array-buffer-byte-length#readme
|
||||||
-----------
|
-----------
|
||||||
array-includes
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/array-includes/LICENSE
|
|
||||||
Copyright: Copyright (C) 2015 Jordan Harband
|
|
||||||
Source: git://github.com/es-shims/array-includes.git
|
|
||||||
Link: git://github.com/es-shims/array-includes.git
|
|
||||||
-----------
|
|
||||||
array.prototype.findlastindex
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/array.prototype.findlastindex/LICENSE
|
|
||||||
Copyright: Copyright (c) 2021 ECMAScript Shims
|
|
||||||
Source: git+https://github.com/es-shims/Array.prototype.findLastIndex.git
|
|
||||||
Link: https://github.com/es-shims/Array.prototype.findLastIndex#readme
|
|
||||||
-----------
|
|
||||||
array.prototype.flat
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/array.prototype.flat/LICENSE
|
|
||||||
Copyright: Copyright (c) 2017 ECMAScript Shims
|
|
||||||
Source: git://github.com/es-shims/Array.prototype.flat.git
|
|
||||||
Link: git://github.com/es-shims/Array.prototype.flat.git
|
|
||||||
-----------
|
|
||||||
array.prototype.flatmap
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/array.prototype.flatmap/LICENSE
|
|
||||||
Copyright: Copyright (c) 2017 ECMAScript Shims
|
|
||||||
Source: git://github.com/es-shims/Array.prototype.flatMap.git
|
|
||||||
Link: git://github.com/es-shims/Array.prototype.flatMap.git
|
|
||||||
-----------
|
|
||||||
arraybuffer.prototype.slice
|
arraybuffer.prototype.slice
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/arraybuffer.prototype.slice/LICENSE
|
License File: node_modules/arraybuffer.prototype.slice/LICENSE
|
||||||
@@ -169,9 +142,14 @@ Link: https://github.com/jestjs/jest.git
|
|||||||
balanced-match
|
balanced-match
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/balanced-match/LICENSE.md
|
License File: node_modules/balanced-match/LICENSE.md
|
||||||
Copyright: Copyright (c) 2013 Julian Gruber <******@************.***>
|
|
||||||
Source: git://github.com/juliangruber/balanced-match.git
|
Source: git://github.com/juliangruber/balanced-match.git
|
||||||
Link: https://github.com/juliangruber/balanced-match
|
Link: git://github.com/juliangruber/balanced-match.git
|
||||||
|
-----------
|
||||||
|
baseline-browser-mapping
|
||||||
|
License: Apache-2.0
|
||||||
|
License File: node_modules/baseline-browser-mapping/LICENSE.txt
|
||||||
|
Source: git+https://github.com/web-platform-dx/baseline-browser-mapping.git
|
||||||
|
Link: git+https://github.com/web-platform-dx/baseline-browser-mapping.git
|
||||||
-----------
|
-----------
|
||||||
binary-extensions
|
binary-extensions
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -184,9 +162,8 @@ Link: sindresorhus/binary-extensions
|
|||||||
brace-expansion
|
brace-expansion
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/brace-expansion/LICENSE
|
License File: node_modules/brace-expansion/LICENSE
|
||||||
Copyright: Copyright (c) 2013 Julian Gruber <******@************.***>
|
Source: git+ssh://git@github.com/juliangruber/brace-expansion.git
|
||||||
Source: git://github.com/juliangruber/brace-expansion.git
|
Link: git+ssh://git@github.com/juliangruber/brace-expansion.git
|
||||||
Link: https://github.com/juliangruber/brace-expansion
|
|
||||||
-----------
|
-----------
|
||||||
braces
|
braces
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -472,8 +449,8 @@ Link: git://github.com/ljharb/define-properties.git
|
|||||||
detect-libc
|
detect-libc
|
||||||
License: Apache-2.0
|
License: Apache-2.0
|
||||||
License File: node_modules/detect-libc/LICENSE
|
License File: node_modules/detect-libc/LICENSE
|
||||||
Source: git://github.com/lovell/detect-libc
|
Source: git://github.com/lovell/detect-libc.git
|
||||||
Link: git://github.com/lovell/detect-libc
|
Link: git://github.com/lovell/detect-libc.git
|
||||||
-----------
|
-----------
|
||||||
detect-newline
|
detect-newline
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -489,12 +466,6 @@ Copyright: Copyright (c) 2009-2015, Kevin Decker <********@*****.***>
|
|||||||
Source: git://github.com/kpdecker/jsdiff.git
|
Source: git://github.com/kpdecker/jsdiff.git
|
||||||
Link: git://github.com/kpdecker/jsdiff.git
|
Link: git://github.com/kpdecker/jsdiff.git
|
||||||
-----------
|
-----------
|
||||||
doctrine
|
|
||||||
License: Apache-2.0
|
|
||||||
License File: node_modules/doctrine/LICENSE
|
|
||||||
Source: eslint/doctrine
|
|
||||||
Link: https://github.com/eslint/doctrine
|
|
||||||
-----------
|
|
||||||
dunder-proto
|
dunder-proto
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/dunder-proto/LICENSE
|
License File: node_modules/dunder-proto/LICENSE
|
||||||
@@ -511,8 +482,8 @@ electron-to-chromium
|
|||||||
License: ISC
|
License: ISC
|
||||||
License File: node_modules/electron-to-chromium/LICENSE
|
License File: node_modules/electron-to-chromium/LICENSE
|
||||||
Copyright: Copyright 2018 Kilian Valkhof
|
Copyright: Copyright 2018 Kilian Valkhof
|
||||||
Source: https://github.com/kilian/electron-to-chromium/
|
Source: git+https://github.com/kilian/electron-to-chromium.git
|
||||||
Link: https://github.com/kilian/electron-to-chromium/
|
Link: git+https://github.com/kilian/electron-to-chromium.git
|
||||||
-----------
|
-----------
|
||||||
emittery
|
emittery
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -577,13 +548,6 @@ Copyright: Copyright (c) 2022 ECMAScript Shims
|
|||||||
Source: git+https://github.com/es-shims/es-set-tostringtag.git
|
Source: git+https://github.com/es-shims/es-set-tostringtag.git
|
||||||
Link: https://github.com/es-shims/es-set-tostringtag#readme
|
Link: https://github.com/es-shims/es-set-tostringtag#readme
|
||||||
-----------
|
-----------
|
||||||
es-shim-unscopables
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/es-shim-unscopables/LICENSE
|
|
||||||
Copyright: Copyright (c) 2022 Jordan Harband
|
|
||||||
Source: git+https://github.com/ljharb/es-shim-unscopables.git
|
|
||||||
Link: https://github.com/ljharb/es-shim-unscopables#readme
|
|
||||||
-----------
|
|
||||||
es-to-primitive
|
es-to-primitive
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/es-to-primitive/LICENSE
|
License File: node_modules/es-to-primitive/LICENSE
|
||||||
@@ -612,27 +576,6 @@ Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (https://sindres
|
|||||||
Source: sindresorhus/escape-string-regexp
|
Source: sindresorhus/escape-string-regexp
|
||||||
Link: sindresorhus/escape-string-regexp
|
Link: sindresorhus/escape-string-regexp
|
||||||
-----------
|
-----------
|
||||||
eslint-import-resolver-node
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/eslint-import-resolver-node/LICENSE
|
|
||||||
Copyright: Copyright (c) 2015 Ben Mosher
|
|
||||||
Source: https://github.com/import-js/eslint-plugin-import
|
|
||||||
Link: https://github.com/import-js/eslint-plugin-import
|
|
||||||
-----------
|
|
||||||
eslint-module-utils
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/eslint-module-utils/LICENSE
|
|
||||||
Copyright: Copyright (c) 2015 Ben Mosher
|
|
||||||
Source: git+https://github.com/import-js/eslint-plugin-import.git
|
|
||||||
Link: https://github.com/import-js/eslint-plugin-import#readme
|
|
||||||
-----------
|
|
||||||
eslint-plugin-import
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/eslint-plugin-import/LICENSE
|
|
||||||
Copyright: Copyright (c) 2015 Ben Mosher
|
|
||||||
Source: https://github.com/import-js/eslint-plugin-import
|
|
||||||
Link: https://github.com/import-js/eslint-plugin-import
|
|
||||||
-----------
|
|
||||||
eslint-scope
|
eslint-scope
|
||||||
License: BSD-2-Clause
|
License: BSD-2-Clause
|
||||||
License File: node_modules/eslint-scope/LICENSE
|
License File: node_modules/eslint-scope/LICENSE
|
||||||
@@ -814,6 +757,13 @@ Copyright: Copyright (c) 2019 Jordan Harband
|
|||||||
Source: git+https://github.com/inspect-js/functions-have-names.git
|
Source: git+https://github.com/inspect-js/functions-have-names.git
|
||||||
Link: https://github.com/inspect-js/functions-have-names#readme
|
Link: https://github.com/inspect-js/functions-have-names#readme
|
||||||
-----------
|
-----------
|
||||||
|
generator-function
|
||||||
|
License: MIT
|
||||||
|
License File: node_modules/generator-function/LICENSE.md
|
||||||
|
Copyright: Copyright (c) 2015 Tiancheng “Timothy” Gu
|
||||||
|
Source: git+https://github.com/TimothyGu/generator-function.git
|
||||||
|
Link: https://github.com/TimothyGu/generator-function#readme
|
||||||
|
-----------
|
||||||
gensync
|
gensync
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/gensync/LICENSE
|
License File: node_modules/gensync/LICENSE
|
||||||
@@ -1026,13 +976,6 @@ Copyright: Copyright (c) 2014-present, Lee Byron and other contributors.
|
|||||||
Source: git://github.com/immutable-js/immutable-js.git
|
Source: git://github.com/immutable-js/immutable-js.git
|
||||||
Link: https://immutable-js.com
|
Link: https://immutable-js.com
|
||||||
-----------
|
-----------
|
||||||
import-fresh
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/import-fresh/license
|
|
||||||
Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (https://sindresorhus.com)
|
|
||||||
Source: sindresorhus/import-fresh
|
|
||||||
Link: sindresorhus/import-fresh
|
|
||||||
-----------
|
|
||||||
import-local
|
import-local
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/import-local/license
|
License File: node_modules/import-local/license
|
||||||
@@ -1529,7 +1472,7 @@ License: MIT
|
|||||||
License File: node_modules/js-yaml/LICENSE
|
License File: node_modules/js-yaml/LICENSE
|
||||||
Copyright: Copyright (C) 2011-2015 by Vitaly Puzrin
|
Copyright: Copyright (C) 2011-2015 by Vitaly Puzrin
|
||||||
Source: nodeca/js-yaml
|
Source: nodeca/js-yaml
|
||||||
Link: nodeca/js-yaml
|
Link: https://github.com/nodeca/js-yaml
|
||||||
-----------
|
-----------
|
||||||
jsdom
|
jsdom
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -1645,12 +1588,6 @@ License File: node_modules/lodash.memoize/LICENSE
|
|||||||
Source: lodash/lodash
|
Source: lodash/lodash
|
||||||
Link: https://lodash.com/
|
Link: https://lodash.com/
|
||||||
-----------
|
-----------
|
||||||
lodash.merge
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/lodash.merge/LICENSE
|
|
||||||
Source: lodash/lodash
|
|
||||||
Link: https://lodash.com/
|
|
||||||
-----------
|
|
||||||
lodash.throttle
|
lodash.throttle
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/lodash.throttle/LICENSE
|
License File: node_modules/lodash.throttle/LICENSE
|
||||||
@@ -1741,11 +1678,10 @@ Source: sindresorhus/mimic-fn
|
|||||||
Link: sindresorhus/mimic-fn
|
Link: sindresorhus/mimic-fn
|
||||||
-----------
|
-----------
|
||||||
minimatch
|
minimatch
|
||||||
License: ISC
|
License: BlueOak-1.0.0
|
||||||
License File: node_modules/minimatch/LICENSE
|
License File: node_modules/minimatch/LICENSE.md
|
||||||
Copyright: Copyright (c) Isaac Z. Schlueter and Contributors
|
Source: git@github.com:isaacs/minimatch
|
||||||
Source: git://github.com/isaacs/minimatch.git
|
Link: git@github.com:isaacs/minimatch
|
||||||
Link: git://github.com/isaacs/minimatch.git
|
|
||||||
-----------
|
-----------
|
||||||
minimist
|
minimist
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -1754,9 +1690,8 @@ Source: git://github.com/minimistjs/minimist.git
|
|||||||
Link: https://github.com/minimistjs/minimist
|
Link: https://github.com/minimistjs/minimist
|
||||||
-----------
|
-----------
|
||||||
minipass
|
minipass
|
||||||
License: ISC
|
License: BlueOak-1.0.0
|
||||||
License File: node_modules/minipass/LICENSE
|
License File: node_modules/minipass/LICENSE.md
|
||||||
Copyright: Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors
|
|
||||||
Source: https://github.com/isaacs/minipass
|
Source: https://github.com/isaacs/minipass
|
||||||
Link: https://github.com/isaacs/minipass
|
Link: https://github.com/isaacs/minipass
|
||||||
-----------
|
-----------
|
||||||
@@ -1872,27 +1807,6 @@ Copyright: Copyright (c) 2014 Jordan Harband
|
|||||||
Source: git://github.com/ljharb/object.assign.git
|
Source: git://github.com/ljharb/object.assign.git
|
||||||
Link: git://github.com/ljharb/object.assign.git
|
Link: git://github.com/ljharb/object.assign.git
|
||||||
-----------
|
-----------
|
||||||
object.fromentries
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/object.fromentries/LICENSE
|
|
||||||
Copyright: Copyright (c) 2018 Jordan Harband
|
|
||||||
Source: git://github.com/es-shims/Object.fromEntries.git
|
|
||||||
Link: git://github.com/es-shims/Object.fromEntries.git
|
|
||||||
-----------
|
|
||||||
object.groupby
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/object.groupby/LICENSE
|
|
||||||
Copyright: Copyright (c) 2023 ECMAScript Shims
|
|
||||||
Source: git+https://github.com/es-shims/Object.groupBy.git
|
|
||||||
Link: https://github.com/es-shims/Object.groupBy#readme
|
|
||||||
-----------
|
|
||||||
object.values
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/object.values/LICENSE
|
|
||||||
Copyright: Copyright (c) 2015 Jordan Harband
|
|
||||||
Source: git://github.com/es-shims/Object.values.git
|
|
||||||
Link: git://github.com/es-shims/Object.values.git
|
|
||||||
-----------
|
|
||||||
once
|
once
|
||||||
License: ISC
|
License: ISC
|
||||||
License File: node_modules/once/LICENSE
|
License File: node_modules/once/LICENSE
|
||||||
@@ -1948,13 +1862,6 @@ License File: node_modules/package-json-from-dist/LICENSE.md
|
|||||||
Source: git+https://github.com/isaacs/package-json-from-dist.git
|
Source: git+https://github.com/isaacs/package-json-from-dist.git
|
||||||
Link: git+https://github.com/isaacs/package-json-from-dist.git
|
Link: git+https://github.com/isaacs/package-json-from-dist.git
|
||||||
-----------
|
-----------
|
||||||
parent-module
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/parent-module/license
|
|
||||||
Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (sindresorhus.com)
|
|
||||||
Source: sindresorhus/parent-module
|
|
||||||
Link: sindresorhus/parent-module
|
|
||||||
-----------
|
|
||||||
parse-json
|
parse-json
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/parse-json/license
|
License File: node_modules/parse-json/license
|
||||||
@@ -2159,8 +2066,8 @@ resolve
|
|||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/resolve/LICENSE
|
License File: node_modules/resolve/LICENSE
|
||||||
Copyright: Copyright (c) 2012 James Halliday
|
Copyright: Copyright (c) 2012 James Halliday
|
||||||
Source: git://github.com/browserify/resolve.git
|
Source: ssh://github.com/browserify/resolve.git
|
||||||
Link: git://github.com/browserify/resolve.git
|
Link: ssh://github.com/browserify/resolve.git
|
||||||
-----------
|
-----------
|
||||||
rrweb-cssom
|
rrweb-cssom
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -2405,7 +2312,7 @@ Link: sindresorhus/string-width
|
|||||||
string-width
|
string-width
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/string-width/license
|
License File: node_modules/string-width/license
|
||||||
Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (sindresorhus.com)
|
Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (https://sindresorhus.com)
|
||||||
Source: sindresorhus/string-width
|
Source: sindresorhus/string-width
|
||||||
Link: sindresorhus/string-width
|
Link: sindresorhus/string-width
|
||||||
-----------
|
-----------
|
||||||
@@ -2570,13 +2477,6 @@ Copyright: Copyright (c) 2014 Blake Embrey (*****@***********.***)
|
|||||||
Source: git://github.com/TypeStrong/ts-node.git
|
Source: git://github.com/TypeStrong/ts-node.git
|
||||||
Link: https://typestrong.org/ts-node
|
Link: https://typestrong.org/ts-node
|
||||||
-----------
|
-----------
|
||||||
tsconfig-paths
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/tsconfig-paths/LICENSE
|
|
||||||
Copyright: Copyright (c) 2016 Jonas Kello
|
|
||||||
Source: https://github.com/dividab/tsconfig-paths
|
|
||||||
Link: https://github.com/dividab/tsconfig-paths
|
|
||||||
-----------
|
|
||||||
type-check
|
type-check
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/type-check/LICENSE
|
License File: node_modules/type-check/LICENSE
|
||||||
@@ -2810,7 +2710,7 @@ Link: chalk/wrap-ansi
|
|||||||
wrap-ansi
|
wrap-ansi
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/wrap-ansi/license
|
License File: node_modules/wrap-ansi/license
|
||||||
Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (sindresorhus.com)
|
Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (https://sindresorhus.com)
|
||||||
Source: chalk/wrap-ansi
|
Source: chalk/wrap-ansi
|
||||||
Link: chalk/wrap-ansi
|
Link: chalk/wrap-ansi
|
||||||
-----------
|
-----------
|
||||||
@@ -2892,12 +2792,6 @@ Copyright: Copyright (c) Sindre Sorhus <************@*****.***> (https://sindres
|
|||||||
Source: sindresorhus/yocto-queue
|
Source: sindresorhus/yocto-queue
|
||||||
Link: sindresorhus/yocto-queue
|
Link: sindresorhus/yocto-queue
|
||||||
-----------
|
-----------
|
||||||
@ampproject/remapping
|
|
||||||
License: Apache-2.0
|
|
||||||
License File: node_modules/@ampproject/remapping/LICENSE
|
|
||||||
Source: git+https://github.com/ampproject/remapping.git
|
|
||||||
Link: git+https://github.com/ampproject/remapping.git
|
|
||||||
-----------
|
|
||||||
@asamuzakjp/css-color
|
@asamuzakjp/css-color
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@asamuzakjp/css-color/LICENSE
|
License File: node_modules/@asamuzakjp/css-color/LICENSE
|
||||||
@@ -3172,15 +3066,15 @@ Link: https://demurgos.github.io/v8-coverage
|
|||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/autocomplete/LICENSE
|
License File: node_modules/@codemirror/autocomplete/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/autocomplete.git
|
Source: git+https://github.com/codemirror/autocomplete.git
|
||||||
Link: https://github.com/codemirror/autocomplete.git
|
Link: git+https://github.com/codemirror/autocomplete.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/commands
|
@codemirror/commands
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/commands/LICENSE
|
License File: node_modules/@codemirror/commands/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/commands.git
|
Source: git+https://github.com/codemirror/commands.git
|
||||||
Link: https://github.com/codemirror/commands.git
|
Link: git+https://github.com/codemirror/commands.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/lang-css
|
@codemirror/lang-css
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -3200,8 +3094,8 @@ Link: https://github.com/codemirror/lang-html.git
|
|||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/lang-javascript/LICENSE
|
License File: node_modules/@codemirror/lang-javascript/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/lang-javascript.git
|
Source: git+https://github.com/codemirror/lang-javascript.git
|
||||||
Link: https://github.com/codemirror/lang-javascript.git
|
Link: git+https://github.com/codemirror/lang-javascript.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/lang-json
|
@codemirror/lang-json
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -3235,8 +3129,8 @@ Link: https://github.com/codemirror/lang-xml.git
|
|||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/language/LICENSE
|
License File: node_modules/@codemirror/language/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/language.git
|
Source: git+https://github.com/codemirror/language.git
|
||||||
Link: https://github.com/codemirror/language.git
|
Link: git+https://github.com/codemirror/language.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/legacy-modes
|
@codemirror/legacy-modes
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -3249,22 +3143,22 @@ Link: https://github.com/codemirror/legacy-modes.git
|
|||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/lint/LICENSE
|
License File: node_modules/@codemirror/lint/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/lint.git
|
Source: git+https://github.com/codemirror/lint.git
|
||||||
Link: https://github.com/codemirror/lint.git
|
Link: git+https://github.com/codemirror/lint.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/search
|
@codemirror/search
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/search/LICENSE
|
License File: node_modules/@codemirror/search/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/search.git
|
Source: git+https://github.com/codemirror/search.git
|
||||||
Link: https://github.com/codemirror/search.git
|
Link: git+https://github.com/codemirror/search.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/state
|
@codemirror/state
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/state/LICENSE
|
License File: node_modules/@codemirror/state/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/state.git
|
Source: git+https://github.com/codemirror/state.git
|
||||||
Link: https://github.com/codemirror/state.git
|
Link: git+https://github.com/codemirror/state.git
|
||||||
-----------
|
-----------
|
||||||
@codemirror/theme-one-dark
|
@codemirror/theme-one-dark
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -3277,8 +3171,8 @@ Link: https://github.com/codemirror/theme-one-dark.git
|
|||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@codemirror/view/LICENSE
|
License File: node_modules/@codemirror/view/LICENSE
|
||||||
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
Copyright: Copyright (C) 2018-2021 by Marijn Haverbeke <******@*********.******> and others
|
||||||
Source: https://github.com/codemirror/view.git
|
Source: git+https://github.com/codemirror/view.git
|
||||||
Link: https://github.com/codemirror/view.git
|
Link: git+https://github.com/codemirror/view.git
|
||||||
-----------
|
-----------
|
||||||
@cspotcode/source-map-support
|
@cspotcode/source-map-support
|
||||||
License: MIT
|
License: MIT
|
||||||
@@ -3358,12 +3252,6 @@ License File: node_modules/@eslint/core/LICENSE
|
|||||||
Source: git+https://github.com/eslint/rewrite.git
|
Source: git+https://github.com/eslint/rewrite.git
|
||||||
Link: https://github.com/eslint/rewrite/tree/main/packages/core#readme
|
Link: https://github.com/eslint/rewrite/tree/main/packages/core#readme
|
||||||
-----------
|
-----------
|
||||||
@eslint/eslintrc
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/@eslint/eslintrc/LICENSE
|
|
||||||
Source: eslint/eslintrc
|
|
||||||
Link: https://github.com/eslint/eslintrc#readme
|
|
||||||
-----------
|
|
||||||
@eslint/js
|
@eslint/js
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@eslint/js/LICENSE
|
License File: node_modules/@eslint/js/LICENSE
|
||||||
@@ -3567,6 +3455,13 @@ Copyright: Copyright 2024 Justin Ridgewell <******@*********.****>
|
|||||||
Source: git+https://github.com/jridgewell/sourcemaps.git
|
Source: git+https://github.com/jridgewell/sourcemaps.git
|
||||||
Link: https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping
|
Link: https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping
|
||||||
-----------
|
-----------
|
||||||
|
@jridgewell/remapping
|
||||||
|
License: MIT
|
||||||
|
License File: node_modules/@jridgewell/remapping/LICENSE
|
||||||
|
Copyright: Copyright 2024 Justin Ridgewell <******@*********.****>
|
||||||
|
Source: git+https://github.com/jridgewell/sourcemaps.git
|
||||||
|
Link: https://github.com/jridgewell/sourcemaps/tree/main/packages/remapping
|
||||||
|
-----------
|
||||||
@jridgewell/resolve-uri
|
@jridgewell/resolve-uri
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@jridgewell/resolve-uri/LICENSE
|
License File: node_modules/@jridgewell/resolve-uri/LICENSE
|
||||||
@@ -3704,18 +3599,12 @@ License: MIT
|
|||||||
Source: git+https://github.com/un-ts/pkgr.git
|
Source: git+https://github.com/un-ts/pkgr.git
|
||||||
Link: https://github.com/un-ts/pkgr/blob/master/packages/core
|
Link: https://github.com/un-ts/pkgr/blob/master/packages/core
|
||||||
-----------
|
-----------
|
||||||
@rtsao/scc
|
|
||||||
License: MIT
|
|
||||||
License File: node_modules/@rtsao/scc/LICENSE
|
|
||||||
Copyright: Copyright (c) 2019 Ryan Tsao
|
|
||||||
Source: rtsao/scc
|
|
||||||
Link: rtsao/scc
|
|
||||||
-----------
|
|
||||||
@sinclair/typebox
|
@sinclair/typebox
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@sinclair/typebox/license
|
License File: node_modules/@sinclair/typebox/license
|
||||||
Source: https://github.com/sinclairzx81/typebox
|
Copyright: Copyright (c) 2017-2026 Haydn Paterson
|
||||||
Link: https://github.com/sinclairzx81/typebox
|
Source: https://github.com/sinclairzx81/typebox-legacy
|
||||||
|
Link: https://github.com/sinclairzx81/typebox-legacy
|
||||||
-----------
|
-----------
|
||||||
@sinonjs/commons
|
@sinonjs/commons
|
||||||
License: BSD-3-Clause
|
License: BSD-3-Clause
|
||||||
@@ -3798,6 +3687,13 @@ Copyright: Copyright (c) Microsoft Corporation.
|
|||||||
Source: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
Source: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||||
Link: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/babel__traverse
|
Link: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/babel__traverse
|
||||||
-----------
|
-----------
|
||||||
|
@types/esrecurse
|
||||||
|
License: MIT
|
||||||
|
License File: node_modules/@types/esrecurse/LICENSE
|
||||||
|
Copyright: Copyright (c) Microsoft Corporation.
|
||||||
|
Source: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||||
|
Link: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/esrecurse
|
||||||
|
-----------
|
||||||
@types/estree
|
@types/estree
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@types/estree/LICENSE
|
License File: node_modules/@types/estree/LICENSE
|
||||||
@@ -3847,11 +3743,6 @@ Copyright: Copyright (c) Microsoft Corporation.
|
|||||||
Source: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
Source: https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||||
Link: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/json-schema
|
Link: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/json-schema
|
||||||
-----------
|
-----------
|
||||||
@types/json5
|
|
||||||
License: MIT
|
|
||||||
Source: https://www.github.com/DefinitelyTyped/DefinitelyTyped.git
|
|
||||||
Link: https://www.github.com/DefinitelyTyped/DefinitelyTyped.git
|
|
||||||
-----------
|
|
||||||
@types/linkify-it
|
@types/linkify-it
|
||||||
License: MIT
|
License: MIT
|
||||||
License File: node_modules/@types/linkify-it/LICENSE
|
License File: node_modules/@types/linkify-it/LICENSE
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ firebase/php-jwt
|
|||||||
License: BSD-3-Clause
|
License: BSD-3-Clause
|
||||||
License File: vendor/firebase/php-jwt/LICENSE
|
License File: vendor/firebase/php-jwt/LICENSE
|
||||||
Copyright: Copyright (c) 2011, Neuman Vong
|
Copyright: Copyright (c) 2011, Neuman Vong
|
||||||
Source: https://github.com/firebase/php-jwt.git
|
Source: https://github.com/googleapis/php-jwt.git
|
||||||
Link: https://github.com/firebase/php-jwt
|
Link: https://github.com/firebase/php-jwt
|
||||||
-----------
|
-----------
|
||||||
fruitcake/php-cors
|
fruitcake/php-cors
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'تم تحديث المستخدم بنجاح',
|
'user_update_notification' => 'تم تحديث المستخدم بنجاح',
|
||||||
'user_delete' => 'المستخدم المحذوف',
|
'user_delete' => 'المستخدم المحذوف',
|
||||||
'user_delete_notification' => 'تم إزالة المستخدم بنجاح',
|
'user_delete_notification' => 'تم إزالة المستخدم بنجاح',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'تم إنشاء رمز واجهة برمجة التطبيقات -API-',
|
'api_token_create' => 'تم إنشاء رمز واجهة برمجة التطبيقات -API-',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'البيانات المعطاة لا توافق سجلاتنا.',
|
'failed' => 'البيانات المعطاة لا توافق سجلاتنا.',
|
||||||
'throttle' => 'تجاوزت الحد الأقصى من المحاولات. الرجاء المحاولة مرة أخرى بعد :seconds ثانية/ثواني.',
|
'throttle' => 'تجاوزت الحد الأقصى من المحاولات. الرجاء المحاولة مرة أخرى بعد :seconds ثانية/ثواني.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'إنشاء حساب',
|
'sign_up' => 'إنشاء حساب',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'نقل الفصول والصفحات داخل الكتاب لإعادة تنظيم محتوياته. يمكن إضافة كتب أخرى مما يسمح بنقل الفصول والصفحات بسهولة بين الكتب. اختياريًا، يمكن تعيين قاعدة فرز تلقائي لفرز محتويات هذا الكتاب تلقائيًا عند حدوث تغييرات.',
|
'books_sort_desc' => 'نقل الفصول والصفحات داخل الكتاب لإعادة تنظيم محتوياته. يمكن إضافة كتب أخرى مما يسمح بنقل الفصول والصفحات بسهولة بين الكتب. اختياريًا، يمكن تعيين قاعدة فرز تلقائي لفرز محتويات هذا الكتاب تلقائيًا عند حدوث تغييرات.',
|
||||||
'books_sort_auto_sort' => 'خِيار الفرز التلقائي',
|
'books_sort_auto_sort' => 'خِيار الفرز التلقائي',
|
||||||
'books_sort_auto_sort_active' => 'الفرز التلقائي الشَغَّال: :sortName',
|
'books_sort_auto_sort_active' => 'الفرز التلقائي الشَغَّال: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'فرز كتاب :bookName',
|
'books_sort_named' => 'فرز كتاب :bookName',
|
||||||
'books_sort_name' => 'ترتيب حسب الإسم',
|
'books_sort_name' => 'ترتيب حسب الإسم',
|
||||||
'books_sort_created' => 'ترتيب حسب تاريخ الإنشاء',
|
'books_sort_created' => 'ترتيب حسب تاريخ الإنشاء',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'تبديل الشريط الجانبي',
|
'toggle_sidebar' => 'تبديل الشريط الجانبي',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'وسوم الصفحة',
|
'page_tags' => 'وسوم الصفحة',
|
||||||
'chapter_tags' => 'وسوم الفصل',
|
'chapter_tags' => 'وسوم الفصل',
|
||||||
'book_tags' => 'وسوم الكتاب',
|
'book_tags' => 'وسوم الكتاب',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'الكل',
|
'role_all' => 'الكل',
|
||||||
'role_own' => 'ما يخص',
|
'role_own' => 'ما يخص',
|
||||||
'role_controlled_by_asset' => 'يتحكم فيها الأصول التي يتم رفعها إلى',
|
'role_controlled_by_asset' => 'يتحكم فيها الأصول التي يتم رفعها إلى',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'حفظ الدور',
|
'role_save' => 'حفظ الدور',
|
||||||
'role_users' => 'مستخدمون داخل هذا الدور',
|
'role_users' => 'مستخدمون داخل هذا الدور',
|
||||||
'role_users_none' => 'لم يتم تعيين أي مستخدمين لهذا الدور',
|
'role_users_none' => 'لم يتم تعيين أي مستخدمين لهذا الدور',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'إعداد المصادقة متعددة العوامل كطبقة إضافية من الأمان لحساب المستخدم الخاص بك.',
|
'users_mfa_desc' => 'إعداد المصادقة متعددة العوامل كطبقة إضافية من الأمان لحساب المستخدم الخاص بك.',
|
||||||
'users_mfa_x_methods' => ':count طريقة مُهيأة | :count طرق مُهيأة',
|
'users_mfa_x_methods' => ':count طريقة مُهيأة | :count طرق مُهيأة',
|
||||||
'users_mfa_configure' => 'إعداد الطرق',
|
'users_mfa_configure' => 'إعداد الطرق',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'قم بإنشاء رمز API',
|
'user_api_token_create' => 'قم بإنشاء رمز API',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Потребителят е обновен успешно',
|
'user_update_notification' => 'Потребителят е обновен успешно',
|
||||||
'user_delete' => 'deleted user',
|
'user_delete' => 'deleted user',
|
||||||
'user_delete_notification' => 'Потребителят е премахнат успешно',
|
'user_delete_notification' => 'Потребителят е премахнат успешно',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'created API token',
|
'api_token_create' => 'created API token',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Въведените данни не съвпадат с информацията в системата.',
|
'failed' => 'Въведените данни не съвпадат с информацията в системата.',
|
||||||
'throttle' => 'Твърде много опити за влизане. Опитайте пак след :seconds секунди.',
|
'throttle' => 'Твърде много опити за влизане. Опитайте пак след :seconds секунди.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Регистриране',
|
'sign_up' => 'Регистриране',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
||||||
'books_sort_auto_sort' => 'Auto Sort Option',
|
'books_sort_auto_sort' => 'Auto Sort Option',
|
||||||
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Сортирай книга :bookName',
|
'books_sort_named' => 'Сортирай книга :bookName',
|
||||||
'books_sort_name' => 'Сортиране по име',
|
'books_sort_name' => 'Сортиране по име',
|
||||||
'books_sort_created' => 'Сортирай по дата на създаване',
|
'books_sort_created' => 'Сортирай по дата на създаване',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Toggle Sidebar',
|
'toggle_sidebar' => 'Toggle Sidebar',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Тагове на страницата',
|
'page_tags' => 'Тагове на страницата',
|
||||||
'chapter_tags' => 'Тагове на главата',
|
'chapter_tags' => 'Тагове на главата',
|
||||||
'book_tags' => 'Тагове на книгата',
|
'book_tags' => 'Тагове на книгата',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'Всички',
|
'role_all' => 'Всички',
|
||||||
'role_own' => 'Собствени',
|
'role_own' => 'Собствени',
|
||||||
'role_controlled_by_asset' => 'Контролирани от актива, към който са качени',
|
'role_controlled_by_asset' => 'Контролирани от актива, към който са качени',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Запази ролята',
|
'role_save' => 'Запази ролята',
|
||||||
'role_users' => 'Потребители в тази роля',
|
'role_users' => 'Потребители в тази роля',
|
||||||
'role_users_none' => 'В момента няма потребители, назначени за тази роля',
|
'role_users_none' => 'В момента няма потребители, назначени за тази роля',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Настрой многофакторно удостверяване като втори слой сигурност на твоя профил.',
|
'users_mfa_desc' => 'Настрой многофакторно удостверяване като втори слой сигурност на твоя профил.',
|
||||||
'users_mfa_x_methods' => ':count метод е настроен|:count методи са настроени',
|
'users_mfa_x_methods' => ':count метод е настроен|:count методи са настроени',
|
||||||
'users_mfa_configure' => 'Конфигурирай методи',
|
'users_mfa_configure' => 'Конфигурирай методи',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Създай API маркер',
|
'user_api_token_create' => 'Създай API маркер',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'ব্যবহারকারীটি সার্থকভাবে হালনাগাদ করা হয়েছে',
|
'user_update_notification' => 'ব্যবহারকারীটি সার্থকভাবে হালনাগাদ করা হয়েছে',
|
||||||
'user_delete' => 'ব্যবহারকারীটি মুছে ফেলেছেন',
|
'user_delete' => 'ব্যবহারকারীটি মুছে ফেলেছেন',
|
||||||
'user_delete_notification' => 'ব্যবহারকারীটি সার্থকভাবে মুছে ফেলা হয়েছে',
|
'user_delete_notification' => 'ব্যবহারকারীটি সার্থকভাবে মুছে ফেলা হয়েছে',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'এপিআই টোকেনটি তৈরী করেছেন',
|
'api_token_create' => 'এপিআই টোকেনটি তৈরী করেছেন',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'প্রদত্ত তথ্যনিরূপিত কোন রেকর্ড পাওয়া যায়নি।',
|
'failed' => 'প্রদত্ত তথ্যনিরূপিত কোন রেকর্ড পাওয়া যায়নি।',
|
||||||
'throttle' => 'লগইন প্রচেষ্টার সীমা অতিক্রান্ত। দয়া করে :seconds সেকেন্ড পর আবার চেষ্টা করুন।',
|
'throttle' => 'লগইন প্রচেষ্টার সীমা অতিক্রান্ত। দয়া করে :seconds সেকেন্ড পর আবার চেষ্টা করুন।',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'নিবন্ধিত হোন',
|
'sign_up' => 'নিবন্ধিত হোন',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
||||||
'books_sort_auto_sort' => 'Auto Sort Option',
|
'books_sort_auto_sort' => 'Auto Sort Option',
|
||||||
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Sort Book :bookName',
|
'books_sort_named' => 'Sort Book :bookName',
|
||||||
'books_sort_name' => 'Sort by Name',
|
'books_sort_name' => 'Sort by Name',
|
||||||
'books_sort_created' => 'Sort by Created Date',
|
'books_sort_created' => 'Sort by Created Date',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Toggle Sidebar',
|
'toggle_sidebar' => 'Toggle Sidebar',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Page Tags',
|
'page_tags' => 'Page Tags',
|
||||||
'chapter_tags' => 'Chapter Tags',
|
'chapter_tags' => 'Chapter Tags',
|
||||||
'book_tags' => 'Book Tags',
|
'book_tags' => 'Book Tags',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'All',
|
'role_all' => 'All',
|
||||||
'role_own' => 'Own',
|
'role_own' => 'Own',
|
||||||
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
|
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Save Role',
|
'role_save' => 'Save Role',
|
||||||
'role_users' => 'Users in this role',
|
'role_users' => 'Users in this role',
|
||||||
'role_users_none' => 'No users are currently assigned to this role',
|
'role_users_none' => 'No users are currently assigned to this role',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
|
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
|
||||||
'users_mfa_x_methods' => ':count method configured|:count methods configured',
|
'users_mfa_x_methods' => ':count method configured|:count methods configured',
|
||||||
'users_mfa_configure' => 'Configure Methods',
|
'users_mfa_configure' => 'Configure Methods',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Create API Token',
|
'user_api_token_create' => 'Create API Token',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'User successfully updated',
|
'user_update_notification' => 'User successfully updated',
|
||||||
'user_delete' => 'deleted user',
|
'user_delete' => 'deleted user',
|
||||||
'user_delete_notification' => 'User successfully removed',
|
'user_delete_notification' => 'User successfully removed',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'created API token',
|
'api_token_create' => 'created API token',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Ovi pristupni podaci se ne slažu sa našom evidencijom.',
|
'failed' => 'Ovi pristupni podaci se ne slažu sa našom evidencijom.',
|
||||||
'throttle' => 'Preveliki broj pokušaja prijave. Molimo vas da pokušate ponovo za :seconds sekundi.',
|
'throttle' => 'Preveliki broj pokušaja prijave. Molimo vas da pokušate ponovo za :seconds sekundi.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Registruj se',
|
'sign_up' => 'Registruj se',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
||||||
'books_sort_auto_sort' => 'Auto Sort Option',
|
'books_sort_auto_sort' => 'Auto Sort Option',
|
||||||
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Sortiraj knjigu :bookName',
|
'books_sort_named' => 'Sortiraj knjigu :bookName',
|
||||||
'books_sort_name' => 'Sortiraj po imenu',
|
'books_sort_name' => 'Sortiraj po imenu',
|
||||||
'books_sort_created' => 'Sortiraj po datumu kreiranja',
|
'books_sort_created' => 'Sortiraj po datumu kreiranja',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Toggle Sidebar',
|
'toggle_sidebar' => 'Toggle Sidebar',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Oznake stranice',
|
'page_tags' => 'Oznake stranice',
|
||||||
'chapter_tags' => 'Oznake poglavlja',
|
'chapter_tags' => 'Oznake poglavlja',
|
||||||
'book_tags' => 'Oznake knjige',
|
'book_tags' => 'Oznake knjige',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'All',
|
'role_all' => 'All',
|
||||||
'role_own' => 'Own',
|
'role_own' => 'Own',
|
||||||
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
|
'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Save Role',
|
'role_save' => 'Save Role',
|
||||||
'role_users' => 'Users in this role',
|
'role_users' => 'Users in this role',
|
||||||
'role_users_none' => 'No users are currently assigned to this role',
|
'role_users_none' => 'No users are currently assigned to this role',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
|
'users_mfa_desc' => 'Setup multi-factor authentication as an extra layer of security for your user account.',
|
||||||
'users_mfa_x_methods' => ':count method configured|:count methods configured',
|
'users_mfa_x_methods' => ':count method configured|:count methods configured',
|
||||||
'users_mfa_configure' => 'Configure Methods',
|
'users_mfa_configure' => 'Configure Methods',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Create API Token',
|
'user_api_token_create' => 'Create API Token',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'S’ha actualitzat l’usuari',
|
'user_update_notification' => 'S’ha actualitzat l’usuari',
|
||||||
'user_delete' => 'ha suprimit l’usuari',
|
'user_delete' => 'ha suprimit l’usuari',
|
||||||
'user_delete_notification' => 'S’ha suprimit l’usuari',
|
'user_delete_notification' => 'S’ha suprimit l’usuari',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'ha creat el testimoni API',
|
'api_token_create' => 'ha creat el testimoni API',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Aquestes credencials no existeixen al nostre registre.',
|
'failed' => 'Aquestes credencials no existeixen al nostre registre.',
|
||||||
'throttle' => 'Massa intents d’inici de sessió. Torneu-ho a provar d’aquí :seconds segons.',
|
'throttle' => 'Massa intents d’inici de sessió. Torneu-ho a provar d’aquí :seconds segons.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Registreu-vos',
|
'sign_up' => 'Registreu-vos',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Mou capítols i pàgines dins d\'un llibre per reorganitzar el seu contingut. Es poden afegir altres llibres que permetin moure fàcilment capítols i pàgines entre llibres. De manera opcional, es poden establir regles d\'ordenació automàtica per ordenar automàticament el contingut d\'aquest llibre quan hi hagi canvis.',
|
'books_sort_desc' => 'Mou capítols i pàgines dins d\'un llibre per reorganitzar el seu contingut. Es poden afegir altres llibres que permetin moure fàcilment capítols i pàgines entre llibres. De manera opcional, es poden establir regles d\'ordenació automàtica per ordenar automàticament el contingut d\'aquest llibre quan hi hagi canvis.',
|
||||||
'books_sort_auto_sort' => 'Opció d\'ordenació automàtica',
|
'books_sort_auto_sort' => 'Opció d\'ordenació automàtica',
|
||||||
'books_sort_auto_sort_active' => 'Opció d\'ordenació activa :sortName',
|
'books_sort_auto_sort_active' => 'Opció d\'ordenació activa :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Ordena el llibre «:bookName»',
|
'books_sort_named' => 'Ordena el llibre «:bookName»',
|
||||||
'books_sort_name' => 'Ordena pel nom',
|
'books_sort_name' => 'Ordena pel nom',
|
||||||
'books_sort_created' => 'Ordena per la data de creació',
|
'books_sort_created' => 'Ordena per la data de creació',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Commuta la barra lateral',
|
'toggle_sidebar' => 'Commuta la barra lateral',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Etiquetes de la pàgina',
|
'page_tags' => 'Etiquetes de la pàgina',
|
||||||
'chapter_tags' => 'Etiquetes del capítol',
|
'chapter_tags' => 'Etiquetes del capítol',
|
||||||
'book_tags' => 'Etiquetes del llibre',
|
'book_tags' => 'Etiquetes del llibre',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'Tot',
|
'role_all' => 'Tot',
|
||||||
'role_own' => 'Propi',
|
'role_own' => 'Propi',
|
||||||
'role_controlled_by_asset' => 'Controlat pel recurs a què estan pujats',
|
'role_controlled_by_asset' => 'Controlat pel recurs a què estan pujats',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Desa el rol',
|
'role_save' => 'Desa el rol',
|
||||||
'role_users' => 'Usuaris assignats en aquest rol',
|
'role_users' => 'Usuaris assignats en aquest rol',
|
||||||
'role_users_none' => 'No hi ha cap usuari assignat en aquest rol',
|
'role_users_none' => 'No hi ha cap usuari assignat en aquest rol',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Configureu l’autenticació multifactorial per a afegir una capa de seguretat extra al vostre compte d’usuari.',
|
'users_mfa_desc' => 'Configureu l’autenticació multifactorial per a afegir una capa de seguretat extra al vostre compte d’usuari.',
|
||||||
'users_mfa_x_methods' => 'Hi ha :count mètode configurat|Hi ha :count mètodes configurats',
|
'users_mfa_x_methods' => 'Hi ha :count mètode configurat|Hi ha :count mètodes configurats',
|
||||||
'users_mfa_configure' => 'Configura un mètode',
|
'users_mfa_configure' => 'Configura un mètode',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Crea un testimoni API',
|
'user_api_token_create' => 'Crea un testimoni API',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Uživatel byl úspěšně aktualizován',
|
'user_update_notification' => 'Uživatel byl úspěšně aktualizován',
|
||||||
'user_delete' => 'odstranil uživatele',
|
'user_delete' => 'odstranil uživatele',
|
||||||
'user_delete_notification' => 'Uživatel byl úspěšně odstraněn',
|
'user_delete_notification' => 'Uživatel byl úspěšně odstraněn',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'API token byl vytvořen',
|
'api_token_create' => 'API token byl vytvořen',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Neplatné přihlašovací údaje.',
|
'failed' => 'Neplatné přihlašovací údaje.',
|
||||||
'throttle' => 'Příliš mnoho pokusů o přihlášení. Zkuste to prosím znovu za :seconds sekund.',
|
'throttle' => 'Příliš mnoho pokusů o přihlášení. Zkuste to prosím znovu za :seconds sekund.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Registrace',
|
'sign_up' => 'Registrace',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Pro přeuspořádání obsahu přesuňte kapitoly a stránky v knize. Mohou být přidány další knihy, které umožní snadný přesun kapitol a stránek mezi knihami. Volitelně lze nastavit pravidlo automatického řazení, aby se při změnách automaticky seřadil obsah této knihy.',
|
'books_sort_desc' => 'Pro přeuspořádání obsahu přesuňte kapitoly a stránky v knize. Mohou být přidány další knihy, které umožní snadný přesun kapitol a stránek mezi knihami. Volitelně lze nastavit pravidlo automatického řazení, aby se při změnách automaticky seřadil obsah této knihy.',
|
||||||
'books_sort_auto_sort' => 'Možnost automatického řazení',
|
'books_sort_auto_sort' => 'Možnost automatického řazení',
|
||||||
'books_sort_auto_sort_active' => 'Aktivní automatické řazení: :sortName',
|
'books_sort_auto_sort_active' => 'Aktivní automatické řazení: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Seřadit knihu :bookName',
|
'books_sort_named' => 'Seřadit knihu :bookName',
|
||||||
'books_sort_name' => 'Seřadit podle názvu',
|
'books_sort_name' => 'Seřadit podle názvu',
|
||||||
'books_sort_created' => 'Seřadit podle data vytvoření',
|
'books_sort_created' => 'Seřadit podle data vytvoření',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Skrýt/Zobrazit postranní panel',
|
'toggle_sidebar' => 'Skrýt/Zobrazit postranní panel',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Štítky stránky',
|
'page_tags' => 'Štítky stránky',
|
||||||
'chapter_tags' => 'Štítky kapitoly',
|
'chapter_tags' => 'Štítky kapitoly',
|
||||||
'book_tags' => 'Štítky knihy',
|
'book_tags' => 'Štítky knihy',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'Vše',
|
'role_all' => 'Vše',
|
||||||
'role_own' => 'Vlastní',
|
'role_own' => 'Vlastní',
|
||||||
'role_controlled_by_asset' => 'Řídí se obsahem, do kterého jsou nahrávány',
|
'role_controlled_by_asset' => 'Řídí se obsahem, do kterého jsou nahrávány',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Uložit roli',
|
'role_save' => 'Uložit roli',
|
||||||
'role_users' => 'Uživatelé mající tuto roli',
|
'role_users' => 'Uživatelé mající tuto roli',
|
||||||
'role_users_none' => 'Žádný uživatel nemá tuto roli',
|
'role_users_none' => 'Žádný uživatel nemá tuto roli',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Nastavit vícefaktorové ověřování jako další vrstvu zabezpečení vašeho uživatelského účtu.',
|
'users_mfa_desc' => 'Nastavit vícefaktorové ověřování jako další vrstvu zabezpečení vašeho uživatelského účtu.',
|
||||||
'users_mfa_x_methods' => ':count nastavená metoda|:count nastavených metod',
|
'users_mfa_x_methods' => ':count nastavená metoda|:count nastavených metod',
|
||||||
'users_mfa_configure' => 'Konfigurovat metody',
|
'users_mfa_configure' => 'Konfigurovat metody',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Vytvořit API Token',
|
'user_api_token_create' => 'Vytvořit API Token',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Diweddarwyd y defnyddiwr yn llwyddiannus',
|
'user_update_notification' => 'Diweddarwyd y defnyddiwr yn llwyddiannus',
|
||||||
'user_delete' => 'dileodd ddefnyddiwr',
|
'user_delete' => 'dileodd ddefnyddiwr',
|
||||||
'user_delete_notification' => 'Tynnwyd y defnyddiwr yn llwyddiannus',
|
'user_delete_notification' => 'Tynnwyd y defnyddiwr yn llwyddiannus',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'creodd docyn API',
|
'api_token_create' => 'creodd docyn API',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Nid yw\'r manylion hyn yn cyfateb i\'n cofnodion.',
|
'failed' => 'Nid yw\'r manylion hyn yn cyfateb i\'n cofnodion.',
|
||||||
'throttle' => 'Gormod o ymdrechion mewngofnodi. Rhowch gynnig arall arni o gwmpas :seconds eiliadau.',
|
'throttle' => 'Gormod o ymdrechion mewngofnodi. Rhowch gynnig arall arni o gwmpas :seconds eiliadau.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Cofrestru',
|
'sign_up' => 'Cofrestru',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
||||||
'books_sort_auto_sort' => 'Auto Sort Option',
|
'books_sort_auto_sort' => 'Auto Sort Option',
|
||||||
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Trefnu Llyfr :bookName',
|
'books_sort_named' => 'Trefnu Llyfr :bookName',
|
||||||
'books_sort_name' => 'Trefnu yn ôl Enw',
|
'books_sort_name' => 'Trefnu yn ôl Enw',
|
||||||
'books_sort_created' => 'Trefnu yn ôl Dyddiad Creu',
|
'books_sort_created' => 'Trefnu yn ôl Dyddiad Creu',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Toglo Bar ochr',
|
'toggle_sidebar' => 'Toglo Bar ochr',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Tagiau Tudalennau',
|
'page_tags' => 'Tagiau Tudalennau',
|
||||||
'chapter_tags' => 'Tagiau Penodau',
|
'chapter_tags' => 'Tagiau Penodau',
|
||||||
'book_tags' => 'Tagiau Llyfrau',
|
'book_tags' => 'Tagiau Llyfrau',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'Popeth',
|
'role_all' => 'Popeth',
|
||||||
'role_own' => 'Meddu',
|
'role_own' => 'Meddu',
|
||||||
'role_controlled_by_asset' => 'Wedi\'u rheoli gan yr ased y maent yn cael eu huwchlwytho iddo',
|
'role_controlled_by_asset' => 'Wedi\'u rheoli gan yr ased y maent yn cael eu huwchlwytho iddo',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Cadw Rôl',
|
'role_save' => 'Cadw Rôl',
|
||||||
'role_users' => 'Defnyddwyr yn y rôl hon',
|
'role_users' => 'Defnyddwyr yn y rôl hon',
|
||||||
'role_users_none' => 'Nid oes unrhyw ddefnyddwyr wedi’u neilltuo i\'r rôl hon ar hyn o bryd',
|
'role_users_none' => 'Nid oes unrhyw ddefnyddwyr wedi’u neilltuo i\'r rôl hon ar hyn o bryd',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Gosod dilysu aml-ffactor fel haen ychwanegol o ddiogelwch ar gyfer eich cyfrif defnyddiwr.',
|
'users_mfa_desc' => 'Gosod dilysu aml-ffactor fel haen ychwanegol o ddiogelwch ar gyfer eich cyfrif defnyddiwr.',
|
||||||
'users_mfa_x_methods' => ':count dull wedi\'i ffurfweddu|:count dull wedi\'u ffurfweddu',
|
'users_mfa_x_methods' => ':count dull wedi\'i ffurfweddu|:count dull wedi\'u ffurfweddu',
|
||||||
'users_mfa_configure' => 'Ffurfweddu Dulliau',
|
'users_mfa_configure' => 'Ffurfweddu Dulliau',
|
||||||
|
'users_mfa_reset' => 'Reset Multi-Factor Authentication Methods',
|
||||||
|
'users_mfa_reset_desc' => 'This will reset and clear all configured multi-factor authentication methods for this user. If multi-factor authentication is required by any of their roles, they\'ll be prompted to configure new methods on their next login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Are you sure you want to reset multi-factor authentication for this user?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Creu Tocyn API',
|
'user_api_token_create' => 'Creu Tocyn API',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Brugeren blev opdateret',
|
'user_update_notification' => 'Brugeren blev opdateret',
|
||||||
'user_delete' => 'slettet bruger',
|
'user_delete' => 'slettet bruger',
|
||||||
'user_delete_notification' => 'Brugeren blev fjernet',
|
'user_delete_notification' => 'Brugeren blev fjernet',
|
||||||
|
'user_mfa_reset' => 'nulstil MFA for brugeren',
|
||||||
|
'user_mfa_reset_notification' => 'Nulstilling af metoder til multifaktor-godkendelse',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'oprettet API token',
|
'api_token_create' => 'oprettet API token',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'De indtastede brugeroplysninger stemmer ikke overens med vores registreringer.',
|
'failed' => 'De indtastede brugeroplysninger stemmer ikke overens med vores registreringer.',
|
||||||
'throttle' => 'For mange mislykkede loginforsøg. Prøv igen om :seconds sekunder.',
|
'throttle' => 'For mange mislykkede loginforsøg. Prøv igen om :seconds sekunder.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Registrer',
|
'sign_up' => 'Registrer',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Flyt kapitler og sider i en bog for at omorganisere dens indhold. Der kan tilføjes andre bøger, som gør det nemt at flytte kapitler og sider mellem bøgerne. Man kan indstille en automatisk sorteringsregel, så bogens indhold automatisk sorteres efter ændringer.',
|
'books_sort_desc' => 'Flyt kapitler og sider i en bog for at omorganisere dens indhold. Der kan tilføjes andre bøger, som gør det nemt at flytte kapitler og sider mellem bøgerne. Man kan indstille en automatisk sorteringsregel, så bogens indhold automatisk sorteres efter ændringer.',
|
||||||
'books_sort_auto_sort' => 'Mulighed for automatisk sortering',
|
'books_sort_auto_sort' => 'Mulighed for automatisk sortering',
|
||||||
'books_sort_auto_sort_active' => 'Automatisk sortering Aktiv: :sortName',
|
'books_sort_auto_sort_active' => 'Automatisk sortering Aktiv: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'En bruger med de nødvendige rettigheder kan oprette regler for automatisk sortering i indstillingsområdet »Lister og sortering«.',
|
||||||
'books_sort_named' => 'Sorter bog :bookName',
|
'books_sort_named' => 'Sorter bog :bookName',
|
||||||
'books_sort_name' => 'Sortér efter navn',
|
'books_sort_name' => 'Sortér efter navn',
|
||||||
'books_sort_created' => 'Sortér efter oprettelsesdato',
|
'books_sort_created' => 'Sortér efter oprettelsesdato',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Sidebjælke til/fra',
|
'toggle_sidebar' => 'Sidebjælke til/fra',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Sidetags',
|
'page_tags' => 'Sidetags',
|
||||||
'chapter_tags' => 'Kapiteltags',
|
'chapter_tags' => 'Kapiteltags',
|
||||||
'book_tags' => 'Bogtags',
|
'book_tags' => 'Bogtags',
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'Alle',
|
'role_all' => 'Alle',
|
||||||
'role_own' => 'Eget',
|
'role_own' => 'Eget',
|
||||||
'role_controlled_by_asset' => 'Styres af det medie/"asset", de uploades til',
|
'role_controlled_by_asset' => 'Styres af det medie/"asset", de uploades til',
|
||||||
|
'role_controlled_by_page_delete' => 'Styres af tilladelser til sletning af sider',
|
||||||
'role_save' => 'Gem rolle',
|
'role_save' => 'Gem rolle',
|
||||||
'role_users' => 'Brugere med denne rolle',
|
'role_users' => 'Brugere med denne rolle',
|
||||||
'role_users_none' => 'Ingen brugere er i øjeblikket tildelt denne rolle',
|
'role_users_none' => 'Ingen brugere er i øjeblikket tildelt denne rolle',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Opsæt multi-faktor godkendelse som et ekstra lag af sikkerhed for din brugerkonto.',
|
'users_mfa_desc' => 'Opsæt multi-faktor godkendelse som et ekstra lag af sikkerhed for din brugerkonto.',
|
||||||
'users_mfa_x_methods' => ':count metode konfigureret|:count metoder konfigureret',
|
'users_mfa_x_methods' => ':count metode konfigureret|:count metoder konfigureret',
|
||||||
'users_mfa_configure' => 'Konfigurer metoder',
|
'users_mfa_configure' => 'Konfigurer metoder',
|
||||||
|
'users_mfa_reset' => 'Nulstil metoder til multifaktor-godkendelse',
|
||||||
|
'users_mfa_reset_desc' => 'Dette vil nulstille og slette alle konfigurerede metoder til multifaktor-godkendelse for denne bruger. Hvis multifaktor-godkendelse er påkrævet for en af brugerens roller, vil vedkommende blive bedt om at konfigurere nye metoder ved næste login.',
|
||||||
|
'users_mfa_reset_confirm' => 'Er du sikker på, at du vil nulstille multifaktorautentificering for denne bruger?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Opret API-token',
|
'user_api_token_create' => 'Opret API-token',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slovensky',
|
'sk' => 'Slovensky',
|
||||||
'sl' => 'Slovenščina',
|
'sl' => 'Slovenščina',
|
||||||
'sv' => 'Svenska',
|
'sv' => 'Svenska',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkçe',
|
'tr' => 'Türkçe',
|
||||||
'uk' => 'Українська',
|
'uk' => 'Українська',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Benutzer erfolgreich aktualisiert',
|
'user_update_notification' => 'Benutzer erfolgreich aktualisiert',
|
||||||
'user_delete' => 'hat Benutzer gelöscht: ',
|
'user_delete' => 'hat Benutzer gelöscht: ',
|
||||||
'user_delete_notification' => 'Benutzer erfolgreich entfernt',
|
'user_delete_notification' => 'Benutzer erfolgreich entfernt',
|
||||||
|
'user_mfa_reset' => 'Setze MFA für Nutzer zurück',
|
||||||
|
'user_mfa_reset_notification' => 'Multifaktor-Authenifizierungsmethoden zurücksetzen',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'API-Token erstellt',
|
'api_token_create' => 'API-Token erstellt',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Diese Anmeldedaten stimmen nicht mit unseren Aufzeichnungen überein.',
|
'failed' => 'Diese Anmeldedaten stimmen nicht mit unseren Aufzeichnungen überein.',
|
||||||
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuchen Sie es in :seconds Sekunden erneut.',
|
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuchen Sie es in :seconds Sekunden erneut.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Registrieren',
|
'sign_up' => 'Registrieren',
|
||||||
@@ -39,7 +40,7 @@ return [
|
|||||||
'register_success' => 'Vielen Dank für Ihre Registrierung! Die Daten sind gespeichert und Sie sind angemeldet.',
|
'register_success' => 'Vielen Dank für Ihre Registrierung! Die Daten sind gespeichert und Sie sind angemeldet.',
|
||||||
|
|
||||||
// Login auto-initiation
|
// Login auto-initiation
|
||||||
'auto_init_starting' => 'Anmeldeversuche',
|
'auto_init_starting' => 'Anmeldeversuch',
|
||||||
'auto_init_starting_desc' => 'Wir verbinden uns mit Ihrem Authentifizierungssystem, um den Anmeldeprozess zu starten. Sollte es nach 5 Sekunden nicht weitergehen, klicken Sie bitte auf den unten stehenden Link.',
|
'auto_init_starting_desc' => 'Wir verbinden uns mit Ihrem Authentifizierungssystem, um den Anmeldeprozess zu starten. Sollte es nach 5 Sekunden nicht weitergehen, klicken Sie bitte auf den unten stehenden Link.',
|
||||||
'auto_init_start_link' => 'Mit Authentifizierung fortfahren',
|
'auto_init_start_link' => 'Mit Authentifizierung fortfahren',
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Verschieben Sie Kapitel und Seiten innerhalb eines Buches, um dessen Inhalt neu zu ordnen. Es können weitere Bücher hinzugefügt werden, wodurch Kapitel und Seiten problemlos zwischen den Büchern verschoben werden können. Optional kann eine automatische Sortierregel festgelegt werden, um den Inhalt dieses Buches bei Änderungen automatisch zu sortieren.',
|
'books_sort_desc' => 'Verschieben Sie Kapitel und Seiten innerhalb eines Buches, um dessen Inhalt neu zu ordnen. Es können weitere Bücher hinzugefügt werden, wodurch Kapitel und Seiten problemlos zwischen den Büchern verschoben werden können. Optional kann eine automatische Sortierregel festgelegt werden, um den Inhalt dieses Buches bei Änderungen automatisch zu sortieren.',
|
||||||
'books_sort_auto_sort' => 'Automatische Sortierfunktionsoption',
|
'books_sort_auto_sort' => 'Automatische Sortierfunktionsoption',
|
||||||
'books_sort_auto_sort_active' => 'Automatische Sortierung aktiv: :sortName',
|
'books_sort_auto_sort_active' => 'Automatische Sortierung aktiv: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Buch ":bookName" sortieren',
|
'books_sort_named' => 'Buch ":bookName" sortieren',
|
||||||
'books_sort_name' => 'Sortieren nach Namen',
|
'books_sort_name' => 'Sortieren nach Namen',
|
||||||
'books_sort_created' => 'Sortieren nach Erstellungsdatum',
|
'books_sort_created' => 'Sortieren nach Erstellungsdatum',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Seitenleiste umschalten',
|
'toggle_sidebar' => 'Seitenleiste umschalten',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Seiten-Schlagwörter',
|
'page_tags' => 'Seiten-Schlagwörter',
|
||||||
'chapter_tags' => 'Kapitel-Schlagwörter',
|
'chapter_tags' => 'Kapitel-Schlagwörter',
|
||||||
'book_tags' => 'Buch-Schlagwörter',
|
'book_tags' => 'Buch-Schlagwörter',
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ return [
|
|||||||
'recycle_bin_restore_confirm' => 'Durch diese Aktion wird das gelöschte Element einschließlich aller untergeordneten Elemente an seinem ursprünglichen Speicherort wiederhergestellt. Sollte der ursprüngliche Speicherort inzwischen gelöscht worden sein und sich nun im Papierkorb befinden, muss auch das übergeordnete Element wiederhergestellt werden.',
|
'recycle_bin_restore_confirm' => 'Durch diese Aktion wird das gelöschte Element einschließlich aller untergeordneten Elemente an seinem ursprünglichen Speicherort wiederhergestellt. Sollte der ursprüngliche Speicherort inzwischen gelöscht worden sein und sich nun im Papierkorb befinden, muss auch das übergeordnete Element wiederhergestellt werden.',
|
||||||
'recycle_bin_restore_deleted_parent' => 'Das übergeordnete Element dieses Eintrags wurde ebenfalls gelöscht. Diese Einträge bleiben gelöscht, bis auch das übergeordnete Element wiederhergestellt wird.',
|
'recycle_bin_restore_deleted_parent' => 'Das übergeordnete Element dieses Eintrags wurde ebenfalls gelöscht. Diese Einträge bleiben gelöscht, bis auch das übergeordnete Element wiederhergestellt wird.',
|
||||||
'recycle_bin_restore_parent' => 'Übergeordneter Eintrag wiederherstellen',
|
'recycle_bin_restore_parent' => 'Übergeordneter Eintrag wiederherstellen',
|
||||||
'recycle_bin_destroy_notification' => 'Löscht :count Elemente aus dem Papierkorb.',
|
'recycle_bin_destroy_notification' => ':count Elemente aus dem Papierkorb gelöscht.',
|
||||||
'recycle_bin_restore_notification' => 'Es wurden :count der Elemente aus dem Papierkorb wiederhergestellt.',
|
'recycle_bin_restore_notification' => 'Es wurden :count der Elemente aus dem Papierkorb wiederhergestellt.',
|
||||||
|
|
||||||
// Audit Log
|
// Audit Log
|
||||||
@@ -207,6 +207,7 @@ return [
|
|||||||
'role_all' => 'Alle',
|
'role_all' => 'Alle',
|
||||||
'role_own' => 'Eigene',
|
'role_own' => 'Eigene',
|
||||||
'role_controlled_by_asset' => 'Abhängig von dem Asset, in das sie hochgeladen werden',
|
'role_controlled_by_asset' => 'Abhängig von dem Asset, in das sie hochgeladen werden',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Rolle speichern',
|
'role_save' => 'Rolle speichern',
|
||||||
'role_users' => 'Dieser Rolle zugeordnete Benutzer',
|
'role_users' => 'Dieser Rolle zugeordnete Benutzer',
|
||||||
'role_users_none' => 'Derzeit sind diesem Rollentyp keine Benutzer zugewiesen',
|
'role_users_none' => 'Derzeit sind diesem Rollentyp keine Benutzer zugewiesen',
|
||||||
@@ -263,6 +264,9 @@ return [
|
|||||||
'users_mfa_desc' => 'Richten Sie die Multi-Faktor-Authentifizierung als zusätzliche Sicherheitsstufe für Ihr Benutzerkonto ein.',
|
'users_mfa_desc' => 'Richten Sie die Multi-Faktor-Authentifizierung als zusätzliche Sicherheitsstufe für Ihr Benutzerkonto ein.',
|
||||||
'users_mfa_x_methods' => ':count Methode konfiguriert|:count Methoden konfiguriert',
|
'users_mfa_x_methods' => ':count Methode konfiguriert|:count Methoden konfiguriert',
|
||||||
'users_mfa_configure' => 'Methoden konfigurieren',
|
'users_mfa_configure' => 'Methoden konfigurieren',
|
||||||
|
'users_mfa_reset' => 'Setze Multifaktor-Authentifizierung zurück',
|
||||||
|
'users_mfa_reset_desc' => 'Dies wird alle konfigurierten Multifaktor-Authentifizierungsmethoden für diesen Nutzer zurücksetzen. Falls Multifaktor-Authentifizierung für eine seiner Rollen erforderlich ist, werden sie aufgefordert, neue Methoden beim nächsten Login zu konfigurieren.',
|
||||||
|
'users_mfa_reset_confirm' => 'Sind Sie sicher, dass Sie diese Multi-Faktor-Authentifizierungsmethode für diesen Nutzer zurücksetzen möchten?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Neuen API-Token erstellen',
|
'user_api_token_create' => 'Neuen API-Token erstellen',
|
||||||
@@ -363,6 +367,7 @@ return [
|
|||||||
'sk' => 'Slowenisch',
|
'sk' => 'Slowenisch',
|
||||||
'sl' => 'Slowenisch',
|
'sl' => 'Slowenisch',
|
||||||
'sv' => 'Schwedisch',
|
'sv' => 'Schwedisch',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkisch',
|
'tr' => 'Türkisch',
|
||||||
'uk' => 'Ukrainisch',
|
'uk' => 'Ukrainisch',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ return [
|
|||||||
'uploaded' => 'Die Datei konnte nicht hochgeladen werden. Der Server akzeptiert möglicherweise keine Dateien dieser Größe.',
|
'uploaded' => 'Die Datei konnte nicht hochgeladen werden. Der Server akzeptiert möglicherweise keine Dateien dieser Größe.',
|
||||||
|
|
||||||
'zip_file' => ':attribute muss eine Datei innerhalb des ZIP referenzieren.',
|
'zip_file' => ':attribute muss eine Datei innerhalb des ZIP referenzieren.',
|
||||||
'zip_file_size' => 'The file :attribute must not exceed :size MB.',
|
'zip_file_size' => 'Die Datei :attribute darf :size MB nicht überschreiten.',
|
||||||
'zip_file_mime' => ':attribute muss eine Datei des Typs :validType referenzieren, gefunden :foundType.',
|
'zip_file_mime' => ':attribute muss eine Datei des Typs :validType referenzieren, gefunden :foundType.',
|
||||||
'zip_model_expected' => 'Datenobjekt erwartet, aber ":type" gefunden.',
|
'zip_model_expected' => 'Datenobjekt erwartet, aber ":type" gefunden.',
|
||||||
'zip_unique' => ':attribute muss für den Objekttyp innerhalb des ZIP eindeutig sein.',
|
'zip_unique' => ':attribute muss für den Objekttyp innerhalb des ZIP eindeutig sein.',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Benutzer erfolgreich aktualisiert',
|
'user_update_notification' => 'Benutzer erfolgreich aktualisiert',
|
||||||
'user_delete' => 'hat Benutzer gelöscht: ',
|
'user_delete' => 'hat Benutzer gelöscht: ',
|
||||||
'user_delete_notification' => 'Benutzer erfolgreich entfernt',
|
'user_delete_notification' => 'Benutzer erfolgreich entfernt',
|
||||||
|
'user_mfa_reset' => 'Setze MFA für Nutzer zurück',
|
||||||
|
'user_mfa_reset_notification' => 'Multifaktor-Authenifizierungsmethoden zurücksetzen',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'API Token wurde erstellt',
|
'api_token_create' => 'API Token wurde erstellt',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Die eingegebenen Anmeldedaten sind ungültig.',
|
'failed' => 'Die eingegebenen Anmeldedaten sind ungültig.',
|
||||||
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuche es in :seconds Sekunden erneut.',
|
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuche es in :seconds Sekunden erneut.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Registrieren',
|
'sign_up' => 'Registrieren',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Kapitel und Seiten innerhalb eines Buches verschieben, um dessen Inhalt zu reorganisieren. Andere Bücher können hinzugefügt werden, was das Verschieben von Kapiteln und Seiten zwischen Büchern erleichtert. Optional kann eine automatische Sortierregel erstellt werden, um den Inhalt dieses Buches nach Änderungen automatisch zu sortieren.',
|
'books_sort_desc' => 'Kapitel und Seiten innerhalb eines Buches verschieben, um dessen Inhalt zu reorganisieren. Andere Bücher können hinzugefügt werden, was das Verschieben von Kapiteln und Seiten zwischen Büchern erleichtert. Optional kann eine automatische Sortierregel erstellt werden, um den Inhalt dieses Buches nach Änderungen automatisch zu sortieren.',
|
||||||
'books_sort_auto_sort' => 'Auto-Sortieroption',
|
'books_sort_auto_sort' => 'Auto-Sortieroption',
|
||||||
'books_sort_auto_sort_active' => 'Automatische Sortierung aktiv: :sortName',
|
'books_sort_auto_sort_active' => 'Automatische Sortierung aktiv: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Buch ":bookName" sortieren',
|
'books_sort_named' => 'Buch ":bookName" sortieren',
|
||||||
'books_sort_name' => 'Sortieren nach Namen',
|
'books_sort_name' => 'Sortieren nach Namen',
|
||||||
'books_sort_created' => 'Sortieren nach Erstellungsdatum',
|
'books_sort_created' => 'Sortieren nach Erstellungsdatum',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Seitenleiste umschalten',
|
'toggle_sidebar' => 'Seitenleiste umschalten',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Seiten-Schlagwörter',
|
'page_tags' => 'Seiten-Schlagwörter',
|
||||||
'chapter_tags' => 'Kapitel-Schlagwörter',
|
'chapter_tags' => 'Kapitel-Schlagwörter',
|
||||||
'book_tags' => 'Buch-Schlagwörter',
|
'book_tags' => 'Buch-Schlagwörter',
|
||||||
@@ -410,10 +414,10 @@ return [
|
|||||||
'comment_deleted_success' => 'Kommentar gelöscht',
|
'comment_deleted_success' => 'Kommentar gelöscht',
|
||||||
'comment_created_success' => 'Kommentar hinzugefügt',
|
'comment_created_success' => 'Kommentar hinzugefügt',
|
||||||
'comment_updated_success' => 'Kommentar aktualisiert',
|
'comment_updated_success' => 'Kommentar aktualisiert',
|
||||||
'comment_archive_success' => 'Kommentar archiviert',
|
'comment_archive_success' => 'Kommentar wurde archiviert',
|
||||||
'comment_unarchive_success' => 'Kommentar nicht mehr archiviert',
|
'comment_unarchive_success' => 'Kommentar nicht mehr archiviert',
|
||||||
'comment_view' => 'Kommentar ansehen',
|
'comment_view' => 'Kommentar ansehen',
|
||||||
'comment_jump_to_thread' => 'Zum Thema springen',
|
'comment_jump_to_thread' => 'Zu diesem Thema springen',
|
||||||
'comment_delete_confirm' => 'Möchtst du diesen Kommentar wirklich löschen?',
|
'comment_delete_confirm' => 'Möchtst du diesen Kommentar wirklich löschen?',
|
||||||
'comment_in_reply_to' => 'Antwort auf :commentId',
|
'comment_in_reply_to' => 'Antwort auf :commentId',
|
||||||
'comment_reference' => 'Referenz',
|
'comment_reference' => 'Referenz',
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ return [
|
|||||||
'updated_page_subject' => 'Aktualisierte Seite: :pageName',
|
'updated_page_subject' => 'Aktualisierte Seite: :pageName',
|
||||||
'updated_page_intro' => 'Eine Seite wurde in :appName aktualisiert:',
|
'updated_page_intro' => 'Eine Seite wurde in :appName aktualisiert:',
|
||||||
'updated_page_debounce' => 'Um eine Flut von Benachrichtigungen zu vermeiden, wirst du für eine gewisse Zeit keine Benachrichtigungen für weitere Bearbeitungen dieser Seite durch denselben Bearbeiter erhalten.',
|
'updated_page_debounce' => 'Um eine Flut von Benachrichtigungen zu vermeiden, wirst du für eine gewisse Zeit keine Benachrichtigungen für weitere Bearbeitungen dieser Seite durch denselben Bearbeiter erhalten.',
|
||||||
'comment_mention_subject' => 'Sie wurden in einem Kommentar auf der Seite :pageName erwähnt',
|
'comment_mention_subject' => 'Du wurdest in einem Kommentar auf der Seite :pageName erwähnt',
|
||||||
'comment_mention_intro' => 'Sie wurden in einem Kommentar zu :appName: erwähnt',
|
'comment_mention_intro' => 'Du wurdest in einem Kommentar zu :appName erwähnt:',
|
||||||
|
|
||||||
'detail_page_name' => 'Seitenname:',
|
'detail_page_name' => 'Seitenname:',
|
||||||
'detail_page_path' => 'Seitenpfad:',
|
'detail_page_path' => 'Seitenpfad:',
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
|
|||||||
'reg_confirm_restrict_domain_placeholder' => 'Keine Einschränkung gesetzt',
|
'reg_confirm_restrict_domain_placeholder' => 'Keine Einschränkung gesetzt',
|
||||||
|
|
||||||
// Sorting Settings
|
// Sorting Settings
|
||||||
'sorting' => 'Listen & Sortieren',
|
'sorting' => 'Listen und Sortierung',
|
||||||
'sorting_book_default' => 'Standardregel für die Sortierung von Büchern',
|
'sorting_book_default' => 'Standardregel für die Sortierung von Büchern',
|
||||||
'sorting_book_default_desc' => 'Wähle die Standard-Sortierregel aus, die auf neue Bücher angewendet werden soll. Dies wirkt sich nicht auf bestehende Bücher aus und kann pro Buch überschrieben werden.',
|
'sorting_book_default_desc' => 'Wähle die Standard-Sortierregel aus, die auf neue Bücher angewendet werden soll. Dies wirkt sich nicht auf bestehende Bücher aus und kann pro Buch überschrieben werden.',
|
||||||
'sorting_rules' => 'Sortierregeln',
|
'sorting_rules' => 'Sortierregeln',
|
||||||
@@ -208,6 +208,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
|
|||||||
'role_all' => 'Alle',
|
'role_all' => 'Alle',
|
||||||
'role_own' => 'Eigene',
|
'role_own' => 'Eigene',
|
||||||
'role_controlled_by_asset' => 'Berechtigungen werden vom Uploadziel bestimmt',
|
'role_controlled_by_asset' => 'Berechtigungen werden vom Uploadziel bestimmt',
|
||||||
|
'role_controlled_by_page_delete' => 'Controlled by page delete permissions',
|
||||||
'role_save' => 'Rolle speichern',
|
'role_save' => 'Rolle speichern',
|
||||||
'role_users' => 'Dieser Rolle zugeordnete Benutzer',
|
'role_users' => 'Dieser Rolle zugeordnete Benutzer',
|
||||||
'role_users_none' => 'Bisher sind dieser Rolle keine Benutzer zugeordnet',
|
'role_users_none' => 'Bisher sind dieser Rolle keine Benutzer zugeordnet',
|
||||||
@@ -264,6 +265,9 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
|
|||||||
'users_mfa_desc' => 'Richte Multi-Faktor-Authentifizierung als zusätzliche Sicherheitsstufe für dein Benutzerkonto ein.',
|
'users_mfa_desc' => 'Richte Multi-Faktor-Authentifizierung als zusätzliche Sicherheitsstufe für dein Benutzerkonto ein.',
|
||||||
'users_mfa_x_methods' => ':count Methode konfiguriert|:count Methoden konfiguriert',
|
'users_mfa_x_methods' => ':count Methode konfiguriert|:count Methoden konfiguriert',
|
||||||
'users_mfa_configure' => 'Methoden konfigurieren',
|
'users_mfa_configure' => 'Methoden konfigurieren',
|
||||||
|
'users_mfa_reset' => 'Setze Multifaktor-Authentifizierung zurück',
|
||||||
|
'users_mfa_reset_desc' => 'Dies wird alle konfigurierten Multifaktor-Authentifizierungsmethoden für diesen Nutzer zurücksetzen. Falls Multifaktor-Authentifizierung für eine seiner Rollen erforderlich ist, werden sie aufgefordert, neue Methoden beim nächsten Login zu konfigurieren.',
|
||||||
|
'users_mfa_reset_confirm' => 'Sind Sie sicher, dass Sie diese Multi-Faktor-Authentifizierungsmethode für diesen Nutzer zurücksetzen möchten?',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'user_api_token_create' => 'Neuen API-Token erstellen',
|
'user_api_token_create' => 'Neuen API-Token erstellen',
|
||||||
@@ -364,6 +368,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung
|
|||||||
'sk' => 'Slowenisch',
|
'sk' => 'Slowenisch',
|
||||||
'sl' => 'Slowenisch',
|
'sl' => 'Slowenisch',
|
||||||
'sv' => 'Schwedisch',
|
'sv' => 'Schwedisch',
|
||||||
|
'th' => 'ภาษาไทย',
|
||||||
'tr' => 'Türkisch',
|
'tr' => 'Türkisch',
|
||||||
'uk' => 'Ukrainisch',
|
'uk' => 'Ukrainisch',
|
||||||
'uz' => 'O‘zbekcha',
|
'uz' => 'O‘zbekcha',
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ return [
|
|||||||
'uploaded' => 'Die Datei konnte nicht hochgeladen werden. Der Server akzeptiert möglicherweise keine Dateien dieser Größe.',
|
'uploaded' => 'Die Datei konnte nicht hochgeladen werden. Der Server akzeptiert möglicherweise keine Dateien dieser Größe.',
|
||||||
|
|
||||||
'zip_file' => ':attribute muss auf eine Datei innerhalb des ZIP verweisen.',
|
'zip_file' => ':attribute muss auf eine Datei innerhalb des ZIP verweisen.',
|
||||||
'zip_file_size' => 'The file :attribute must not exceed :size MB.',
|
'zip_file_size' => 'Die Datei :attribute darf :size MB nicht überschreiten.',
|
||||||
'zip_file_mime' => ':attribute muss eine Datei des Typs :validType referenzieren, gefunden :foundType.',
|
'zip_file_mime' => ':attribute muss eine Datei des Typs :validType referenzieren, gefunden :foundType.',
|
||||||
'zip_model_expected' => 'Datenobjekt erwartet, aber ":type" gefunden.',
|
'zip_model_expected' => 'Datenobjekt erwartet, aber ":type" gefunden.',
|
||||||
'zip_unique' => ':attribute muss für den Objekttyp innerhalb des ZIP eindeutig sein.',
|
'zip_unique' => ':attribute muss für den Objekttyp innerhalb des ZIP eindeutig sein.',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ return [
|
|||||||
'user_update_notification' => 'Ο Χρήστης ενημερώθηκε με επιτυχία',
|
'user_update_notification' => 'Ο Χρήστης ενημερώθηκε με επιτυχία',
|
||||||
'user_delete' => 'διαγραμμένος χρήστης',
|
'user_delete' => 'διαγραμμένος χρήστης',
|
||||||
'user_delete_notification' => 'Ο Χρήστης αφαιρέθηκε επιτυχώς',
|
'user_delete_notification' => 'Ο Χρήστης αφαιρέθηκε επιτυχώς',
|
||||||
|
'user_mfa_reset' => 'reset MFA for user',
|
||||||
|
'user_mfa_reset_notification' => 'Multi-factor authentication methods reset',
|
||||||
|
|
||||||
// API Tokens
|
// API Tokens
|
||||||
'api_token_create' => 'created API token',
|
'api_token_create' => 'created API token',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ return [
|
|||||||
|
|
||||||
'failed' => 'Αυτά τα διαπιστευτήρια δεν ταιριάζουν με τα αρχεία μας.',
|
'failed' => 'Αυτά τα διαπιστευτήρια δεν ταιριάζουν με τα αρχεία μας.',
|
||||||
'throttle' => 'Πάρα πολλές προσπάθειες σύνδεσης. Δοκιμάστε ξανά σε :δευτερόλεπτα.',
|
'throttle' => 'Πάρα πολλές προσπάθειες σύνδεσης. Δοκιμάστε ξανά σε :δευτερόλεπτα.',
|
||||||
|
'mfa_throttle' => 'Too many multi-factor verification attempts. Please try again in :seconds seconds.',
|
||||||
|
|
||||||
// Login & Register
|
// Login & Register
|
||||||
'sign_up' => 'Εγγραφείτε',
|
'sign_up' => 'Εγγραφείτε',
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ return [
|
|||||||
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
'books_sort_desc' => 'Move chapters and pages within a book to reorganise its contents. Other books can be added which allows easy moving of chapters and pages between books. Optionally an auto sort rule can be set to automatically sort this book\'s contents upon changes.',
|
||||||
'books_sort_auto_sort' => 'Auto Sort Option',
|
'books_sort_auto_sort' => 'Auto Sort Option',
|
||||||
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
'books_sort_auto_sort_active' => 'Auto Sort Active: :sortName',
|
||||||
|
'books_sort_auto_sort_creation_hint' => 'Auto sort option rules can be created in the "Lists & Sorting" settings area by a user with the relevant permissions.',
|
||||||
'books_sort_named' => 'Ταξινόμηση Βιβλίου :bookname',
|
'books_sort_named' => 'Ταξινόμηση Βιβλίου :bookname',
|
||||||
'books_sort_name' => 'Ταξινόμηση κατά όνομα',
|
'books_sort_name' => 'Ταξινόμηση κατά όνομα',
|
||||||
'books_sort_created' => 'Ταξινόμηση κατά ημερομηνία δημιουργίας',
|
'books_sort_created' => 'Ταξινόμηση κατά ημερομηνία δημιουργίας',
|
||||||
@@ -330,6 +331,9 @@ return [
|
|||||||
|
|
||||||
// Editor Sidebar
|
// Editor Sidebar
|
||||||
'toggle_sidebar' => 'Toggle Sidebar',
|
'toggle_sidebar' => 'Toggle Sidebar',
|
||||||
|
'page_contents' => 'Page Contents',
|
||||||
|
'page_contents_none' => 'No headings were found in the page content.',
|
||||||
|
'page_contents_info' => 'The contents menu is generated from any heading formats used in the page.',
|
||||||
'page_tags' => 'Ετικέτες Σελίδας',
|
'page_tags' => 'Ετικέτες Σελίδας',
|
||||||
'chapter_tags' => 'Ετικέτες Κεφαλαίου',
|
'chapter_tags' => 'Ετικέτες Κεφαλαίου',
|
||||||
'book_tags' => 'Ετικέτες Βιβλίου',
|
'book_tags' => 'Ετικέτες Βιβλίου',
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user