mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 08:58:35 +00:00
Merge pull request #2212 from kodumbeats/feat-db-refactor-ui-fixes
feat(db-refactor): merge feat-database-indexing changes
This commit is contained in:
commit
6f881e8c64
1604 changed files with 34891 additions and 2644 deletions
44
.github/ISSUE_TEMPLATE/bug.md
vendored
44
.github/ISSUE_TEMPLATE/bug.md
vendored
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
name: 🐛 Bug Report
|
||||
about: Submit a bug report to help us improve
|
||||
labels: "bug"
|
||||
---
|
||||
|
||||
## 🐛 Bug Report
|
||||
|
||||
(A clear and concise description of what the bug is)
|
||||
|
||||
## Have you spent some time to check if this issue has been raised before?
|
||||
|
||||
(Have you googled for a similar issue or checked our older issues for a similar bug)
|
||||
|
||||
## To Reproduce
|
||||
|
||||
(Write your steps here:)
|
||||
|
||||
## Expected behavior
|
||||
|
||||
<!--
|
||||
How did you expect your project to behave?
|
||||
It’s fine if you’re not sure your understanding is correct.
|
||||
Write down what you thought would happen.
|
||||
-->
|
||||
|
||||
(Write what you thought would happen.)
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
<!--
|
||||
Did something go wrong?
|
||||
Is something broken, or not behaving as you expected?
|
||||
Describe this section in detail, and attach screenshots if possible.
|
||||
Don't only say "it doesn't work"!
|
||||
-->
|
||||
|
||||
(Write what happened. Add screenshots, if applicable.)
|
||||
|
||||
## Your Environment
|
||||
|
||||
<!-- Include as many relevant details about the environment you experienced the bug in -->
|
||||
|
||||
(Write Environment, Operating system and version etc.)
|
||||
82
.github/ISSUE_TEMPLATE/bug.yaml
vendored
Normal file
82
.github/ISSUE_TEMPLATE/bug.yaml
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
name: "🐛 Bug Report"
|
||||
description: "Submit a bug report to help us improve"
|
||||
title: "🐛 Bug Report: "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out our bug report form 🙏
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "👟 Reproduction steps"
|
||||
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||
placeholder: "When I ..."
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "👍 Expected behavior"
|
||||
description: "What did you think would happen?"
|
||||
placeholder: "It should ..."
|
||||
- type: textarea
|
||||
id: actual-behavior
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "👎 Actual Behavior"
|
||||
description: "What did actually happen? Add screenshots, if applicable."
|
||||
placeholder: "It actually ..."
|
||||
- type: dropdown
|
||||
id: appwrite-version
|
||||
attributes:
|
||||
label: "🎲 Appwrite version"
|
||||
description: "What version of Appwrite are you running?"
|
||||
options:
|
||||
- Version 0.10.x
|
||||
- Version 0.9.x
|
||||
- Version 0.8.x
|
||||
- Version 0.7.x
|
||||
- Version 0.6.x
|
||||
- Different version (specify in environment)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: "💻 Operating system"
|
||||
description: "What OS is your server / device running on?"
|
||||
options:
|
||||
- Linux
|
||||
- MacOS
|
||||
- Windows
|
||||
- Something else
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: "🧱 Your Environment"
|
||||
description: "Is your environment customized in any way?"
|
||||
placeholder: "I use Cloudflare for ..."
|
||||
- type: checkboxes
|
||||
id: no-duplicate-issues
|
||||
attributes:
|
||||
label: "👀 Have you spent some time to check if this issue has been raised before?"
|
||||
description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
|
||||
options:
|
||||
- label: "I checked and didn't find similar issue"
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: read-code-of-conduct
|
||||
attributes:
|
||||
label: "🏢 Have you read the Code of Conduct?"
|
||||
options:
|
||||
- label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
|
||||
required: true
|
||||
17
.github/ISSUE_TEMPLATE/documentation.md
vendored
17
.github/ISSUE_TEMPLATE/documentation.md
vendored
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
name: 📚 Documentation
|
||||
about: Report an issue related to documentation
|
||||
labels: "documentation"
|
||||
---
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
(A clear and concise description of what the issue is.)
|
||||
|
||||
## Have you spent some time to check if this issue has been raised before?
|
||||
|
||||
(Have you googled for a similar issue or checked our older issues for a similar bug)
|
||||
|
||||
### Have you read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/master/CODE_OF_CONDUCT.md)?
|
||||
|
||||
(Write your answer here.)
|
||||
32
.github/ISSUE_TEMPLATE/documentation.yaml
vendored
Normal file
32
.github/ISSUE_TEMPLATE/documentation.yaml
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
name: "📚 Documentation"
|
||||
description: "Report an issue related to documentation"
|
||||
title: "📚 Documentation: "
|
||||
labels: [documentation]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make our documentation better 🙏
|
||||
- type: textarea
|
||||
id: issue-description
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "💭 Description"
|
||||
description: "A clear and concise description of what the issue is."
|
||||
placeholder: "Documentation should not ..."
|
||||
- type: checkboxes
|
||||
id: no-duplicate-issues
|
||||
attributes:
|
||||
label: "👀 Have you spent some time to check if this issue has been raised before?"
|
||||
description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
|
||||
options:
|
||||
- label: "I checked and didn't find similar issue"
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: read-code-of-conduct
|
||||
attributes:
|
||||
label: "🏢 Have you read the Code of Conduct?"
|
||||
options:
|
||||
- label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
|
||||
required: true
|
||||
21
.github/ISSUE_TEMPLATE/feature.md
vendored
21
.github/ISSUE_TEMPLATE/feature.md
vendored
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
name: 🚀 Feature
|
||||
about: Submit a proposal for a new feature
|
||||
labels: "feature"
|
||||
---
|
||||
|
||||
## 🚀 Feature
|
||||
|
||||
(A clear and concise description of what the feature is.)
|
||||
|
||||
## Have you spent some time to check if this issue has been raised before?
|
||||
|
||||
(Have you googled for a similar issue or checked our older issues for a similar bug)
|
||||
|
||||
### Have you read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/master/CODE_OF_CONDUCT.md)?
|
||||
|
||||
(Write your answer here.)
|
||||
|
||||
## Pitch
|
||||
|
||||
(Please explain why this feature should be implemented and how it would be used. Add examples, if applicable.)
|
||||
40
.github/ISSUE_TEMPLATE/feature.yaml
vendored
Normal file
40
.github/ISSUE_TEMPLATE/feature.yaml
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
name: 🚀 Feature
|
||||
description: "Submit a proposal for a new feature"
|
||||
title: "🚀 Feature: "
|
||||
labels: [feature]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out our feature request form 🙏
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "🔖 Feature description"
|
||||
description: "A clear and concise description of what the feature is."
|
||||
placeholder: "You should add ..."
|
||||
- type: textarea
|
||||
id: pitch
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "🎤 Pitch"
|
||||
description: "Please explain why this feature should be implemented and how it would be used. Add examples, if applicable."
|
||||
placeholder: "In my use-case, ..."
|
||||
- type: checkboxes
|
||||
id: no-duplicate-issues
|
||||
attributes:
|
||||
label: "👀 Have you spent some time to check if this issue has been raised before?"
|
||||
description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
|
||||
options:
|
||||
- label: "I checked and didn't find similar issue"
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: read-code-of-conduct
|
||||
attributes:
|
||||
label: "🏢 Have you read the Code of Conduct?"
|
||||
options:
|
||||
- label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
|
||||
required: true
|
||||
45
.github/workflows/tests.yml
vendored
Normal file
45
.github/workflows/tests.yml
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
name: "Tests"
|
||||
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
tests:
|
||||
name: Unit & E2E
|
||||
runs-on: self-hosted
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- name: Build Appwrite
|
||||
# Upstream bug causes buildkit pulls to fail so prefetch base images
|
||||
# https://github.com/moby/moby/issues/41864
|
||||
run: |
|
||||
echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
|
||||
docker pull composer:2.0
|
||||
docker pull php:8.0-cli-alpine
|
||||
docker compose build --progress=plain
|
||||
docker compose up -d
|
||||
sleep 10
|
||||
- name: Doctor
|
||||
run: docker compose exec -T appwrite doctor
|
||||
|
||||
- name: Environment Variables
|
||||
run: docker compose exec -T appwrite vars
|
||||
|
||||
- name: Run Tests
|
||||
run: docker compose exec -T appwrite test --debug
|
||||
|
||||
- name: Teardown
|
||||
if: always()
|
||||
run: |
|
||||
docker compose down -v
|
||||
docker ps -aq | xargs docker rm --force
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,6 +2,7 @@
|
|||
/vendor/
|
||||
/node_modules/
|
||||
/tests/resources/storage/
|
||||
/app/sdks/*
|
||||
/.idea/
|
||||
.DS_Store
|
||||
.php_cs.cache
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ arch:
|
|||
|
||||
os: linux
|
||||
|
||||
# Small change
|
||||
vm:
|
||||
size: large
|
||||
|
||||
|
||||
language: shell
|
||||
|
||||
notifications:
|
||||
|
|
@ -17,24 +16,44 @@ notifications:
|
|||
- team@appwrite.io
|
||||
|
||||
before_install:
|
||||
# Install latest Docker
|
||||
- curl -fsSL https://get.docker.com | sh
|
||||
# Enable Buildkit in Docker config
|
||||
- echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json
|
||||
- mkdir -p $HOME/.docker
|
||||
- echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
|
||||
- sudo service docker start
|
||||
# Login to increase Docker Hub ratelimit
|
||||
- >
|
||||
if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then
|
||||
echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin
|
||||
fi
|
||||
- docker --version
|
||||
- docker buildx create --use
|
||||
- chmod -R u+x ./.travis-ci
|
||||
- export COMPOSE_INTERACTIVE_NO_CLI=1
|
||||
# Install latest Compose
|
||||
- sudo rm /usr/local/bin/docker-compose
|
||||
- curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||
- chmod +x docker-compose
|
||||
- sudo mv docker-compose /usr/local/bin
|
||||
- docker-compose --version
|
||||
# Enable Buildkit
|
||||
- docker buildx create --name travis_builder --use
|
||||
- export COMPOSE_INTERACTIVE_NO_CLI
|
||||
- export DOCKER_BUILDKIT=1
|
||||
- export COMPOSE_DOCKER_CLI_BUILD=1
|
||||
- export BUILDKIT_PROGRESS=plain
|
||||
# Only pass a single runtime for CI stability
|
||||
- echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
|
||||
# Ensure Travis scripts are executable
|
||||
- chmod -R u+x ./.travis-ci
|
||||
|
||||
install:
|
||||
- docker-compose up -d --build
|
||||
- docker-compose pull
|
||||
# Upstream bug causes buildkit pulls to fail so prefetch base images
|
||||
# https://github.com/moby/moby/issues/41864
|
||||
- docker pull composer:2.0
|
||||
- docker pull php:8.0-cli-alpine
|
||||
- docker-compose build
|
||||
- docker-compose up -d
|
||||
- sleep 10
|
||||
|
||||
script:
|
||||
|
|
@ -53,6 +72,10 @@ script:
|
|||
- docker-compose exec appwrite test --debug
|
||||
- docker-compose logs appwrite
|
||||
|
||||
after_script:
|
||||
# travis re-uses their build nodes so clean them up
|
||||
- docker buildx rm travis_builder
|
||||
|
||||
after_failure:
|
||||
- docker-compose logs appwrite
|
||||
|
||||
45
CHANGES.md
45
CHANGES.md
|
|
@ -1,10 +1,52 @@
|
|||
# Version 0.10.0
|
||||
# Version 1.0.0
|
||||
|
||||
## Features
|
||||
|
||||
- Grouped auth related attributes in project collection. Introduced new attribute `auths` and removed all attributes related to auth methods and `usersAuthLimit` as well, all these are grouped under `auths` attribute
|
||||
- Grouped oAuth related attributes in project collection. Introduced new attribute `providers` and removed all attributes related to OAuth2 providers. All OAuth2 attributes are grouped under `providers`
|
||||
- Project model changed, `userAuth<AuthMethod>` => `auth<AuthMethod>` example `userAuthEmailPassword` => `authEmailPassword`, also `userOauth2<Provider>...` => `provider<Provider>...` example `userOauth2GithubAppid` => `providerGithubAppid`
|
||||
# Version 0.10.4
|
||||
|
||||
## Bugs
|
||||
- Fixed another memory leak in realtime service (#1627)
|
||||
|
||||
# Version 0.10.3
|
||||
|
||||
## Bugs
|
||||
- Fixed memory leak in realtime service (#1606)
|
||||
- Fixed function execution output now being UTF-8 encoded before saved (#1607)
|
||||
|
||||
# Version 0.10.2
|
||||
|
||||
## Bugs
|
||||
- Fixed SSL certificates status not being updated (#1592)
|
||||
- Fixed failing team invites on console (#1580)
|
||||
|
||||
# Version 0.10.1
|
||||
|
||||
## Bugs
|
||||
- Improved error messages on Migration regarding invalid document structures (#1576)
|
||||
- Fixed Console SDK endpoint to work with multiple proxies (#1575)
|
||||
- Fixed last function environments variables being corrupt (#1577)
|
||||
- Fixed `_APP_FUNCTIONS_CPUS` variable for cloud functions (#1568)
|
||||
|
||||
# Version 0.10.0
|
||||
|
||||
## Features
|
||||
- Added Realtime (#948)
|
||||
- Added Realtime statistics to the console (#948)
|
||||
- Added Magic URL login (#1552)
|
||||
- Refactored E-Mail template (#1422)
|
||||
- Improved locale management (#1440)
|
||||
- Added `$permissions` to execution response (#948)
|
||||
- Switch from using Docker CLI to Docker API by intergrating [utopia-php/orchestration](https://github.com/utopia-php/orchestration) (#1420)
|
||||
- Added DOCKERHUB_PULL_USERNAME, DOCKERHUB_PULL_PASSWORD and DOCKERHUB_PULL_EMAIL env variables for pulling from private DockerHub repos (#1420)
|
||||
- Added `updateName`, `updateEmail` and `updatePassword` to Users service and console (#1547)
|
||||
|
||||
## Bugs
|
||||
- Fixed MariaDB timeout after 24 hours (#1510)
|
||||
- Fixed upgrading installation with customized `docker-compose.yml` file (#1513)
|
||||
- Fixed usage stats on the dashboard displaying invalid total users count (#1514)
|
||||
|
||||
# Version 0.9.4
|
||||
|
||||
|
|
@ -12,6 +54,7 @@
|
|||
|
||||
- Fixed security vulnerability that exposes project ID's from other admin users (#1453)
|
||||
|
||||
|
||||
# Version 0.9.3
|
||||
|
||||
## Bugs
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ We love to create issues that are good for beginners and label them as `good fir
|
|||
- [PHP FIG](https://www.php-fig.org/) - [PSR-1](https://www.php-fig.org/psr/psr-1/) and [PSR-4](https://www.php-fig.org/psr/psr-4/)
|
||||
- [PHP Swoole](https://www.swoole.co.uk/)
|
||||
|
||||
Learn more at our [Technology Stack](## Technology Stack) section.
|
||||
Learn more at our [Technology Stack](#technology-stack) section.
|
||||
|
||||
##### Network and Protocols
|
||||
- [OSI Model](https://en.wikipedia.org/wiki/OSI_model)
|
||||
|
|
@ -167,6 +167,8 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
|
|||
│ ├── Migration
|
||||
│ ├── Network
|
||||
│ ├── OpenSSL
|
||||
│ ├── Realtime
|
||||
│ ├── Resque
|
||||
│ ├── Specification
|
||||
│ ├── Task
|
||||
│ ├── Template
|
||||
|
|
|
|||
102
Dockerfile
102
Dockerfile
|
|
@ -1,4 +1,4 @@
|
|||
FROM composer:2.0 as step0
|
||||
FROM composer:2.0 as composer
|
||||
|
||||
ARG TESTING=false
|
||||
ENV TESTING=$TESTING
|
||||
|
|
@ -12,7 +12,7 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \
|
|||
--no-plugins --no-scripts --prefer-dist \
|
||||
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
|
||||
|
||||
FROM php:8.0-cli-alpine as step1
|
||||
FROM php:8.0-cli-alpine as compile
|
||||
|
||||
ARG DEBUG=false
|
||||
ENV DEBUG=$DEBUG
|
||||
|
|
@ -34,6 +34,7 @@ RUN \
|
|||
git \
|
||||
zlib-dev \
|
||||
brotli-dev \
|
||||
openssl-dev \
|
||||
yaml-dev \
|
||||
imagemagick \
|
||||
imagemagick-dev \
|
||||
|
|
@ -41,51 +42,24 @@ RUN \
|
|||
|
||||
RUN docker-php-ext-install sockets
|
||||
|
||||
FROM compile AS redis
|
||||
RUN \
|
||||
# Redis Extension
|
||||
git clone --depth 1 --branch $PHP_REDIS_VERSION https://github.com/phpredis/phpredis.git && \
|
||||
cd phpredis && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
# Mongodb Extension
|
||||
git clone --depth 1 --branch $PHP_MONGODB_VERSION https://github.com/mongodb/mongo-php-driver.git && \
|
||||
cd mongo-php-driver && \
|
||||
git submodule update --init && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## Swoole Extension
|
||||
make && make install
|
||||
|
||||
## Swoole Extension
|
||||
FROM compile AS swoole
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_SWOOLE_VERSION https://github.com/swoole/swoole-src.git && \
|
||||
cd swoole-src && \
|
||||
phpize && \
|
||||
./configure --enable-http2 && \
|
||||
./configure --enable-sockets --enable-http2 --enable-openssl && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## Imagick Extension
|
||||
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/imagick/imagick && \
|
||||
cd imagick && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## YAML Extension
|
||||
git clone --depth 1 --branch $PHP_YAML_VERSION https://github.com/php/pecl-file_formats-yaml && \
|
||||
cd pecl-file_formats-yaml && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## Maxminddb extension
|
||||
git clone --depth 1 --branch $PHP_MAXMINDDB_VERSION https://github.com/maxmind/MaxMind-DB-Reader-php.git && \
|
||||
cd MaxMind-DB-Reader-php && \
|
||||
cd ext && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd ../..
|
||||
cd ..
|
||||
|
||||
## Swoole Debugger setup
|
||||
RUN if [ "$DEBUG" == "true" ]; then \
|
||||
|
|
@ -99,6 +73,44 @@ RUN if [ "$DEBUG" == "true" ]; then \
|
|||
cd ..;\
|
||||
fi
|
||||
|
||||
## Imagick Extension
|
||||
FROM compile AS imagick
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/imagick/imagick && \
|
||||
cd imagick && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
## YAML Extension
|
||||
FROM compile AS yaml
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_YAML_VERSION https://github.com/php/pecl-file_formats-yaml && \
|
||||
cd pecl-file_formats-yaml && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
## Maxminddb extension
|
||||
FROM compile AS maxmind
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_MAXMINDDB_VERSION https://github.com/maxmind/MaxMind-DB-Reader-php.git && \
|
||||
cd MaxMind-DB-Reader-php && \
|
||||
cd ext && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
# Mongodb Extension
|
||||
FROM compile as mongodb
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_MONGODB_VERSION https://github.com/mongodb/mongo-php-driver.git && \
|
||||
cd mongo-php-driver && \
|
||||
git submodule update --init && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
FROM php:8.0-cli-alpine as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
|
|
@ -193,13 +205,13 @@ RUN \
|
|||
|
||||
WORKDIR /usr/src/code
|
||||
|
||||
COPY --from=step0 /usr/local/src/vendor /usr/src/code/vendor
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yasd.so* /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/imagick.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=composer /usr/local/src/vendor /usr/src/code/vendor
|
||||
COPY --from=swoole /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yasd.so* /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=redis /usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=imagick /usr/local/lib/php/extensions/no-debug-non-zts-20200930/imagick.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=yaml /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=maxmind /usr/local/lib/php/extensions/no-debug-non-zts-20200930/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=mongodb /usr/local/lib/php/extensions/no-debug-non-zts-20200930/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
|
||||
# Add Source Code
|
||||
COPY ./app /usr/src/code/app
|
||||
|
|
@ -228,6 +240,7 @@ RUN chmod +x /usr/local/bin/doctor && \
|
|||
chmod +x /usr/local/bin/usage && \
|
||||
chmod +x /usr/local/bin/install && \
|
||||
chmod +x /usr/local/bin/migrate && \
|
||||
chmod +x /usr/local/bin/realtime && \
|
||||
chmod +x /usr/local/bin/schedule && \
|
||||
chmod +x /usr/local/bin/sdks && \
|
||||
chmod +x /usr/local/bin/ssl && \
|
||||
|
|
@ -256,6 +269,7 @@ RUN if [ "$DEBUG" == "true" ]; then echo "opcache.enable=0" >> /usr/local/etc/ph
|
|||
RUN echo "opcache.preload_user=www-data" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "opcache.preload=/usr/src/code/app/preload.php" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "default_socket_timeout=-1" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "opcache.jit_buffer_size=100M" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "opcache.jit=1235" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -8,7 +8,7 @@
|
|||
<br />
|
||||
</p>
|
||||
|
||||
<!--[](CONTRIBUTING.md)-->
|
||||
[](https://hacktoberfest.appwrite.io)
|
||||
[](https://appwrite.io/discord)
|
||||
[](https://hub.docker.com/r/appwrite/appwrite)
|
||||
[](https://travis-ci.com/appwrite/appwrite)
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
[](docs/tutorials/add-translations.md)
|
||||
<!-- [](https://store.appwrite.io) -->
|
||||
|
||||
[**Appwrite 0.9 has been released! Learn what's new!**](https://dev.to/appwrite/announcing-appwrite-0-9-the-open-source-firebase-alternative-53ho)
|
||||
[**Appwrite 0.10 has been released! Learn what's new!**](https://dev.to/appwrite/it-s-here-announcing-appwrite-0-10-and-the-new-appwrite-realtime-api-lbm)
|
||||
|
||||
Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker<nobr> microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.
|
||||
|
||||
|
|
@ -39,6 +39,7 @@ Table of Contents:
|
|||
- [SDKs](#sdks)
|
||||
- [Client](#client)
|
||||
- [Server](#server)
|
||||
- [Community](#community)
|
||||
- [Contributing](#contributing)
|
||||
- [Security](#security)
|
||||
- [Follow Us](#follow-us)
|
||||
|
|
@ -57,7 +58,7 @@ docker run -it --rm \
|
|||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
|
||||
--entrypoint="install" \
|
||||
appwrite/appwrite:0.9.4
|
||||
appwrite/appwrite:0.10.4
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
|
@ -69,7 +70,7 @@ docker run -it --rm ^
|
|||
--volume //var/run/docker.sock:/var/run/docker.sock ^
|
||||
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
|
||||
--entrypoint="install" ^
|
||||
appwrite/appwrite:0.9.4
|
||||
appwrite/appwrite:0.10.4
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
|
@ -79,7 +80,7 @@ docker run -it --rm ,
|
|||
--volume /var/run/docker.sock:/var/run/docker.sock ,
|
||||
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
|
||||
--entrypoint="install" ,
|
||||
appwrite/appwrite:0.9.4
|
||||
appwrite/appwrite:0.10.4
|
||||
```
|
||||
|
||||
Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-linux native hosts, the server might take a few minutes to start after installation completes.
|
||||
|
|
@ -97,9 +98,9 @@ Getting started with Appwrite is as easy as creating a new project, choosing you
|
|||
|
||||
* [Getting Started for Web](https://appwrite.io/docs/getting-started-for-web)
|
||||
* [Getting Started for Flutter](https://appwrite.io/docs/getting-started-for-flutter)
|
||||
* [Getting Started for Android](https://appwrite.io/docs/getting-started-for-android)
|
||||
* [Getting Started for Server](https://appwrite.io/docs/getting-started-for-server)
|
||||
* [Getting Started for CLI](https://appwrite.io/docs/command-line)
|
||||
* Getting Started for Android (Coming soon...)
|
||||
* Getting Started for iOS (Coming soon...)
|
||||
|
||||
### Services
|
||||
|
|
@ -134,6 +135,9 @@ Below is a list of currently supported platforms and languages. If you wish to h
|
|||
* ✅ [Kotlin](https://github.com/appwrite/sdk-for-kotlin) - **Beta** (Maintained by the Appwrite Team)
|
||||
* ✅ [.NET](https://github.com/appwrite/sdk-for-dotnet) - **Experimental** (Maintained by the Appwrite Team)
|
||||
|
||||
#### Community
|
||||
* ✅ [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (Maintained by [Michael Gangolf](https://github.com/m1ga/))
|
||||
|
||||
Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)!
|
||||
|
||||
## Contributing
|
||||
|
|
@ -148,7 +152,7 @@ For security issues, kindly email us at [security@appwrite.io](mailto:security@a
|
|||
|
||||
## Follow Us
|
||||
|
||||
Join our growing community around the world! See our official [Blog](https://medium.com/appwrite-io). Follow us on [Twitter](https://twitter.com/appwrite_io), [Facebook Page](https://www.facebook.com/appwrite.io), [Facebook Group](https://www.facebook.com/groups/appwrite.developers/) or join our live [Discord server](https://discord.gg/GSeTUeA) for more help, ideas, and discussions.
|
||||
Join our growing community around the world! See our official [Blog](https://medium.com/appwrite-io). Follow us on [Twitter](https://twitter.com/appwrite_io), [Facebook Page](https://www.facebook.com/appwrite.io), [Facebook Group](https://www.facebook.com/groups/appwrite.developers/) , [Dev Community](https://dev.to/appwrite) or join our live [Discord server](https://discord.gg/GSeTUeA) for more help, ideas, and discussions.
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,13 @@ return [
|
|||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateSession',
|
||||
'enabled' => true,
|
||||
],
|
||||
'magic-url' => [
|
||||
'name' => 'Magic URL',
|
||||
'key' => 'usersAuthMagicURL',
|
||||
'icon' => '/images/users/magic-url.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateMagicURLSession',
|
||||
'enabled' => true,
|
||||
],
|
||||
'anonymous' => [
|
||||
'name' => 'Anonymous',
|
||||
'key' => 'anonymous',
|
||||
|
|
@ -35,7 +42,6 @@ return [
|
|||
'name' => 'Phone',
|
||||
'key' => 'phone',
|
||||
'icon' => '/images/users/phone.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreatePhoneSession',
|
||||
'docs' => '',
|
||||
'enabled' => false,
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1542,6 +1542,39 @@ $collections = [
|
|||
],
|
||||
],
|
||||
],
|
||||
Database::SYSTEM_COLLECTION_CONNECTIONS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'name' => 'Realtime Connections',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'label' => 'Container',
|
||||
'key' => 'container',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'label' => 'Timestamp',
|
||||
'key' => 'timestamp',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CONNECTIONS,
|
||||
'label' => 'Value',
|
||||
'key' => 'value',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
Database::SYSTEM_COLLECTION_RESERVED => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_RESERVED,
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ $collections = [
|
|||
'required' => false,
|
||||
'default' => new stdClass,
|
||||
'array' => false,
|
||||
'filters' => ['json', 'range'],
|
||||
'filters' => ['json', 'range', 'enum'],
|
||||
],
|
||||
[
|
||||
'$id' => 'filters',
|
||||
|
|
@ -510,8 +510,8 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => true,
|
||||
'filters' => ['json'],
|
||||
'array' => false,
|
||||
'filters' => ['subQueryPlatforms'],
|
||||
],
|
||||
[
|
||||
'$id' => 'webhooks',
|
||||
|
|
@ -521,8 +521,8 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => true,
|
||||
'filters' => ['json'],
|
||||
'array' => false,
|
||||
'filters' => ['subQueryWebhooks'],
|
||||
],
|
||||
[
|
||||
'$id' => 'keys',
|
||||
|
|
@ -532,8 +532,8 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => true,
|
||||
'filters' => ['json'],
|
||||
'array' => false,
|
||||
'filters' => ['subQueryKeys'],
|
||||
],
|
||||
[
|
||||
'$id' => 'domains',
|
||||
|
|
@ -543,16 +543,381 @@ $collections = [
|
|||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => true,
|
||||
'filters' => ['json'],
|
||||
'array' => false,
|
||||
'filters' => ['subQueryDomains'],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_fulltext_name',
|
||||
'$id' => '_key_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [1024],
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [2048],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'platforms' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'platforms',
|
||||
'name' => 'platforms',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'type',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'name',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 256,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'key',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'store',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 256,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'hostname',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 256,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'dateCreated',
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'dateUpdated',
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'domains' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'domains',
|
||||
'name' => 'domains',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'updated',
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'domain',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'tld',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'registerable',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'verification',
|
||||
'type' => Database::VAR_BOOLEAN,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'certificateId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'keys' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'keys',
|
||||
'name' => 'keys',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'name',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'scopes',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => true,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'secret',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 256, // var_dump of \bin2hex(\random_bytes(128)) => string(256)
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'webhooks' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'webhooks',
|
||||
'name' => 'webhooks',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'projectId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'name',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'url',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'httpUser',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'httpPass',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'security',
|
||||
'type' => Database::VAR_BOOLEAN,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'events',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => true,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_project',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['projectId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
|
|
@ -578,7 +943,7 @@ $collections = [
|
|||
'$id' => 'email',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 1024,
|
||||
'size' => 320,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
|
|
@ -695,15 +1060,51 @@ $collections = [
|
|||
'array' => true,
|
||||
'filters' => ['json'],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'deleted',
|
||||
'type' => Database::VAR_BOOLEAN,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_email',
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['email'],
|
||||
'lengths' => [1024],
|
||||
'lengths' => [320],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [2048],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_deleted_email',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['deleted', 'email'],
|
||||
'lengths' => [0, 320],
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
|
@ -993,13 +1394,24 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_fulltext_name',
|
||||
'$id' => '_key_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [1024],
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [2048],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
|
|
@ -1273,6 +1685,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
|
|
@ -1283,10 +1706,10 @@ $collections = [
|
|||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_fulltext_name',
|
||||
'$id' => '_key_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [1024],
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [2048],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
|
|
@ -1441,13 +1864,24 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_fulltext_name',
|
||||
'$id' => '_key_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [1024],
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [2048],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
|
|
@ -1514,6 +1948,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
|
|
@ -1523,6 +1968,13 @@ $collections = [
|
|||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [2048],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
|
@ -1631,6 +2083,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'search',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
|
|
@ -1640,6 +2103,13 @@ $collections = [
|
|||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_fulltext_search',
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [16384],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
|
@ -1812,7 +2282,56 @@ $collections = [
|
|||
'orders' => [Database::ORDER_DESC],
|
||||
],
|
||||
],
|
||||
]
|
||||
],
|
||||
'realtime' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'realtime',
|
||||
'name' => 'Realtime Connections',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => 'container',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'timestamp',
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'value',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [], //TODO: use json filter
|
||||
]
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_timestamp',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['timestamp'],
|
||||
'lengths' => [],
|
||||
'orders' => [Database::ORDER_DESC],
|
||||
],
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
return $collections;
|
||||
return $collections;
|
||||
|
|
@ -197,6 +197,21 @@ return [
|
|||
'model' => Response::MODEL_ANY,
|
||||
'note' => 'version >= 0.7',
|
||||
],
|
||||
'users.update.email' => [
|
||||
'description' => 'This event triggers when the user email address is updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => 'version >= 0.10',
|
||||
],
|
||||
'users.update.name' => [
|
||||
'description' => 'This event triggers when the user name is updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => 'version >= 0.10',
|
||||
],
|
||||
'users.update.password' => [
|
||||
'description' => 'This event triggers when the user password is updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => 'version >= 0.10',
|
||||
],
|
||||
'users.update.status' => [
|
||||
'description' => 'This event triggers when a user status is updated from the users API.',
|
||||
'model' => Response::MODEL_USER,
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ return [
|
|||
'ar', // Arabic
|
||||
'be', // Belarusian
|
||||
'bg', // Bulgarian
|
||||
'bh', // Bihari
|
||||
'bn', // Bengali
|
||||
'bs', //Bosnian
|
||||
'bs', // Bosnian
|
||||
'ca', // Catalan
|
||||
'cs', // Czech
|
||||
'da', // Danish
|
||||
'de', // German
|
||||
'en', // English
|
||||
'es', // Spanish
|
||||
|
|
@ -17,9 +19,10 @@ return [
|
|||
'fo', // Faroese
|
||||
'fr', // French
|
||||
'el', // Greek
|
||||
'gu', //Gujrati
|
||||
'gu', // Gujrati
|
||||
'he', // Hebrew
|
||||
'hi', // Hindi
|
||||
'hi', // Hindi,
|
||||
'hr', // Croatian
|
||||
'hu', // Hungarian
|
||||
'hy', // Armenian
|
||||
'id', // Indonesian
|
||||
|
|
@ -30,6 +33,7 @@ return [
|
|||
'kn', // Kannada
|
||||
'km', // Khmer
|
||||
'ko', // Korean
|
||||
'lb', // Luxembourgish
|
||||
'lt', // Lithuanian
|
||||
'ml', // Malayalam
|
||||
'mr', // Marathi
|
||||
|
|
@ -42,10 +46,12 @@ return [
|
|||
'pl', // Polish
|
||||
'pt-br', // Portuguese - Brazil
|
||||
'pt-pt', // Portuguese - Portugal
|
||||
'pa', //Punjabi
|
||||
'pa', // Punjabi
|
||||
'ro', // Romanian
|
||||
'ru', // Russian
|
||||
'sa', //Sanskrit
|
||||
'si', // Sinhala
|
||||
'sk', // Slovakia
|
||||
'sl', // Slovenian
|
||||
'sq', // Albanian
|
||||
'sv', // Swedish
|
||||
|
|
@ -53,7 +59,7 @@ return [
|
|||
'th', // Thai
|
||||
'tr', // Turkish
|
||||
'uk', // Ukrainian
|
||||
'ur', //Urdu
|
||||
'ur', // Urdu
|
||||
'vi', // Vietnamese
|
||||
'zh-cn', // Chinese - China
|
||||
'zh-tw', // Chinese - Taiwan
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ return [
|
|||
[
|
||||
"code" => "hi",
|
||||
"name" => "Hindi",
|
||||
"nativeName" => "हिन्दी"
|
||||
"nativeName" => "हिन्दी / हिंदी "
|
||||
],
|
||||
[
|
||||
"code" => "ho",
|
||||
|
|
@ -706,7 +706,7 @@ return [
|
|||
[
|
||||
"code" => "sd",
|
||||
"name" => "Sindhi",
|
||||
"nativeName" => "सिनधि"
|
||||
"nativeName" => "सिन्धी / सिंधी "
|
||||
],
|
||||
[
|
||||
"code" => "se",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ar",
|
||||
"settings.direction": "rtl",
|
||||
"emails.sender": "فريق %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "تأكيد الحساب",
|
||||
"emails.verification.hello": "مرحبا {{name}}",
|
||||
"emails.verification.body": "برجاء اتباع الرابط التالي لتأكيد بريدك الإلكتروني",
|
||||
"emails.verification.footer": "لو لم تطلب تأكيد هذا البريد الإلكتروني، يمكنك تجاهل هذه الرسالة",
|
||||
"emails.verification.thanks": "شكرا",
|
||||
"emails.verification.signature": "فريق {{project}}",
|
||||
"emails.magicSession.subject": "تسجيل الدخول",
|
||||
"emails.magicSession.hello": "أهلا،",
|
||||
"emails.magicSession.body": "اتبع هذا الرابط لتسجيل الدخول",
|
||||
"emails.magicSession.footer": "لو لم تطلب تسجيل الدخول بهذا البريد الاكتروني ، يمكنك تجاهل هذه الرسالة",
|
||||
"emails.magicSession.thanks": "شكرا",
|
||||
"emails.magicSession.signature": "فريق {{project}}",
|
||||
"emails.recovery.subject": "تغيير كلمة السر",
|
||||
"emails.recovery.hello": "أهلا {{name}}",
|
||||
"emails.recovery.body": "برجاء اتباع الراط التالي لتغيير كلمة السر الخاصة بـ{{project}}",
|
||||
"emails.recovery.footer": "لولم تطلب تغيير كلمة السر، يمكنك تجاهل هذه الرسالة",
|
||||
"emails.recovery.thanks": "شكرا",
|
||||
"emails.recovery.signature": "فريق {{project}}",
|
||||
"emails.invitation.subject": "دعوة لفريق %s في %s",
|
||||
"emails.invitation.hello": "أهلا",
|
||||
"emails.invitation.body": "هذة الرسالة تم ارسالها لك لأن {{owner}} ارسل لك دعوة لتكون عضوا بفريق {{team}} في {{project}}",
|
||||
"emails.invitation.footer": "اذا كنت غير مهتم، يمكنك تجاهل هذه الرسالة",
|
||||
"emails.invitation.thanks": "شكرا",
|
||||
"emails.invitation.signature": "فريق {{project}}",
|
||||
"locale.country.unknown": "مجهول",
|
||||
"countries.af": "أفغانستان",
|
||||
"countries.ao": "أنغولا",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "be",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Каманда %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Верыфікацыя акаўнта",
|
||||
"emails.verification.hello": "Прывітанне {{name}}",
|
||||
"emails.verification.body": "Перайдзіце па гэтай спасылцы, каб пацвердзіць свой адрас электроннай пошты",
|
||||
"emails.verification.footer": "Калі вы не запытвалі пацвярджэнне гэтага адрасу, праігнаруйце гэтае паведамленне.",
|
||||
"emails.verification.thanks": "Дзякуем",
|
||||
"emails.verification.signature": "каманда {{project}}",
|
||||
"emails.magicSession.subject": "Лагін",
|
||||
"emails.magicSession.hello": "Прывітанне,",
|
||||
"emails.magicSession.body": "Перайдзіце па спасылцы, каб увайсці.",
|
||||
"emails.magicSession.footer": "Калі вы не прасілі ўвайсці, выкарыстоўваючы гэты адрас электроннай пошты, праігнаруйце гэтае паведамленне.",
|
||||
"emails.magicSession.thanks": "Дзякуем",
|
||||
"emails.magicSession.signature": "каманда {{project}}",
|
||||
"emails.recovery.subject": "Скід пароля",
|
||||
"emails.recovery.hello": "Прывітанне, {{name}}",
|
||||
"emails.recovery.body": "Перайдзіце па гэтай спасылцы, каб скінуць пароль для праекта {{project}}.",
|
||||
"emails.recovery.footer": "Калі вы не прасілі скінуць пароль, вы можаце праігнараваць гэта паведамленне.",
|
||||
"emails.recovery.thanks": "Дзякуем",
|
||||
"emails.recovery.signature": "каманда {{project}}",
|
||||
"emails.invitation.subject": "Запрошення до Команди %s у %s",
|
||||
"emails.invitation.hello": "Прывітанне",
|
||||
"emails.invitation.body": "Гэта паведамленне было адпраўлена вам, таму што {{owner}} хацеў запрасіць вас стаць членам каманды {{team}} у {{project}}.",
|
||||
"emails.invitation.footer": "Калі вам гэта не цікава, вы можаце праігнараваць гэтае паведамленне.",
|
||||
"emails.invitation.thanks": "Дзякуем",
|
||||
"emails.invitation.signature": "каманда {{project}}",
|
||||
"locale.country.unknown": "Невядомы",
|
||||
"countries.af": "Афганістан",
|
||||
"countries.ao": "Ангола",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Паўночная Амерыка",
|
||||
"continents.oc": "Акіянія",
|
||||
"continents.sa": "Паўднёвая Амерыка"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
232
app/config/locale/translations/bh.json
Normal file
232
app/config/locale/translations/bh.json
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"बुद्धिमान होइत क कला ई जाने क कला अछि जे की अनदेखा कर्मा चाहि| \"",
|
||||
"settings.locale": "bh",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s टीम",
|
||||
"emails.verification.subject": "खाता प्रमाणिकरण",
|
||||
"emails.verification.hello": "नमस्ते {{name}}",
|
||||
"emails.verification.body": "ईमेल प्रमाणिकरण करे क लेल दिहल गइल लिंक फॉलो करें|",
|
||||
"emails.verification.footer": "अगर ई पता को सत्यापित करे के लिए ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।",
|
||||
"emails.verification.thanks": "धन्यवाद",
|
||||
"emails.verification.signature": "{{project}} टीम",
|
||||
"emails.magicSession.subject": "लॉग इन करीं|",
|
||||
"emails.magicSession.hello": "प्रणाम",
|
||||
"emails.magicSession.body": "लॉग इन करें लेल दिहल गइल लिंक फॉलो करें|",
|
||||
"emails.magicSession.footer": "अगर लॉग इन करे के लिए ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।",
|
||||
"emails.magicSession.thanks": "धन्यवाद",
|
||||
"emails.magicSession.signature": "{{project}} टीम",
|
||||
"emails.recovery.subject": "पासवर्ड बदल क लेल|",
|
||||
"emails.recovery.hello": "प्रणाम {{name}}",
|
||||
"emails.recovery.body": "पासवर्ड बदल क लेल दिहल गइल लिंक फॉलो करें|",
|
||||
"emails.recovery.footer": "अगर पासवर्ड बदल क लेल ना कहाले, तो आप ई संदेश क अनदेखा कर सकत अछि।",
|
||||
"emails.recovery.thanks": "धन्यवाद",
|
||||
"emails.recovery.signature": "{{project}} टीम",
|
||||
"emails.invitation.subject": "%s टीम क %s पे न्योता देवे क लेल|",
|
||||
"emails.invitation.hello": "प्रणाम",
|
||||
"emails.invitation.body": "ई मेल आपके एही लेल भेजल गईल रहल काहे क {{owner}} आपके {{project}} क {{team}} टीम का सदस्य बनावे चाहित रहे|",
|
||||
"emails.invitation.footer": "अगर आवे क इच्छा ना होवत, तो आप ई संदेश क अनदेखा कर सकत अछि।",
|
||||
"emails.invitation.thanks": "धन्यवाद",
|
||||
"emails.invitation.signature": "{{project}} टीम",
|
||||
"locale.country.unknown": "अनजान",
|
||||
"countries.af": "अफ़ग़ानिस्तान",
|
||||
"countries.ao": "अंगोला",
|
||||
"countries.al": "अल्बानिया",
|
||||
"countries.ad": "अंडोरा",
|
||||
"countries.ae": "संयुक्त अरब अमीरात",
|
||||
"countries.ar": "अर्जेंटीना",
|
||||
"countries.am": "आर्मीनिया",
|
||||
"countries.ag": "अंटीगुआ और बारबूडा",
|
||||
"countries.au": "ऑस्ट्रेलिया",
|
||||
"countries.at": "ऑस्ट्रिया",
|
||||
"countries.az": "अज़रबैजान",
|
||||
"countries.bi": "बुरुंडी",
|
||||
"countries.be": "बेल्जियम",
|
||||
"countries.bj": "बेनिन",
|
||||
"countries.bf": "बुर्किना फासो",
|
||||
"countries.bd": "बांग्लादेश",
|
||||
"countries.bg": "बुल्गारिया",
|
||||
"countries.bh": "बहरीन",
|
||||
"countries.bs": "बहामास",
|
||||
"countries.ba": "बॉस्निया और हर्ज़ेगोविना",
|
||||
"countries.by": "बेलारूस",
|
||||
"countries.bz": "बेलीज़",
|
||||
"countries.bo": "बोलीविया",
|
||||
"countries.br": "ब्राज़ील",
|
||||
"countries.bb": "बारबाडोस",
|
||||
"countries.bn": "ब्रुनेई",
|
||||
"countries.bt": "भूटान",
|
||||
"countries.bw": "बोत्सवाना",
|
||||
"countries.cf": "मध्य अफ्रीकी गणराज्य",
|
||||
"countries.ca": "कनाडा",
|
||||
"countries.ch": "स्विट्ज़रलैंड",
|
||||
"countries.cl": "चिली",
|
||||
"countries.cn": "चीन",
|
||||
"countries.ci": "आइवरी कोस्ट",
|
||||
"countries.cm": "कैमरून",
|
||||
"countries.cd": "कांगो लोकतान्त्रिक गणराज्य",
|
||||
"countries.cg": "कांगो गणराज्य",
|
||||
"countries.co": "कोलंबिया",
|
||||
"countries.km": "कोमोरोस",
|
||||
"countries.cv": "केप वर्दे",
|
||||
"countries.cr": "कोस्टा रीका",
|
||||
"countries.cu": "क्यूबा",
|
||||
"countries.cy": "साइप्रस",
|
||||
"countries.cz": "चेक गणराज्य",
|
||||
"countries.de": "जर्मनी",
|
||||
"countries.dj": "जिबूती",
|
||||
"countries.dm": "डोमिनिका",
|
||||
"countries.dk": "डेनमार्क",
|
||||
"countries.do": "डोमिनिकन रिपब्लिक",
|
||||
"countries.dz": "अल्जीरिया",
|
||||
"countries.ec": "ईक्वाडोर",
|
||||
"countries.eg": "मिस्र",
|
||||
"countries.er": "इरित्रिया",
|
||||
"countries.es": "स्पेन",
|
||||
"countries.ee": "एस्टोनिया",
|
||||
"countries.et": "इथियोपिया",
|
||||
"countries.fi": "फ़िनलैंड",
|
||||
"countries.fj": "फ़िजी",
|
||||
"countries.fr": "फ्रांस",
|
||||
"countries.fm": "माइक्रोनेशिया",
|
||||
"countries.ga": "गबोन",
|
||||
"countries.gb": "यूनाइटेड किंगडम",
|
||||
"countries.ge": "जॉर्जिया",
|
||||
"countries.gh": "घाना",
|
||||
"countries.gn": "गिनी",
|
||||
"countries.gm": "ज़ाम्बिया",
|
||||
"countries.gw": "गिनी-बिसाऊ",
|
||||
"countries.gq": "इक्वेटोरियल गिनी",
|
||||
"countries.gr": "यूनान",
|
||||
"countries.gd": "ग्रेनाडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गयाना",
|
||||
"countries.hn": "होंडुरस",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
"countries.hu": "हंगरी",
|
||||
"countries.id": "इंडोनेशिया",
|
||||
"countries.in": "भारत",
|
||||
"countries.ie": "आयरलैंड",
|
||||
"countries.ir": "ईरान",
|
||||
"countries.iq": "इराक",
|
||||
"countries.is": "आइसलैंड",
|
||||
"countries.il": "इज़राइल",
|
||||
"countries.it": "इटली",
|
||||
"countries.jm": "जमैका",
|
||||
"countries.jo": "जॉर्डन",
|
||||
"countries.jp": "जापान",
|
||||
"countries.kz": "कज़ाख़िस्तान",
|
||||
"countries.ke": "कीनियाा",
|
||||
"countries.kg": "किर्गिज़स्तान",
|
||||
"countries.kh": "कंबोडिया",
|
||||
"countries.ki": "किरिबाती",
|
||||
"countries.kn": "सेंट किट्स एंड नेविस",
|
||||
"countries.kr": "दक्षिण कोरिया",
|
||||
"countries.kw": "कुवैत",
|
||||
"countries.la": "लाओस",
|
||||
"countries.lb": "लेबनान",
|
||||
"countries.lr": "लाइबेरिया",
|
||||
"countries.ly": "लीबिया",
|
||||
"countries.lc": "सेंट लूसिया",
|
||||
"countries.li": "लिकटेंस्टीन",
|
||||
"countries.lk": "श्रीलंका",
|
||||
"countries.ls": "लेसोथो",
|
||||
"countries.lt": "लिथुआनिया",
|
||||
"countries.lu": "लक्ज़मबर्ग",
|
||||
"countries.lv": "लातविया",
|
||||
"countries.ma": "मोरक्को",
|
||||
"countries.mc": "मोनैको",
|
||||
"countries.md": "मॉल्डोवा",
|
||||
"countries.mg": "मेडागास्कर",
|
||||
"countries.mv": "मालदीव",
|
||||
"countries.mx": "मेक्सिको",
|
||||
"countries.mh": "मार्शल द्वीपसमूह",
|
||||
"countries.mk": "मैसिडोनिया",
|
||||
"countries.ml": "माली",
|
||||
"countries.mt": "माल्टा",
|
||||
"countries.mm": "म्यांमार",
|
||||
"countries.me": "मोंटेनेग्रो",
|
||||
"countries.mn": "मंगोलिया",
|
||||
"countries.mz": "मोज़ाम्बिक",
|
||||
"countries.mr": "मॉरिटानिया",
|
||||
"countries.mu": "मॉरिशस",
|
||||
"countries.mw": "मलावी",
|
||||
"countries.my": "मलेशिया",
|
||||
"countries.na": "नामीबिया",
|
||||
"countries.ne": "नाइजर",
|
||||
"countries.ng": "नाईजीरिया",
|
||||
"countries.ni": "निकारागुआ",
|
||||
"countries.nl": "नीदरलैंड",
|
||||
"countries.no": "नॉर्वे",
|
||||
"countries.np": "नेपाल",
|
||||
"countries.nr": "नाउरु",
|
||||
"countries.nz": "न्यूजीलैंड",
|
||||
"countries.om": "ओमान",
|
||||
"countries.pk": "पाकिस्तान",
|
||||
"countries.pa": "पनामा",
|
||||
"countries.pe": "पेरू",
|
||||
"countries.ph": "फिलीपींस",
|
||||
"countries.pw": "पलाऊ",
|
||||
"countries.pg": "पापुआ न्यू गिनी",
|
||||
"countries.pl": "पोलैंड",
|
||||
"countries.kp": "उत्तर कोरिया",
|
||||
"countries.pt": "पुर्तगाल",
|
||||
"countries.py": "पैराग्वे",
|
||||
"countries.qa": "क़तर",
|
||||
"countries.ro": "रोमानिया",
|
||||
"countries.ru": "रूस",
|
||||
"countries.rw": "रवांडा",
|
||||
"countries.sa": "सऊदी अरब",
|
||||
"countries.sd": "सूडान",
|
||||
"countries.sn": "सेनेगल",
|
||||
"countries.sg": "सिंगापुर",
|
||||
"countries.sb": "सोलोमन द्वीप",
|
||||
"countries.sl": "सिएरा लियोन",
|
||||
"countries.sv": "अल साल्वाडोर",
|
||||
"countries.sm": "सैन मैरिनो",
|
||||
"countries.so": "सोमालिया",
|
||||
"countries.rs": "सर्बिया",
|
||||
"countries.ss": "दक्षिण सूडान",
|
||||
"countries.st": "साओ तोमे और प्रिंसिपी",
|
||||
"countries.sr": "सूरीनाम",
|
||||
"countries.sk": "स्लोवाकिया",
|
||||
"countries.si": "स्लोवेनिया",
|
||||
"countries.se": "स्वीडन",
|
||||
"countries.sz": "स्वाज़ीलैंड",
|
||||
"countries.sc": "सेशेल्स",
|
||||
"countries.sy": "सीरिया",
|
||||
"countries.td": "चाड",
|
||||
"countries.tg": "टोगो",
|
||||
"countries.th": "थाईलैंड",
|
||||
"countries.tj": "ताजिकिस्तान",
|
||||
"countries.tm": "तुर्कमेनिस्तान",
|
||||
"countries.tl": "तिमोर-लेस्ते",
|
||||
"countries.to": "टोंगा",
|
||||
"countries.tt": "त्रिनिदाद और टोबैगो",
|
||||
"countries.tn": "ट्यूनीशिया",
|
||||
"countries.tr": "तुर्की",
|
||||
"countries.tv": "तुवालू",
|
||||
"countries.tz": "तंजानिया",
|
||||
"countries.ug": "युगांडा",
|
||||
"countries.ua": "यूक्रेन",
|
||||
"countries.uy": "उरुग्वे",
|
||||
"countries.us": "संयुक्त राज्य अमेरिका",
|
||||
"countries.uz": "उज़्बेकिस्तान",
|
||||
"countries.va": "वैटिकन सिटी",
|
||||
"countries.vc": "सेंट विंसेंट एंड ग्रेनेडाइंस",
|
||||
"countries.ve": "वेनेज़ुएला",
|
||||
"countries.vn": "वियतनाम",
|
||||
"countries.vu": "वानूआतू",
|
||||
"countries.ws": "समोआ",
|
||||
"countries.ye": "यमन",
|
||||
"countries.za": "दक्षिण अफ्रीका",
|
||||
"countries.zm": "ज़ाम्बिया",
|
||||
"countries.zw": "ज़िम्बाब्वे",
|
||||
"continents.af": "अफ़्रीका",
|
||||
"continents.an": "अंटार्कटिका",
|
||||
"continents.as": "एशिया",
|
||||
"continents.eu": "यूरोप",
|
||||
"continents.na": "उत्तरी अमेरिका",
|
||||
"continents.oc": "ओशिनिया",
|
||||
"continents.sa": "दक्षिण अमेरिका"
|
||||
}
|
||||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ca",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Equip",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verificació del compte",
|
||||
"emails.verification.hello": "Hola {{name}}",
|
||||
"emails.verification.body": "Accedeix a aquest enllaç per tal de verificar la teva adreça electrònica.",
|
||||
"emails.verification.footer": "Si no has sol·licitat la verificació d'aquesta adreça electrònica, pots ignorar aquest missatge.",
|
||||
"emails.verification.thanks": "Gràcies",
|
||||
"emails.verification.signature": "Equip {{project}}",
|
||||
"emails.magicSession.subject": "Entrar",
|
||||
"emails.magicSession.hello": "Hola,",
|
||||
"emails.magicSession.body": "Accedeix a aquest enllaç per a entrar.",
|
||||
"emails.magicSession.footer": "Si no has sol·licitat entrar amb aquesta adreça electrònica, pots ignorar aquest missatge.",
|
||||
"emails.magicSession.thanks": "Gràcies",
|
||||
"emails.magicSession.signature": "Equip {{project}}",
|
||||
"emails.recovery.subject": "Reinicialitzar contrasenya",
|
||||
"emails.recovery.hello": "Hola {{name}}",
|
||||
"emails.recovery.body": "Accedeix a aquest enllaç per a reinicialitzar la teva contrasenya de {{project}}.",
|
||||
"emails.recovery.footer": "Si no has sol·licitat reinicialitzar la teva contrasenya, pots ignorar aquest missatge.",
|
||||
"emails.recovery.thanks": "Gràcies",
|
||||
"emails.recovery.signature": "Equip {{project}}",
|
||||
"emails.invitation.subject": "Invitació a l'equip %s a s%",
|
||||
"emails.invitation.hello": "Hola",
|
||||
"emails.invitation.body": "Aquest correu se t'ha enviat perquè {{owner}} vol convidar-te a formar part de l'equip {{team}} al {{project}}.",
|
||||
"emails.invitation.footer": "Si no és del teu interès, pots ignorar aquest missatge.",
|
||||
"emails.invitation.thanks": "Gràcies",
|
||||
"emails.invitation.signature": "Equip {{project}}",
|
||||
"locale.country.unknown": "Desconegut",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
@ -29,7 +35,7 @@
|
|||
"countries.ae": "Unió dels Emirats Àrabs Units",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armènia",
|
||||
"countries.ag": "Antigua o Barbuda",
|
||||
"countries.ag": "Antigua i Barbuda",
|
||||
"countries.au": "Austràlia",
|
||||
"countries.at": "Àustria",
|
||||
"countries.az": "Azerbaidjan",
|
||||
|
|
@ -38,7 +44,7 @@
|
|||
"countries.bj": "Benín",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangla Desh",
|
||||
"countries.bg": "Bulgaria",
|
||||
"countries.bg": "Bulgària",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bòsnia i Hercegovina",
|
||||
|
|
@ -107,7 +113,7 @@
|
|||
"countries.il": "Israel",
|
||||
"countries.it": "Itàlia",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordà",
|
||||
"countries.jo": "Jordània",
|
||||
"countries.jp": "Japó",
|
||||
"countries.kz": "Kazakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
|
|
@ -121,7 +127,7 @@
|
|||
"countries.lb": "Líban",
|
||||
"countries.lr": "Libèria",
|
||||
"countries.ly": "Líbia",
|
||||
"countries.lc": "Santa Llúcia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesoto",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
232
app/config/locale/translations/da.json
Normal file
232
app/config/locale/translations/da.json
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"Kunsten at være klog er kunsten at vide, hvad man skal overse.\"",
|
||||
"settings.locale": "da",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Konto Verifikation",
|
||||
"emails.verification.hello": "Hej {{name}}",
|
||||
"emails.verification.body": "Følg dette link, for at verificere din email adresse.",
|
||||
"emails.verification.footer": "Hvis du ikke har bedt om at verificere denne adresse, ignorer venligst denne besked.",
|
||||
"emails.verification.thanks": "Tak",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hej,",
|
||||
"emails.magicSession.body": "Følg dette link for at logge ind.",
|
||||
"emails.magicSession.footer": "Hvis du ikke har bedt om at logge ind med denne email, ignorer venligst denne besked.",
|
||||
"emails.magicSession.thanks": "Tak",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Nulstil Password",
|
||||
"emails.recovery.hello": "Hej {{name}}",
|
||||
"emails.recovery.body": "Følg dette link for at nulstille koden til {{project}}.",
|
||||
"emails.recovery.footer": "Hvis du ikke har bedt om at nulstille dit password, ignorer venligst denne besked.",
|
||||
"emails.recovery.thanks": "Tak",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitation til %s Team på %s",
|
||||
"emails.invitation.hello": "Hej",
|
||||
"emails.invitation.body": "Denne mail blev sendt til dig, fordi {{owner}} vil invitere dig til at blive medlem af {{team}} teamet på {{project}}.",
|
||||
"emails.invitation.footer": "Hvis du ikke er interesseret, ignorer venligst denne besked.",
|
||||
"emails.invitation.thanks": "Tak",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Ukendt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albanien",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Forenede Arabiske Emirater",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenien",
|
||||
"countries.ag": "Antigua and Barbuda",
|
||||
"countries.au": "Australien",
|
||||
"countries.at": "Østrig",
|
||||
"countries.az": "Aserbajdsjan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgien",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesh",
|
||||
"countries.bg": "Bulgarien",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnien-Hercegovina",
|
||||
"countries.by": "Hviderusland",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivia",
|
||||
"countries.br": "Brasilien",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Den Centralafrikanske Republik",
|
||||
"countries.ca": "Canada",
|
||||
"countries.ch": "Schweiz",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Kina",
|
||||
"countries.ci": "Elfenbenskysten",
|
||||
"countries.cm": "Cameroun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republikken Congo",
|
||||
"countries.co": "Colombia",
|
||||
"countries.km": "Comorerne",
|
||||
"countries.cv": "Kap Verde",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Cuba",
|
||||
"countries.cy": "Cypern",
|
||||
"countries.cz": "Tjekkiet",
|
||||
"countries.de": "Tyskland",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Danmark",
|
||||
"countries.do": "Dominikanske Republik",
|
||||
"countries.dz": "Algeriet",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Egypten",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spainen",
|
||||
"countries.ee": "Estland",
|
||||
"countries.et": "Etiopien",
|
||||
"countries.fi": "Finland",
|
||||
"countries.fj": "Fiji",
|
||||
"countries.fr": "Frankrig",
|
||||
"countries.fm": "Mikronesien",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Storbritannien",
|
||||
"countries.ge": "Georgien",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Ækvatorialguinea",
|
||||
"countries.gr": "Grækenland",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Ungarn",
|
||||
"countries.id": "Indonesien",
|
||||
"countries.in": "Indien",
|
||||
"countries.ie": "Irland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italen",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kasakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
"countries.kg": "Kirgisistan",
|
||||
"countries.kh": "Cambodja",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts og Nevis",
|
||||
"countries.kr": "Sydkorea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libyen",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litauen",
|
||||
"countries.lu": "Luxembourg",
|
||||
"countries.lv": "Letland",
|
||||
"countries.ma": "Marokko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldova",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldiverne",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mh": "Marshalløerne",
|
||||
"countries.mk": "Makedonien",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongoliet",
|
||||
"countries.mz": "Mozambique",
|
||||
"countries.mr": "Mauritanien",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysia",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Holland",
|
||||
"countries.no": "Norge",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "New Zealand",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filippinerne",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Ny Guinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nordkorea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Qatar",
|
||||
"countries.ro": "Rumænien",
|
||||
"countries.ru": "Rusland",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudi Arabien",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapore",
|
||||
"countries.sb": "Salomonøerne",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbien",
|
||||
"countries.ss": "Sydsudan",
|
||||
"countries.st": "Sao Tome og Principe",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovakiet",
|
||||
"countries.si": "Slovenien",
|
||||
"countries.se": "Sverige",
|
||||
"countries.sz": "Swaziland",
|
||||
"countries.sc": "Seychellerne",
|
||||
"countries.sy": "Syrien",
|
||||
"countries.td": "Tchad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tadsjikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad og Tobago",
|
||||
"countries.tn": "Tunisien",
|
||||
"countries.tr": "Tyrkiet",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "Amerikas Forenede Stater",
|
||||
"countries.uz": "Usbekistan",
|
||||
"countries.va": "Vatikanet",
|
||||
"countries.vc": "Saint Vincent og Grenadinerne",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "Sydafrika",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktis",
|
||||
"continents.as": "Asien",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Nordamerica",
|
||||
"continents.oc": "Oceanien",
|
||||
"continents.sa": "Sydamerica"
|
||||
}
|
||||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "de",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Kontoverifizierung",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Folge diesem Link, um deine E-Mail-Adresse zu bestätigen.",
|
||||
"emails.verification.footer": "Solltest du keine Verifizierung dieser E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.",
|
||||
"emails.verification.thanks": "Danke",
|
||||
"emails.verification.signature": "{{project}}-Team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Folge diesem Link, um dich einzuloggen.",
|
||||
"emails.magicSession.footer": "Solltest du keinen Login für diese E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.",
|
||||
"emails.magicSession.thanks": "Danke",
|
||||
"emails.magicSession.signature": "{{project}}-Team",
|
||||
"emails.recovery.subject": "Kennwort zurücksetzen",
|
||||
"emails.recovery.hello": "Hallo {{name}}",
|
||||
"emails.recovery.body": "Folge diesem Link, um dein {{project}}-Kennwort zurückzusetzen.",
|
||||
"emails.recovery.footer": "Solltest du keine Kennwort-Zurücksetzung angefordert haben, kannst du diese Nachricht ignorieren.",
|
||||
"emails.recovery.thanks": "Danke",
|
||||
"emails.recovery.signature": "{{project}}-Team",
|
||||
"emails.invitation.subject": "Einladung zum %s-Team auf %s",
|
||||
"emails.invitation.hello": "Hello",
|
||||
"emails.invitation.body": "Du erhälst diese E-Mail, weil {{owner}} dich in das Team {{team}} auf {{project}} eingeladen hat.",
|
||||
"emails.invitation.footer": "Wenn du nicht interessiert bist, kannst du diese Nachricht ignorieren.",
|
||||
"emails.invitation.thanks": "Danke",
|
||||
"emails.invitation.signature": "{{project}}-Team",
|
||||
"locale.country.unknown": "Unbekannt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
@ -135,7 +141,7 @@
|
|||
"countries.mv": "Malediven",
|
||||
"countries.mx": "Mexiko",
|
||||
"countries.mh": "Marshallinseln",
|
||||
"countries.mk": "Mazedonien",
|
||||
"countries.mk": "Nordmazedonien",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
|
|
@ -163,7 +169,7 @@
|
|||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Neu-Guinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nord Korea",
|
||||
"countries.kp": "Nordkorea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Katar",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Nordamerika",
|
||||
"continents.oc": "Ozeanien",
|
||||
"continents.sa": "Südamerika"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,32 @@
|
|||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"Η τέχνη του να είσαι σοφός, είναι η τέχνη να ξέρεις τι πρέπει να παραβλέψεις.\"",
|
||||
"settings.locale": "gr",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Ομάδα %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Επαλήθευση Λογαριασμού",
|
||||
"emails.verification.hello": "Γεια σου {{name}}",
|
||||
"emails.verification.body": "Ακολουθήστε αυτό το link για να επαληθεύσετε τη δ/νση του email σας",
|
||||
"emails.verification.footer": "Εάν δεν ζητήσατε επαλήθευση αυτής της δ/νσης email, μπορείτε να αγνοήσετε αυτό το μήνυμα",
|
||||
"emails.verification.thanks": "Ευχαριστούμε",
|
||||
"emails.verification.signature": "Η ομάδα του {{project}}",
|
||||
"emails.magicSession.subject": "Είσοδος",
|
||||
"emails.magicSession.hello": "Γεια σου,",
|
||||
"emails.magicSession.body": "Ακολουθήστε αυτό το link για να συνδεθείτε",
|
||||
"emails.magicSession.footer": "Εάν δεν ζητήσατε να συνδεθείτε χρησιμοποιώντας αυτό το email, μπορείτε να αγνοήσετε αυτό το μήνυμα.",
|
||||
"emails.magicSession.thanks": "Ευχαριστούμε",
|
||||
"emails.magicSession.signature": "Η ομάδα του {{project}}",
|
||||
"emails.recovery.subject": "Αλλαγή κωδικού πρόσβασης",
|
||||
"emails.recovery.hello": "Γεια σου {{name}}",
|
||||
"emails.recovery.body": "Ακολουθήστε αυτό το link για να αλλάξετε τον {{project}} κωδικό σας",
|
||||
"emails.recovery.footer": "Εάν δεν ζητήσατε αλλαγή του κωδικού σας πρόσβασης, μπορείτε να αγνοήσετε αυτό το μήνυμα",
|
||||
"emails.recovery.thanks": "Ευχαριστούμε",
|
||||
"emails.recovery.signature": "Η ομάδα του {{project}}",
|
||||
"emails.invitation.subject": "Πρόσκληση στην %s Ομάδα στον %s",
|
||||
"emails.invitation.hello": "Γεια σου",
|
||||
"emails.invitation.body": "Αυτό το email στάλθηκε επειδή ο/η {{owner}} θέλει να σας προσκαλέσει να γίνετε μέλος της ομάδας {{team}} του {{project}}.",
|
||||
"emails.invitation.footer": "Εάν δεν ενδιαφέρεστε, μπορείτε να αγνοήσετε αυτό το μήνυμα.",
|
||||
"emails.invitation.thanks": "Ευχαριστούμε",
|
||||
"emails.invitation.signature": "Η ομάδα του {{project}}",
|
||||
"locale.country.unknown": "Άγνωστο",
|
||||
"countries.af": "Αφγανιστάν",
|
||||
"countries.ao": "Ανγκόλα",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Βόρεια Αμερική",
|
||||
"continents.oc": "Ωκεανία",
|
||||
"continents.sa": "Νότια Αμερική"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.",
|
||||
"emails.verification.thanks": "Thanks",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Follow this link to login.",
|
||||
"emails.magicSession.footer": "If you didn’t ask to login using this email, you can ignore this message.",
|
||||
"emails.magicSession.thanks": "Thanks",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Password Reset",
|
||||
"emails.recovery.hello": "Hello {{name}}",
|
||||
"emails.recovery.body": "Follow this link to reset your {{project}} password.",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "es",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Equipo %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verificación de cuenta",
|
||||
"emails.verification.hello": "Hola {{name}}",
|
||||
"emails.verification.body": "Haz clic en este enlace para verificar tu correo.",
|
||||
"emails.verification.footer": "Si no has solicitado verificar este correo, puedes ignorar este mensaje.",
|
||||
"emails.verification.thanks": "Gracias",
|
||||
"emails.verification.signature": "Equipo de {{project}}",
|
||||
"emails.magicSession.subject": "Inicio de sesión",
|
||||
"emails.magicSession.hello": "Hola,",
|
||||
"emails.magicSession.body": "Haz clic en este enlace para iniciar sesión.",
|
||||
"emails.magicSession.footer": "Si no has solicitado ingresar usando este correo, puedes ignorar este mensaje.",
|
||||
"emails.magicSession.thanks": "Gracias",
|
||||
"emails.magicSession.signature": "Equipo de {{project}}",
|
||||
"emails.recovery.subject": "Restablecer contraseña",
|
||||
"emails.recovery.hello": "Hola {{name}}",
|
||||
"emails.recovery.body": "Haz clic en este enlace para restablecer la contraseña de tu proyecto {{project}}.",
|
||||
"emails.recovery.footer": "Si no has solicitado restablecer la contraseña, puedes ignorar este mensaje.",
|
||||
"emails.recovery.thanks": "Gracias",
|
||||
"emails.recovery.signature": "Equipo de {{project}}",
|
||||
"emails.invitation.subject": "Invitación al equipo %s en %s",
|
||||
"emails.invitation.hello": "Hola",
|
||||
"emails.invitation.body": "Este correo ha sido enviado a petición de {{owner}} quien quiere invitarte a formar parte del equipo {{team}} en el proyecto {{project}}.",
|
||||
"emails.invitation.footer": "Si no estas interesado, puedes ignorar este mensaje.",
|
||||
"emails.invitation.thanks": "Gracias",
|
||||
"emails.invitation.signature": "Equipo de {{project}}",
|
||||
"locale.country.unknown": "Desconocido",
|
||||
"countries.af": "Afganistán",
|
||||
"countries.ao": "Angola",
|
||||
|
|
@ -133,7 +139,7 @@
|
|||
"countries.md": "Moldavia",
|
||||
"countries.mg": "Madagascar",
|
||||
"countries.mv": "Maldivas",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mx": "México",
|
||||
"countries.mh": "Islas Marshall",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Malí",
|
||||
|
|
|
|||
|
|
@ -3,26 +3,32 @@
|
|||
"settings.locale": "fa",
|
||||
"settings.direction": "rtl",
|
||||
"emails.sender": "تیم %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "تأیید حساب",
|
||||
"emails.verification.hello": "سلام {{name}}",
|
||||
"emails.verification.body": "برای تأیید حسابتان پیوند زیر را دنبال کنید.",
|
||||
"emails.verification.footer": "اگر شما درخواست تأیید حساب ندادهاید، میتوانید این ایمیل را نادیده بگیرید.",
|
||||
"emails.verification.thanks": "سپاس فراوان",
|
||||
"emails.verification.signature": "تیم {{name}}",
|
||||
"emails.magicSession.subject": "ورود به حساب کاربری",
|
||||
"emails.magicSession.hello": "سلام،",
|
||||
"emails.magicSession.body": "برای ورود به حسابتان پیوند زیر را دنبال کنید.",
|
||||
"emails.magicSession.footer": "اگر شما درخواست ورود به حساب کاربری ندادهاید، میتوانید این ایمیل را نادیده بگیرید.",
|
||||
"emails.magicSession.thanks": "سپاس فراوان",
|
||||
"emails.magicSession.signature": "تیم {{name}}",
|
||||
"emails.recovery.subject": "بازیابی گذرواژه",
|
||||
"emails.recovery.hello": "سلام {{name}}",
|
||||
"emails.recovery.body": "برای بازیابی گذرواژهتان پیوند زیر را دنبال کنید.",
|
||||
"emails.recovery.footer": "اگر شما درخواست بازیابی گذرواژه ندادهاید، میتوانید این ایمیل را نادیده بگیرید.",
|
||||
"emails.recovery.thanks": "سپاس فراوان",
|
||||
"emails.recovery.signature": "تیم {{name}}",
|
||||
"emails.invitation.subject": "دعوت به تیم %s در %s",
|
||||
"emails.invitation.hello": "سلام",
|
||||
"emails.invitation.body": "این ایمیل برای شما فرستاده شدهاست زیرا {{owner}} میخواهد شما را به تیم {{team}} در پروژهی {{project}} بیفزاید.",
|
||||
"emails.invitation.footer": "اگر علاقه ندارید، میتوانید این پیام را نادیده بگیرید.",
|
||||
"emails.invitation.thanks": "سپاس فراوان",
|
||||
"emails.invitation.signature": "تیم {{name}}",
|
||||
"locale.country.unknown": "ناشناخته",
|
||||
"countries.af": "افقانستان",
|
||||
"countries.af": "افغانستان",
|
||||
"countries.ao": "آنگولا",
|
||||
"countries.al": "آلبانی",
|
||||
"countries.ad": "آندورا",
|
||||
|
|
@ -102,20 +108,20 @@
|
|||
"countries.in": "هند",
|
||||
"countries.ie": "ایرلند",
|
||||
"countries.ir": "ایران",
|
||||
"countries.iq": "عراث",
|
||||
"countries.iq": "عراق",
|
||||
"countries.is": "ایسلند",
|
||||
"countries.il": "اسرائیل",
|
||||
"countries.it": "ایتالیا",
|
||||
"countries.jm": "جاماییکا",
|
||||
"countries.jo": "اردن",
|
||||
"countries.jp": "جاپن",
|
||||
"countries.jp": "ژاپن",
|
||||
"countries.kz": "قزاقستان",
|
||||
"countries.ke": "کنیا",
|
||||
"countries.kg": "قرقیزستان",
|
||||
"countries.kh": "کامبوج",
|
||||
"countries.ki": "کیریباتی",
|
||||
"countries.kn": "سنت کیتس و نویس",
|
||||
"countries.kr": "کرخ جنوبی",
|
||||
"countries.kr": "کره جنوبی",
|
||||
"countries.kw": "کویت",
|
||||
"countries.la": "لائوس",
|
||||
"countries.lb": "لبنان",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "آمریکای شمالی",
|
||||
"continents.oc": "اقیانوسیه",
|
||||
"continents.sa": "آمریکای جنوبی"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,33 @@
|
|||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"Viisaus merkitsee epäolennaisen ohittamisen taitoa.\"",
|
||||
"settings.locale": "fi",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Tiimi",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"locale.country.unknown": "Unknown",
|
||||
"emails.verification.subject": "Tilin vahvistaminen",
|
||||
"emails.verification.hello": "Hei {{name}}",
|
||||
"emails.verification.body": "Vahvista sähköpostiosoitteesi napsauttamalla tätä linkkiä.",
|
||||
"emails.verification.footer": "Voit ohittaa tämän viestin, jos et pyytänyt sähköpostiosoitteen vahvistamista.",
|
||||
"emails.verification.thanks": "Kiitos",
|
||||
"emails.verification.signature": "Projektin {{project}} tiimi",
|
||||
"emails.magicSession.subject": "Sisäänkirjautuminen",
|
||||
"emails.magicSession.hello": "Hei,",
|
||||
"emails.magicSession.body": "Kirjaudu sisään napsauttamalla tätä linkkiä.",
|
||||
"emails.magicSession.footer": "Voit ohittaa tämän viestin, jos et pyytänyt sisäänkirjautumista tällä sähköpostiosoitteella.",
|
||||
"emails.magicSession.thanks": "Kiitos",
|
||||
"emails.magicSession.signature": "Projektin {{project}} tiimi",
|
||||
"emails.recovery.subject": "Salasanan nollaaminen",
|
||||
"emails.recovery.hello": "Hei {{name}}",
|
||||
"emails.recovery.body": "Nollaa projektin {{project}} salasanasi napsauttamalla tätä linkkiä.",
|
||||
"emails.recovery.footer": "Voit ohittaa tämän viestin, jos et pyytänyt salasanasi nollaamista.",
|
||||
"emails.recovery.thanks": "Kiitos",
|
||||
"emails.recovery.signature": "Projektin {{project}} tiimi",
|
||||
"emails.invitation.subject": "Kutsu liittyä tiimiin %s projektissa %s",
|
||||
"emails.invitation.hello": "Hei",
|
||||
"emails.invitation.body": "Saat tämän viestin, koska {{owner}} haluaa kutsua sinut tiimin {{team}} jäseneksi projektissa {{project}}.",
|
||||
"emails.invitation.footer": "Voit ohittaa tämän viestin, jos et halua liittyä tiimiin.",
|
||||
"emails.invitation.thanks": "Kiitos",
|
||||
"emails.invitation.signature": "Projektin {{project}} tiimi",
|
||||
"locale.country.unknown": "Tuntematon",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
|
|
@ -220,7 +226,7 @@
|
|||
"continents.an": "Antarktis",
|
||||
"continents.as": "Aasia",
|
||||
"continents.eu": "Eurooppa",
|
||||
"continents.na": "Pohjois Amerikka",
|
||||
"continents.na": "Pohjois-Amerikka",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "Etelä Amerikka"
|
||||
"continents.sa": "Etelä-Amerikka"
|
||||
}
|
||||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "fr",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Équipe %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Vérification du compte",
|
||||
"emails.verification.hello": "Bonjour {{name}}",
|
||||
"emails.verification.body": "Suivez ce lien pour vérifier votre adresse mail.",
|
||||
"emails.verification.footer": "Si vous n'avez pas demandé à vérifier cette adresse mail, vous pouvez ignorer ce message.",
|
||||
"emails.verification.thanks": "Merci",
|
||||
"emails.verification.signature": "Équipe {{project}}",
|
||||
"emails.magicSession.subject": "Connexion",
|
||||
"emails.magicSession.hello": "Bonjour,",
|
||||
"emails.magicSession.body": "Suivez ce lien pour vous connecter.",
|
||||
"emails.magicSession.footer": "Si vous n'avez pas demandé à vous connecter en utilisant cet e-mail, vous pouvez ignorer ce message.",
|
||||
"emails.magicSession.thanks": "Merci",
|
||||
"emails.magicSession.signature": "Réinitialisation du mot de passe",
|
||||
"emails.recovery.subject": "Bonjour {{name}}",
|
||||
"emails.recovery.hello": "Bonjour {{name}}",
|
||||
"emails.recovery.body": "Suivez ce lien pour réinitialiser votre mot de passe de {{projet}}.",
|
||||
"emails.recovery.footer": "Si vous n'avez pas demandé à réinitialiser votre mot de passe, vous pouvez ignorer ce message.",
|
||||
"emails.recovery.thanks": "Merci",
|
||||
"emails.recovery.signature": "Équipe {{project}}",
|
||||
"emails.invitation.subject": "Invitation à l'équipe %s de %s",
|
||||
"emails.invitation.hello": "Bonjour",
|
||||
"emails.invitation.body": "Ce mail vous a été envoyé parce que {{owner}} voulait vous inviter à devenir membre de l'équipe {{team}} de {{project}}.",
|
||||
"emails.invitation.footer": "Si vous n'êtes pas intéressé, vous pouvez ignorer ce message.",
|
||||
"emails.invitation.thanks": "Merci",
|
||||
"emails.invitation.signature": "Équipe {{project}}",
|
||||
"locale.country.unknown": "Inconnu",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -3,25 +3,31 @@
|
|||
"settings.locale": "gu",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s ટીમ",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
"emails.verification.subject": "ખાતાની ચકાસણી",
|
||||
"emails.verification.hello": "નમસ્કાર {{name}}",
|
||||
"emails.verification.body": "તમારું ઇમેઇલ સરનામું ચકાસવા માટે આ લિંકને અનુસરો.",
|
||||
"emails.verification.footer": "જો તમે આ સરનામાંની ચકાસણી કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.",
|
||||
"emails.verification.thanks": "આભાર",
|
||||
"emails.verification.signature": "{{project}} ટીમ",
|
||||
"emails.magicSession.subject": "પ્રવેશ કરો",
|
||||
"emails.magicSession.hello": "નમસ્કાર,",
|
||||
"emails.magicSession.body": "પ્રવેશ કરવા માટે આ લિંકને અનુસરો.",
|
||||
"emails.magicSession.footer": "જો તમે આ ઇમેઇલનો ઉપયોગ કરીને પ્રવેશ કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.",
|
||||
"emails.magicSession.thanks": "આભાર",
|
||||
"emails.magicSession.signature": "{{project}} ટીમ",
|
||||
"emails.recovery.subject": "પાસવર્ડ ફરીથી સેટ કરો",
|
||||
"emails.recovery.hello": "નમસ્કાર {{name}}",
|
||||
"emails.recovery.body": "તમારો {{project}} પાસવર્ડ ફરીથી સેટ કરવા માટે આ લિંકને અનુસરો.",
|
||||
"emails.recovery.footer": "જો તમે તમારો પાસવર્ડ ફરીથી સેટ કરવાનું ન કહ્યું હોય, તો તમે આ સંદેશને અવગણી શકો છો.",
|
||||
"emails.recovery.thanks": "આભાર",
|
||||
"emails.recovery.signature": "{{project}} ટીમ",
|
||||
"emails.invitation.subject": "%s ટીમને %s પર આમંત્રણ",
|
||||
"emails.invitation.hello": "નમસ્કાર",
|
||||
"emails.invitation.body": "આ મેઇલ તમને મોકલવામાં આવ્યો હતો કારણ કે {{owner}} તમને {{project}} માં {{team}} ટીમના સભ્ય બનવા માટે આમંત્રિત કરવા માંગતા હતો.",
|
||||
"emails.invitation.footer": "જો તમને રસ નથી, તો તમે આ સંદેશને અવગણી શકો છો.",
|
||||
"emails.invitation.thanks": "આભાર",
|
||||
"emails.invitation.signature": "{{project}} ટીમ",
|
||||
"locale.country.unknown": "અજાણ",
|
||||
"countries.af": "અફઘાનિસ્તાન",
|
||||
"countries.ao": "અંગોલા",
|
||||
"countries.al": "અલ્બેનિયા",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,32 @@
|
|||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"להיות חכם זה לדעת ממה להתעלם.\"",
|
||||
"settings.locale": "he",
|
||||
"settings.direction": "rtl",
|
||||
"emails.sender": "צוות %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "אימות חשבון",
|
||||
"emails.verification.hello": "שלום {{name}}",
|
||||
"emails.verification.body": "לחץ על קישור זה כדי לאמת את כתובת הדוא\"ל שלך.",
|
||||
"emails.verification.footer": "אם לא ביקשת לאמת כתובת זו, תוכל להתעלם מהודעה זו.",
|
||||
"emails.verification.thanks": "תודה",
|
||||
"emails.verification.signature": "צוות {{project}}",
|
||||
"emails.magicSession.subject": "כניסה למערכת",
|
||||
"emails.magicSession.hello": "שלום,",
|
||||
"emails.magicSession.body": "לחץ על קישור זה כדי להיכנס.",
|
||||
"emails.magicSession.footer": "אם לא ביקשת להיכנס באמצעות דוא\"ל זה, תוכל להתעלם מהודעה זו.",
|
||||
"emails.magicSession.thanks": "תודה",
|
||||
"emails.magicSession.signature": "צוות {{project}}",
|
||||
"emails.recovery.subject": "איפוס סיסמא",
|
||||
"emails.recovery.hello": "שלום {{name}}",
|
||||
"emails.recovery.body": "עקוב אחר קישור זה כדי לאפס את סיסמתך ב-{{project}}.",
|
||||
"emails.recovery.footer": "אם לא ביקשת לאפס את הסיסמה, תוכל להתעלם מהודעה זו.",
|
||||
"emails.recovery.thanks": "תודה",
|
||||
"emails.recovery.signature": "צוות {{project}}",
|
||||
"emails.invitation.subject": "הזמנה לצוות %s ב- %s",
|
||||
"emails.invitation.hello": "שלום",
|
||||
"emails.invitation.body": "דואר זה נשלח אליך מכיוון ש {{owner}} רצה להזמין אותך להיות חבר בצוות {{team}} ב-{{project}}.",
|
||||
"emails.invitation.footer": "אם אינך מעוניין, תוכל להתעלם מהודעה זו.",
|
||||
"emails.invitation.thanks": "תודה",
|
||||
"emails.invitation.signature": "צוות {{project}}",
|
||||
"locale.country.unknown": "לא ידוע",
|
||||
"countries.af": "אפגניסטן",
|
||||
"countries.ao": "אנגולה",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "hi",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s टीम",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "खाता सत्यापन",
|
||||
"emails.verification.hello": "नमस्ते {{name}}",
|
||||
"emails.verification.body": "इस लिंक के माध्यम से ईमेल सत्यापित कीजिये।",
|
||||
"emails.verification.footer": "यदि आपने इस पते को सत्यापित करने के लिए नहीं कहा है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.verification.thanks": "धन्यवाद",
|
||||
"emails.verification.signature": "{{project}} टीम",
|
||||
"emails.magicSession.subject": "लॉग इन",
|
||||
"emails.magicSession.hello": "नमस्ते,",
|
||||
"emails.magicSession.body": "इस लिंक के माध्यम से लॉग इन करें।",
|
||||
"emails.magicSession.footer": "यदि आपने इस ईमेल का उपयोग करके लॉगिन करने के लिए नहीं कहा है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.magicSession.thanks": "धन्यवाद",
|
||||
"emails.magicSession.signature": "{{project}} टीम",
|
||||
"emails.recovery.subject": "पासवर्ड रीसेट",
|
||||
"emails.recovery.hello": "नमस्ते {{name}}",
|
||||
"emails.recovery.body": "इस लिंक के माध्यम से अपना {{project}} पासवर्ड रीसेट करें।",
|
||||
"emails.recovery.footer": "यदि आपने अपना पासवर्ड रीसेट करने के लिए नहीं कहा है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.recovery.thanks": "धन्यवाद",
|
||||
"emails.recovery.signature": "{{project}} टीम",
|
||||
"emails.invitation.subject": "%s टीम को %s पर आमंत्रण",
|
||||
"emails.invitation.hello": "नमस्ते",
|
||||
"emails.invitation.body": "यह मेल आपको इसलिए भेजा गया था क्योंकि {{owner}} आपको {{team}} टीम का सदस्य बनने के लिए आमंत्रित करना चाहते थे जो {{project}} से जुड़ा है।",
|
||||
"emails.invitation.footer": "यदि यह आपके लिए आवश्यक नहीं है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.invitation.thanks": "धन्यवाद",
|
||||
"emails.invitation.signature": "{{project}} टीम",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
"countries.af": "अफ़ग़ानिस्तान",
|
||||
"countries.ao": "अंगोला",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "उत्तरी अमेरिका",
|
||||
"continents.oc": "ओशिनिया",
|
||||
"continents.sa": "दक्षिण अमेरिका"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
232
app/config/locale/translations/hr.json
Normal file
232
app/config/locale/translations/hr.json
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"Umjetnost mudrosti je umjetnost znanja o tome što zanemariti.\"",
|
||||
"settings.locale": "hr",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Tim",
|
||||
"emails.verification.subject": "Verifikacija računa",
|
||||
"emails.verification.hello": "Pozdrav {{name}}",
|
||||
"emails.verification.body": "Slijedite ovu poveznicu da biste potvrdili svoju adresu e-pošte.",
|
||||
"emails.verification.footer": "Ukoliko niste zatražili potvrdu ove adrese, možete zanemariti ovu poruku.",
|
||||
"emails.verification.thanks": "Hvala",
|
||||
"emails.verification.signature": "{{project}} tim",
|
||||
"emails.magicSession.subject": "Prijavite se",
|
||||
"emails.magicSession.hello": "Pozdrav,",
|
||||
"emails.magicSession.body": "Slijedite ovu poveznicu za prijavu.",
|
||||
"emails.magicSession.footer": "Ako niste zatražili prijavu putem ove e-pošte, možete zanemariti ovu poruku.",
|
||||
"emails.magicSession.thanks": "Hvala",
|
||||
"emails.magicSession.signature": "{{project}} tim",
|
||||
"emails.recovery.subject": "Ponovno postavljanje lozinke",
|
||||
"emails.recovery.hello": "Pozdrav {{name}}",
|
||||
"emails.recovery.body": "Slijedite ovu poveznicu za ponovno postavljanje {{project}} lozinke.",
|
||||
"emails.recovery.footer": "Ako niste zatražili ponovno postavljanje Vaše lozinke, možete zanemariti ovu poruku.",
|
||||
"emails.recovery.thanks": "Hvala",
|
||||
"emails.recovery.signature": "{{project}} tim",
|
||||
"emails.invitation.subject": "Pozivnica za %s tim na %s",
|
||||
"emails.invitation.hello": "Pozdrav",
|
||||
"emails.invitation.body": "Ova poruka Vam je poslana jer Vas je {{owner}} htio pozvati da postanete član {{team}} tima na {{project}}.",
|
||||
"emails.invitation.footer": "Ukoliko niste zainteresirani, možete zanemariti ovu poruku.",
|
||||
"emails.invitation.thanks": "Hvala",
|
||||
"emails.invitation.signature": "{{project}} tim",
|
||||
"locale.country.unknown": "Nepoznato",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albanija",
|
||||
"countries.ad": "Andora",
|
||||
"countries.ae": "Ujedinjeni Arapski Emirati",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenija",
|
||||
"countries.ag": "Antigva i Barbuda",
|
||||
"countries.au": "Australija",
|
||||
"countries.at": "Austrija",
|
||||
"countries.az": "Azerbajdžan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgija",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladeš",
|
||||
"countries.bg": "Bugarska",
|
||||
"countries.bh": "Bahrein",
|
||||
"countries.bs": "Bahami",
|
||||
"countries.ba": "Bosna i Hercegovina",
|
||||
"countries.by": "Bjelorusija",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivija",
|
||||
"countries.br": "Brazil",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunej",
|
||||
"countries.bt": "Butan",
|
||||
"countries.bw": "Bocvana",
|
||||
"countries.cf": "Srednjoafrička Republika",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Švicarska",
|
||||
"countries.cl": "Čile",
|
||||
"countries.cn": "Kina",
|
||||
"countries.ci": "Obala bjelokosti",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "Demokratska Republika Kongo",
|
||||
"countries.cg": "Republika Kongo",
|
||||
"countries.co": "Kolumbija",
|
||||
"countries.km": "Komori",
|
||||
"countries.cv": "Zelenortska Republika",
|
||||
"countries.cr": "Kostarika",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cipar",
|
||||
"countries.cz": "Češka",
|
||||
"countries.de": "Njemačka",
|
||||
"countries.dj": "Džibuti",
|
||||
"countries.dm": "Dominika",
|
||||
"countries.dk": "Danska",
|
||||
"countries.do": "Dominikanska Republika",
|
||||
"countries.dz": "Alžir",
|
||||
"countries.ec": "Ekvador",
|
||||
"countries.eg": "Egipt",
|
||||
"countries.er": "Eritreja",
|
||||
"countries.es": "Španjolska",
|
||||
"countries.ee": "Estonija",
|
||||
"countries.et": "Etiopija",
|
||||
"countries.fi": "Finska",
|
||||
"countries.fj": "Fidži",
|
||||
"countries.fr": "Francuska",
|
||||
"countries.fm": "Mikronezija",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Ujedinjeno Kraljevstvo",
|
||||
"countries.ge": "Gruzija",
|
||||
"countries.gh": "Gana",
|
||||
"countries.gn": "Gvineja",
|
||||
"countries.gm": "Gambija",
|
||||
"countries.gw": "Gvineja Bisau",
|
||||
"countries.gq": "Ekvatorijalna Gvineja",
|
||||
"countries.gr": "Grčka",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Gvajana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Hrvatska",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Mađarska",
|
||||
"countries.id": "Indonezija",
|
||||
"countries.in": "Indija",
|
||||
"countries.ie": "Irska",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Izrael",
|
||||
"countries.it": "Italija",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kazahstan",
|
||||
"countries.ke": "Kenija",
|
||||
"countries.kg": "Kirgistan",
|
||||
"countries.kh": "Kambodža",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Sveti Kristofor i Nevis",
|
||||
"countries.kr": "Južna Koreja",
|
||||
"countries.kw": "Kuvajt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberija",
|
||||
"countries.ly": "Libija",
|
||||
"countries.lc": "Sveta Lucija",
|
||||
"countries.li": "Lihtenštajn",
|
||||
"countries.lk": "Šri Lanka",
|
||||
"countries.ls": "Lesoto",
|
||||
"countries.lt": "Litva",
|
||||
"countries.lu": "Luksemburg",
|
||||
"countries.lv": "Latvija",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monako",
|
||||
"countries.md": "Moldavija",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldivi",
|
||||
"countries.mx": "Meksiko",
|
||||
"countries.mh": "Maršalovi otoci",
|
||||
"countries.mk": "Sjeverna Makedonija",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Mijanmar",
|
||||
"countries.me": "Crna Gora",
|
||||
"countries.mn": "Mongolija",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauritanija",
|
||||
"countries.mu": "Mauricijus",
|
||||
"countries.mw": "Malavi",
|
||||
"countries.my": "Malezija",
|
||||
"countries.na": "Namibija",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigerija",
|
||||
"countries.ni": "Nikaragva",
|
||||
"countries.nl": "Nizozemska",
|
||||
"countries.no": "Norveška",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Novi Zeland",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipini",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Nova Guineja",
|
||||
"countries.pl": "Poljska",
|
||||
"countries.kp": "Sjeverna Koreja",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paragvaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunjska",
|
||||
"countries.ru": "Rusija",
|
||||
"countries.rw": "Ruanda",
|
||||
"countries.sa": "Saudijska Arabija",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Solomonski otoci",
|
||||
"countries.sl": "Sijera Leone",
|
||||
"countries.sv": "Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalija",
|
||||
"countries.rs": "Srbija",
|
||||
"countries.ss": "Južni Sudan",
|
||||
"countries.st": "Sveti Toma i Prinsipe",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovačka",
|
||||
"countries.si": "Slovenija",
|
||||
"countries.se": "Švedska",
|
||||
"countries.sz": "Esvatini",
|
||||
"countries.sc": "Sejšeli",
|
||||
"countries.sy": "Sirija",
|
||||
"countries.td": "Čad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Tajland",
|
||||
"countries.tj": "Tadžikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad i Tobago",
|
||||
"countries.tn": "Tunis",
|
||||
"countries.tr": "Turska",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzanija",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukrajina",
|
||||
"countries.uy": "Urugvaj",
|
||||
"countries.us": "Sjedinjene Američke Države",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatikan",
|
||||
"countries.vc": "Sveti Vincent i Grenadini",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vijetnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Južnoafrička Republika",
|
||||
"countries.zm": "Zambija",
|
||||
"countries.zw": "Zimbabve",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antartika",
|
||||
"continents.as": "Azija",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Sjeverna Amerika",
|
||||
"continents.oc": "Oceanija",
|
||||
"continents.sa": "Južna Amerika"
|
||||
}
|
||||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "id",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Tim %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verifikasi Akun",
|
||||
"emails.verification.hello": "Hai {{name}}",
|
||||
"emails.verification.body": "Ikuti tautan ini untuk memverifikasi alamat email Anda.",
|
||||
"emails.verification.footer": "Jika Anda tidak meminta untuk memverifikasi alamat email ini, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.verification.thanks": "Terima kasih",
|
||||
"emails.verification.signature": "Tim {{project}}",
|
||||
"emails.magicSession.subject": "Masuk",
|
||||
"emails.magicSession.hello": "Hai,",
|
||||
"emails.magicSession.body": "Ikuti tautan ini untuk masuk.",
|
||||
"emails.magicSession.footer": "Jika Anda tidak meminta untuk masuk menggunakan email ini, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.magicSession.thanks": "Terima kasih",
|
||||
"emails.magicSession.signature": "Tim {{project}}",
|
||||
"emails.recovery.subject": "Atur Ulang Kata Sandi",
|
||||
"emails.recovery.hello": "Halo {{name}}",
|
||||
"emails.recovery.body": "Ikuti tautan ini untuk menyetel ulang kata sandi {{project}} Anda.",
|
||||
"emails.recovery.footer": "Jika Anda tidak meminta untuk menyetel ulang kata sandi, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.recovery.thanks": "Terima kasih",
|
||||
"emails.recovery.signature": "Tim {{project}}",
|
||||
"emails.invitation.subject": "Undangan ke Tim %s di %s",
|
||||
"emails.invitation.hello": "Halo",
|
||||
"emails.invitation.body": "Email ini dikirimkan kepada Anda karena {{owner}} ingin mengundang Anda untuk menjadi anggota tim {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Jika Anda tidak tertarik, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.invitation.thanks": "Terima kasih",
|
||||
"emails.invitation.signature": "Tim {{project}}",
|
||||
"locale.country.unknown": "Tidak diketahui",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "it",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Team %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verifica account",
|
||||
"emails.verification.hello": "Ciao {{name}}",
|
||||
"emails.verification.body": "Clicca questo link per verificare il tuo indirizzo email.",
|
||||
"emails.verification.footer": "Se non sei stato tu a richiedere la verifica dell’indirizzo email, puoi ignorare questo messaggio.",
|
||||
"emails.verification.thanks": "Grazie",
|
||||
"emails.verification.signature": "Il team {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Ciao,",
|
||||
"emails.magicSession.body": "Clicca questo link per accedere.",
|
||||
"emails.magicSession.footer": "Se non sei stato tu a richiedere di effettuare l’accesso, puoi ignorare questo messaggio.",
|
||||
"emails.magicSession.thanks": "Grazie",
|
||||
"emails.magicSession.signature": "Il team {{project}}",
|
||||
"emails.recovery.subject": "Reimpostazione password",
|
||||
"emails.recovery.hello": "Ciao {{name}}",
|
||||
"emails.recovery.body": "Clicca questo link per reimpostare la tua password di {{project}}.",
|
||||
"emails.recovery.footer": "Se non sei stato tu a richiedere la reimpostazione della password, puoi ignorare questo messaggio.",
|
||||
"emails.recovery.thanks": "Grazie",
|
||||
"emails.recovery.signature": "Il team {{project}}",
|
||||
"emails.invitation.subject": "Invito al Team %s per %s",
|
||||
"emails.invitation.hello": "Ciao",
|
||||
"emails.invitation.body": "Ricevi questa email perché {{owner}} ti ha invitato a diventare un membro del team {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Ignora questo messaggio se non sei interessato.",
|
||||
"emails.invitation.thanks": "Grazie",
|
||||
"emails.invitation.signature": "Il team {{project}}",
|
||||
"locale.country.unknown": "Sconosciuto",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ka",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s ತಂಡ",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "ಖಾತೆ ಪರಿಶೀಲನೆ",
|
||||
"emails.verification.hello": "ನಮಸ್ಕಾರ {{name}}",
|
||||
"emails.verification.body": "ನಿಮ್ಮ ಇಮೇಲ್ ವಿಳಾಸ ಪರಿಶೀಲನೆಗೆ ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ",
|
||||
"emails.verification.footer": "ನೀವು ಇಮೇಲ್ ವಿಳಾಸ ಪರಿಶೀಲನೆಗೆ ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
|
||||
"emails.verification.thanks": "ಧನ್ಯವಾದಗಳು",
|
||||
"emails.verification.signature": "{{project}} ತಂಡ",
|
||||
"emails.magicSession.subject": "ಲಾಗಿನ್",
|
||||
"emails.magicSession.hello": "ನಮಸ್ಕಾರ,",
|
||||
"emails.magicSession.body": "ಲಾಗಿನ್ ಮಾಡಲಿಕ್ಕೆ ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ",
|
||||
"emails.magicSession.footer": "ನೀವು ಈ ಇಮೇಲನಿಂದ ಲಾಗಿನ್ ಮಾಡಲು ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
|
||||
"emails.magicSession.thanks": "ಧನ್ಯವಾದಗಳು",
|
||||
"emails.magicSession.signature": "{{project}} ತಂಡ",
|
||||
"emails.recovery.subject": "ಗುಪ್ತಪದ ಮರುಹೊಂದಿಸಿ",
|
||||
"emails.recovery.hello": "ನಮಸ್ಕಾರ {{name}}",
|
||||
"emails.recovery.body": "ನಿಮ್ಮ {{project}} ಗುಪ್ತಪದವನ್ನು ಮರುಹೊಂದಿಸಲು ಈ ಲಿಂಕನ್ನು ಅನುಸರಿಸಿ",
|
||||
"emails.recovery.footer": "ನೀವು ಗುಪ್ತಪದವನ್ನು ಮರುಹೊಂದಿಸಲು ಕೇಳದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
|
||||
"emails.recovery.thanks": "ಧನ್ಯವಾದಗಳು",
|
||||
"emails.recovery.signature": "{{project}} ತಂಡ",
|
||||
"emails.invitation.subject": "%s ತಂಡಕ್ಕೆ %s ರಲ್ಲಿ ಆಹ್ವಾನ",
|
||||
"emails.invitation.hello": "ನಮಸ್ಕಾರ",
|
||||
"emails.invitation.body": "ಈ ಇಮೇಲ್ ನಿಮಗೆ ಬಂದಿದೆ ಏಕೆಂದರೆ {{owner}} ನಿಮ್ಮನ್ನು {{team}} ತಂಡದ {{project}}ರಲ್ಲಿ ಸದಸ್ಯ ಆಗಲಿಕ್ಕೆ ಆಹ್ವಾನಿಸಿದ್ದಾರೆ",
|
||||
"emails.invitation.footer": "ನಿಮಗೆ ಆಸಕ್ತಿಯಿಲ್ಲದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
|
||||
"emails.invitation.thanks": "ಧನ್ಯವಾದಗಳು",
|
||||
"emails.invitation.signature": "{{project}} ತಂಡ",
|
||||
"locale.country.unknown": "Unknown",
|
||||
"countries.af": "ಅಫ್ಘಾನಿಸ್ತಾನ",
|
||||
"countries.ao": "ಅಂಗೋಲಾ",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ko",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s 팀",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "계정 인증",
|
||||
"emails.verification.hello": "안녕하세요 {{name}}님",
|
||||
"emails.verification.body": "이메일 인증을 위해 링크를 클릭하여주세요.",
|
||||
"emails.verification.footer": "이메일 인증을 부탁하지 않으셨다면 이 메시지를 무시하여주세요.",
|
||||
"emails.verification.thanks": "감사합니다",
|
||||
"emails.verification.signature": "{{project}} 팀",
|
||||
"emails.magicSession.subject": "로그인",
|
||||
"emails.magicSession.hello": "안녕하세요,",
|
||||
"emails.magicSession.body": "로그인 하시려면 링크를 클릭하여주세요.",
|
||||
"emails.magicSession.footer": "이 이메일 계정으로 로그인 신청을 하지 않으셨다면 이 메세지를 무시하여주세요.",
|
||||
"emails.magicSession.thanks": "감사합니다",
|
||||
"emails.magicSession.signature": "{{project}} 팀",
|
||||
"emails.recovery.subject": "비밀번호 재설정",
|
||||
"emails.recovery.hello": "안녕하세요 {{name}}님",
|
||||
"emails.recovery.body": "{{project}}의 비밀번호 재설정을 위해 링크를 클릭하여주세요.",
|
||||
"emails.recovery.footer": "비밀번호 재설정 신청을 하지 않으셨다면 이 메세지를 무시하여주세요.",
|
||||
"emails.recovery.thanks": "감사합니다",
|
||||
"emails.recovery.signature": "{{project}} 팀",
|
||||
"emails.invitation.subject": "초대장 %s 팀 - %s",
|
||||
"emails.invitation.hello": "안녕하세요",
|
||||
"emails.invitation.body": "{{owner}}님이 귀하를 {{project}}의 {{team}} 팀으로 초대합니다.",
|
||||
"emails.invitation.footer": "팀에 합류할 의사가 없으시면 이 메세지를 무시하여주세요.",
|
||||
"emails.invitation.thanks": "감사합니다",
|
||||
"emails.invitation.signature": "{{project}} 팀",
|
||||
"locale.country.unknown": "알려지지 않은",
|
||||
"countries.af": "아프가니스탄",
|
||||
"countries.ao": "앙골라",
|
||||
|
|
@ -57,7 +63,7 @@
|
|||
"countries.cn": "중국",
|
||||
"countries.ci": "코트디부아르",
|
||||
"countries.cm": "카메룬",
|
||||
"countries.cd": "콩고공화국의 행정",
|
||||
"countries.cd": "콩고 민주 공화국",
|
||||
"countries.cg": "콩고 공화국",
|
||||
"countries.co": "콜롬비아",
|
||||
"countries.km": "코모로",
|
||||
|
|
|
|||
232
app/config/locale/translations/lb.json
Normal file
232
app/config/locale/translations/lb.json
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.locale": "lb",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Kont Verifikatioun",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Follegt dëse Link fir Är E -Mail Adress z'iwwerpréiwen.",
|
||||
"emails.verification.footer": "Wann Dir net gefrot hutt dës Adress z'iwwerpréiwen, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.verification.thanks": "Merci",
|
||||
"emails.verification.signature": "{{project}} équipe",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Follegt dëse Link fir umellen.",
|
||||
"emails.magicSession.footer": "Wann Dir net gefrot hutt Iech mat dëser E -Mail anzemelden, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.magicSession.thanks": "Merci",
|
||||
"emails.magicSession.signature": "{{project}} équipe",
|
||||
"emails.recovery.subject": "Password Reset",
|
||||
"emails.recovery.hello": "Hello {{name}}",
|
||||
"emails.recovery.body": "Follegt dëse Link fir Äert {{project}} Passwuert zréckzesetzen.",
|
||||
"emails.recovery.footer": "Wann Dir net gefrot hutt Äert Passwuert zréckzesetzen, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.recovery.thanks": "Merci",
|
||||
"emails.recovery.signature": "{{project}} équipe",
|
||||
"emails.invitation.subject": "Invitatioun un %s équipe bei %s",
|
||||
"emails.invitation.hello": "Hallo",
|
||||
"emails.invitation.body": "Dës E -Mail gouf un Iech geschéckt well {{owner}} Iech invitéiere wëllt fir Member vum {{team}} Team bei {{project}} ze ginn.",
|
||||
"emails.invitation.footer": "Wann Dir net interesséiert sidd, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.invitation.thanks": "Merci",
|
||||
"emails.invitation.signature": "{{project}} équipe",
|
||||
"locale.country.unknown": "Onbekannt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albanien",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Vereenegt Arabesch Emirater",
|
||||
"countries.ar": "Argentinien",
|
||||
"countries.am": "Armenien",
|
||||
"countries.ag": "Antigua a Barbuda",
|
||||
"countries.au": "Australien",
|
||||
"countries.at": "Éisträich",
|
||||
"countries.az": "Aserbaidschan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belsch",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesch",
|
||||
"countries.bg": "Bulgarien",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnien an Herzegowina",
|
||||
"countries.by": "Wäissrussland",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivien",
|
||||
"countries.br": "Brasilien",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Zentralafrikanesch Republik",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Schwäiz",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "China",
|
||||
"countries.ci": "Côte d'Ivoire",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republik Kongo",
|
||||
"countries.co": "Kolumbien",
|
||||
"countries.km": "Komoren",
|
||||
"countries.cv": "Cap Vert",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Zypern",
|
||||
"countries.cz": "Tschechien",
|
||||
"countries.de": "Däitschland",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Dänemark",
|
||||
"countries.do": "Dominikanesch Republik",
|
||||
"countries.dz": "Algerien",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Ägypten",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spuenien",
|
||||
"countries.ee": "Estland",
|
||||
"countries.et": "Äthiopien",
|
||||
"countries.fi": "Finnland",
|
||||
"countries.fj": "Fidschi",
|
||||
"countries.fr": "Frankräich",
|
||||
"countries.fm": "Mikronesien",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Vereenegt Kinnekräich",
|
||||
"countries.ge": "Georgien",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Äquatorialguinea",
|
||||
"countries.gr": "Griichenland",
|
||||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haïti",
|
||||
"countries.hu": "Ungarn",
|
||||
"countries.id": "Indonesien",
|
||||
"countries.in": "Indien",
|
||||
"countries.ie": "Irland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italien",
|
||||
"countries.jm": "Jamaika",
|
||||
"countries.jo": "Jordanien",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kazakhstan",
|
||||
"countries.ke": "Kenia",
|
||||
"countries.kg": "Kirgisistan",
|
||||
"countries.kh": "Kambodscha",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts and Nevis",
|
||||
"countries.kr": "Südkorea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libyen",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litauen",
|
||||
"countries.lu": "Lëtzebuerg",
|
||||
"countries.lv": "Lettland",
|
||||
"countries.ma": "Marokko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldawien",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Malediven",
|
||||
"countries.mx": "Mexiko",
|
||||
"countries.mh": "Marshallinselen",
|
||||
"countries.mk": "Mazedonien",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongolei",
|
||||
"countries.mz": "Mosambik",
|
||||
"countries.mr": "Mauritanien",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysien",
|
||||
"countries.na": "Namibien",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Holland",
|
||||
"countries.no": "Norwegen",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Neiséiland",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Philippinnen",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua-Neuguinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nordkorea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Quatar",
|
||||
"countries.ro": "Rumänien",
|
||||
"countries.ru": "Russland",
|
||||
"countries.rw": "Ruanda",
|
||||
"countries.sa": "Saudi Arabien",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Solomon Inselen",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbien",
|
||||
"countries.ss": "Südsudan",
|
||||
"countries.st": "Sao Tome a Principe",
|
||||
"countries.sr": "Suriname",
|
||||
"countries.sk": "Slowakei",
|
||||
"countries.si": "Slowenien",
|
||||
"countries.se": "Schweden",
|
||||
"countries.sz": "Swasiland",
|
||||
"countries.sc": "Seychellen",
|
||||
"countries.sy": "Syrien",
|
||||
"countries.td": "Tschad",
|
||||
"countries.tg": "Goen",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tadjikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Tinidad an Tobago",
|
||||
"countries.tn": "Tunesien",
|
||||
"countries.tr": "Tierkei",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tansania",
|
||||
"countries.ug": "Ugana",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "Vereenegt Staaten",
|
||||
"countries.uz": "Usbekistan",
|
||||
"countries.va": "Vatikan Stad",
|
||||
"countries.vc": "Saint Vincent an d'Grenadinnen",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "Südafrika",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktis",
|
||||
"continents.as": "Asien",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Nordamerika",
|
||||
"continents.oc": "Ozeanien",
|
||||
"continents.sa": "Südamerika"
|
||||
}
|
||||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ml",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s ടീം",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "അക്കൗണ്ട് സ്ഥിരീകരണം",
|
||||
"emails.verification.hello": "നമസ്കാരം {{name}}",
|
||||
"emails.verification.body": "നിങ്ങളുടെ ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കുന്നതിനായി ഈ ലിങ്ക് പിന്തുടരുക.",
|
||||
"emails.verification.footer": "ഈ വിലാസം സ്ഥിരീകരിക്കാന് നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, നിങ്ങൾക്ക് ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
|
||||
"emails.verification.thanks": "നന്ദി",
|
||||
"emails.verification.signature": "{{project}} ടീം",
|
||||
"emails.magicSession.subject": "ലോഗിൻ",
|
||||
"emails.magicSession.hello": "നമസ്കാരം,",
|
||||
"emails.magicSession.body": "ലോഗിൻ ചെയ്യുന്നതിനായി ഈ ലിങ്ക് പിന്തുടരുക.",
|
||||
"emails.magicSession.footer": "ഈ ഇമെയിൽ ഉപയോഗിച്ച് ലോഗിൻ ചെയ്യാൻ നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
|
||||
"emails.magicSession.thanks": "നന്ദി",
|
||||
"emails.magicSession.signature": "{{project}} ടീം",
|
||||
"emails.recovery.subject": "രഹസ്യവാക്ക് പുനക്രമീകരണം",
|
||||
"emails.recovery.hello": "നമസ്കാരം {{name}}",
|
||||
"emails.recovery.body": "നിങ്ങളുടെ {{Project}} രഹസ്യവാക്ക് പുനക്രമീകരിക്കുന്നതിന് ഈ ലിങ്ക് പിന്തുടരുക.",
|
||||
"emails.recovery.footer": "നിങ്ങളുടെ പാസ്വേഡ് പുനക്രമീകരിക്കാന് നിങ്ങൾ ആവശ്യപ്പെട്ടില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
|
||||
"emails.recovery.thanks": "നന്ദി",
|
||||
"emails.recovery.signature": "{{project}} ടീം",
|
||||
"emails.invitation.subject": "%s -ലെ %s ടീമിലേക്കുള്ള ക്ഷണം",
|
||||
"emails.invitation.hello": "നമസ്കാരം",
|
||||
"emails.invitation.body": "നിങ്ങളെ {{project}} -ലെ {{team}} ടീമിലെ അംഗമാകുവാന് ക്ഷണിക്കാൻ {{owner}} ആഗ്രഹിക്കുതിനാലാണ് ഈ മെയിൽ നിങ്ങൾക്ക് അയക്കുന്നത്.",
|
||||
"emails.invitation.footer": "നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
|
||||
"emails.invitation.thanks": "നന്ദി",
|
||||
"emails.invitation.signature": "{{project}} ടീം",
|
||||
"locale.country.unknown": "Unknown",
|
||||
"countries.af": "അഫ്ഗാനിസ്ഥാൻ",
|
||||
"countries.ao": "അംഗോള",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ms",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Pengesahan Akaun",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Tekan pautan ini untuk mengesahkan alamat email anda.",
|
||||
"emails.verification.footer": "Sekiranya anda tidak membuat permintaan untuk mengesahkan email ini, sila abaikan mesej ini.",
|
||||
"emails.verification.thanks": "Terima kasih",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Log masuk",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Tekan pautan ini untuk log masuk.",
|
||||
"emails.magicSession.footer": "Sekiranya anda tidak membuat permintaan untuk log masuk menggunakan email ini, sila abaikan mesej ini.",
|
||||
"emails.magicSession.thanks": "Terima kasih",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Menetap semula Kata Laluan",
|
||||
"emails.recovery.hello": "Hello {{name}}",
|
||||
"emails.recovery.body": "Tekan pautan ini untuk menetapkan semula kata laluan {{project}}.",
|
||||
"emails.recovery.footer": "Sekiranya anda tidak membuat permintaan menetap semula kata laluan, sila abaikan mesej ini.",
|
||||
"emails.recovery.thanks": "Terima kasih",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Jemputan ke pasukan %s di %s",
|
||||
"emails.invitation.hello": "Hello",
|
||||
"emails.invitation.body": "Anda menerima mel ini kerana {{owner}} ingin menjemput anda untuk menjadi ahli pasukan {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Sekiranya anda tidak berminat, sila abaikan mesej ini.",
|
||||
"emails.invitation.thanks": "Terima kasih",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Tidak Diketahui",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,32 @@
|
|||
{
|
||||
"settings.inspire": "\"बुद्धिमान हुनु को कला के लाई बेवास्ता गर्न जान्ने को कला हो।\"",
|
||||
"settings.inspire": "\"के लाई बेवास्ता गर्ने भन्ने जान्नुनै बुद्धिमान हुनुको कला हो ।\"",
|
||||
"settings.locale": "ne",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s टीम",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.sender": "%s समूह",
|
||||
"emails.verification.subject": "खाता प्रमाणिकरण",
|
||||
"emails.verification.hello": "नमस्ते {{name}}",
|
||||
"emails.verification.body": "इमेल ठेगाना प्रमाणित गर्नको लागी यो लिंकमा जानुहोस।",
|
||||
"emails.verification.footer": "यदि तपाइँले आफ्नो खाता प्रमाणित गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।",
|
||||
"emails.verification.thanks": "धन्यवाद",
|
||||
"emails.verification.signature": "{{project}} समूह",
|
||||
"emails.magicSession.subject": "लगइन",
|
||||
"emails.magicSession.hello": "नमस्ते,",
|
||||
"emails.magicSession.body": "लगइन गर्नको लागी यो लिंकमा जानुहोस।",
|
||||
"emails.magicSession.footer": "यदि तपाइँले यो इमेल प्रयोग गरेर लगइन गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।",
|
||||
"emails.magicSession.thanks": "धन्यवाद",
|
||||
"emails.magicSession.signature": "{{project}} समूह",
|
||||
"emails.recovery.subject": "पासवर्ड रिसेट",
|
||||
"emails.recovery.hello": "नमस्ते {{name}}",
|
||||
"emails.recovery.body": "{{project}}को पासवर्ड रिसेट गर्नको लागी यो लिंकमा जानुहोस।",
|
||||
"emails.recovery.footer": "यदि तपाइँले आफ्नो पासवर्ड रिसेट गर्न सोध्नु भएको छैन भने तपाइँले यो सन्देश लाई बेवास्ता गर्न सक्नुहुन्छ।",
|
||||
"emails.recovery.thanks": "धन्यवाद",
|
||||
"emails.recovery.signature": "{{project}} समूह",
|
||||
"emails.invitation.subject": "%s समूहको लागि %s मा निमन्त्रणा",
|
||||
"emails.invitation.hello": "नमस्ते",
|
||||
"emails.invitation.body": "{{owner}}ले तपाइँलाई {{project}}मा {{team}}को सदस्य बन्न आमन्त्रित गर्न चाहनु भएको छ। त्येसैले तपाइँलाई यो सन्देश पठाइएको हो।",
|
||||
"emails.invitation.footer": "यदि तपाइँ इच्छुक हुनुहुन्न भने, तपाइँले यो सन्देशलाई बेवास्ता गर्न सक्नुहुन्छ।",
|
||||
"emails.invitation.thanks": "धन्यवाद",
|
||||
"emails.invitation.signature": "{{project}} समूह",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
"countries.af": "अफगानिस्तान",
|
||||
"countries.ao": "अंगोला",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "nl",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Account Verificatie",
|
||||
"emails.verification.hello": "Hoi {{name}}",
|
||||
"emails.verification.body": "Volg deze link om uw e-mail te verifieren",
|
||||
"emails.verification.footer": "Als u geen aanvraag voor verificatie heeft gemaakt, kan u deze mail negeren",
|
||||
"emails.verification.thanks": "Bedankt",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hoi,",
|
||||
"emails.magicSession.body": "Volg deze link om in te loggen",
|
||||
"emails.magicSession.footer": "Als u geen aanvraag heeft gemaakt om met deze mail in te loggen, kan u deze mail negeren",
|
||||
"emails.magicSession.thanks": "Bedankt",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Wachtwoord Herinstellen",
|
||||
"emails.recovery.hello": "Hallo {{name}}",
|
||||
"emails.recovery.body": "Volg deze link om het wachtwoord van uw project {{project}} te wijzigen",
|
||||
"emails.recovery.footer": "Als u geen aanvraag heeft gemaakt om uw wachtwoord te wijzigen, kan u deze mail negeren",
|
||||
"emails.recovery.thanks": "Bedankt",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Uitnodiging van %s Team uit %s",
|
||||
"emails.invitation.hello": "Hallo,",
|
||||
"emails.invitation.body": "U ontvangt deze mail want u was uitgenodig door {{owner}} om lid van het {{team}} team te worden in {{project}} ",
|
||||
"emails.invitation.footer": "Als u niet geintereseerd bent, kan u deze mail negeren.",
|
||||
"emails.invitation.thanks": "Bedankt",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Onbekend",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Noord Amerika",
|
||||
"continents.oc": "Oceanië",
|
||||
"continents.sa": "Zuid Amerika"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "no",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Kontobekreftelse",
|
||||
"emails.verification.hello": "Hallo {{name}}",
|
||||
"emails.verification.body": "Følg denne lenken for å bekrefte din e-post adresse.",
|
||||
"emails.verification.footer": "Dersom du ikke ba om å bekrefte e-post adressen, kan du se bort fra denne meldingen.",
|
||||
"emails.verification.thanks": "Takk",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Pålogging",
|
||||
"emails.magicSession.hello": "Hei,",
|
||||
"emails.magicSession.body": "Følg denne lenken for å logge på.",
|
||||
"emails.magicSession.footer": "Dersom du ikke ba om å logge på med denne e-post adressen, kan du se bort fra denne meldingen.",
|
||||
"emails.magicSession.thanks": "Takk",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Nullstille passord",
|
||||
"emails.recovery.hello": "Hallo {{name}}",
|
||||
"emails.recovery.body": "Følg denne lenken for å nullstille ditt {{project}} passord.",
|
||||
"emails.recovery.footer": "Dersom du ikke ba om å nullstille passordet ditt, kan du se bort fra denne meldingen.",
|
||||
"emails.recovery.thanks": "Takk",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitasjon til %s Team ved %s",
|
||||
"emails.invitation.hello": "Hallo",
|
||||
"emails.invitation.body": "Denne meldingen ble sent til deg fordi {{owner}} ønsket å invitere deg til å bli medlem av {{team}} team i {{project}}.",
|
||||
"emails.invitation.footer": "Dersom du ikke er interessert, kan du se bort fra denne meldingen.",
|
||||
"emails.invitation.thanks": "Takk",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Ukjent",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Nord-Amerika",
|
||||
"continents.oc": "Oseania",
|
||||
"continents.sa": "Sør-Amerika"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,34 @@
|
|||
{
|
||||
"settings.inspire": "\"ଜ୍ଞାନୀ ହେବାର କଳା ହେଉଛି କ’ଣ ଅଣଦେଖା କରାଯିବ ଜାଣିବାର କଳା |\"",
|
||||
"settings.inspire": "\"ବୁଦ୍ଧିମାନ ହେବାର କଳା ହେଉଛି କ’ଣ ଅଣଦେଖା କରାଯିବ ଜାଣିବାର କଳା |\"",
|
||||
"settings.locale": "or",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s ଟିମ",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.sender": "%s ଦଳ",
|
||||
"emails.verification.subject": "ଖାତା ଯାଞ୍ଚ",
|
||||
"emails.verification.hello": "ନମସ୍କାର {{name}}",
|
||||
"emails.verification.body": "ଆପଣଙ୍କର ଇମେଲ୍ ଠିକଣା ଯାଞ୍ଚ କରିବାକୁ ଏହି ଲିଙ୍କ୍ ଅନୁସରଣ କରନ୍ତୁ |",
|
||||
"emails.verification.footer": "ଯଦି ଆପଣ ଏହି ଠିକଣା ଯାଞ୍ଚ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |",
|
||||
"emails.verification.thanks": "ଧନ୍ୟବାଦ",
|
||||
"emails.verification.signature": "{{project}} ଦଳ",
|
||||
"emails.magicSession.subject": "ଲଗଇନ୍ କରନ୍ତୁ",
|
||||
"emails.magicSession.hello": "ନମସ୍କାର,",
|
||||
"emails.magicSession.body": "ଲଗଇନ୍ କରିବାକୁ ଏହି ଲିଙ୍କ୍ ଅନୁସରଣ କରନ୍ତୁ |",
|
||||
"emails.magicSession.footer": "ଯଦି ଆପଣ ଏହି ଇମେଲ୍ ବ୍ୟବହାର କରି ଲଗଇନ୍ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |",
|
||||
"emails.magicSession.thanks": "ଧନ୍ୟବାଦ",
|
||||
"emails.magicSession.signature": "{{project}} ଦଳ",
|
||||
"emails.recovery.subject": "ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରନ୍ତୁ |",
|
||||
"emails.recovery.hello": "ନମସ୍କାର {{name}}",
|
||||
"emails.recovery.body": "ଆପଣଙ୍କର {{project}} ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରିବାକୁ ଏହି ଲିଙ୍କକୁ ଅନୁସରଣ କରନ୍ତୁ |",
|
||||
"emails.recovery.footer": "ଯଦି ଆପଣ ଆପଣଙ୍କର ପାସୱାର୍ଡ ପୁନଃ ସେଟ୍ କରିବାକୁ କହି ନାହାଁନ୍ତି, ତେବେ ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଉପେକ୍ଷା କରିପାରିବେ |",
|
||||
"emails.recovery.thanks": "ଧନ୍ୟବାଦ",
|
||||
"emails.recovery.signature": "{{project}} ଦଳ",
|
||||
"emails.invitation.subject": "%s ରେ %s ଦଳକୁ ନିମନ୍ତ୍ରଣ |",
|
||||
"emails.invitation.hello": "ନମସ୍କାର",
|
||||
"emails.invitation.body": "ଏହି ମେଲ୍ ଆପଣଙ୍କୁ ପଠାଯାଇଥିଲା କାରଣ {{owner}} ଆପଣଙ୍କୁ {{project} ରେ {{team}} ଦଳର ସଦସ୍ୟ ହେବାକୁ ଆମନ୍ତ୍ରଣ କରିବାକୁ ଚାହୁଁଥିଲେ |",
|
||||
"emails.invitation.footer": "ଯଦି ଆପଣ ଆଗ୍ରହୀ ନୁହଁନ୍ତି, ଆପଣ ଏହି ସନ୍ଦେଶକୁ ଅଣଦେଖା କରିପାରିବେ |",
|
||||
"emails.invitation.thanks": "ଧନ୍ୟବାଦ",
|
||||
"emails.invitation.signature": "{{project}} ଦଳ",
|
||||
"locale.country.unknown": "ଅଜ୍ଞାତ",
|
||||
"countries.af": "ଅଫଘନିସ୍ତାନ",
|
||||
"countries.af": "ଆଫଗାନିସ୍ତାନ",
|
||||
"countries.ao": "ଅଙ୍ଗୋଲା",
|
||||
"countries.al": "ଆଲବେନିଆ",
|
||||
"countries.ad": "ଆଣ୍ଡୋରା",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -1,226 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"Sztuka bycia mądrym to sztuka wiedzieć, co przeoczyć.\"",
|
||||
"settings.locale": "pl",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Zespół %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"locale.country.unknown": "Nieznany",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andora",
|
||||
"countries.ae": "Zjednoczone Emiraty Arabskie",
|
||||
"countries.ar": "Argentyna",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua i Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbejdżan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgia",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesz",
|
||||
"countries.bg": "Bułgaria",
|
||||
"countries.bh": "Bahrajn",
|
||||
"countries.bs": "Bahamy",
|
||||
"countries.ba": "Bośnia i Hercegowina",
|
||||
"countries.by": "Białoruś",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Boliwia",
|
||||
"countries.br": "Brazylia",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Republika Środkowoafrykańska",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Szwajcaria",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Chiny",
|
||||
"countries.ci": "Wybrzeże Kości Słoniowej",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republika Konga",
|
||||
"countries.co": "Kolumbia",
|
||||
"countries.km": "Komory",
|
||||
"countries.cv": "Republika Zielonego Przylądka",
|
||||
"countries.cr": "Kostaryka",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cypr",
|
||||
"countries.cz": "Czechy",
|
||||
"countries.de": "Niemcy",
|
||||
"countries.dj": "Dżibuti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Dania",
|
||||
"countries.do": "Republika Dominikańska",
|
||||
"countries.dz": "Algieria",
|
||||
"countries.ec": "Ekwador",
|
||||
"countries.eg": "Egipt",
|
||||
"countries.er": "Erytrea",
|
||||
"countries.es": "Hiszpania",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Etiopia",
|
||||
"countries.fi": "Finlandia",
|
||||
"countries.fj": "Fidżi",
|
||||
"countries.fr": "Francja",
|
||||
"countries.fm": "Mikronezja",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Wielka Brytania",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Gwinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Gwinea Bissau",
|
||||
"countries.gq": "Gwinea Równikowa",
|
||||
"countries.gr": "Grecja",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gwatemala",
|
||||
"countries.gy": "Gujana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorwacja",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Węgry",
|
||||
"countries.id": "Indonezja",
|
||||
"countries.in": "Indie",
|
||||
"countries.ie": "Irlandia",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Islandia",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Włochy",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japonia",
|
||||
"countries.kz": "Kazachstan",
|
||||
"countries.ke": "Kenia",
|
||||
"countries.kg": "Kirgistan",
|
||||
"countries.kh": "Kambodża",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts i Nevis",
|
||||
"countries.kr": "Korea Południowa",
|
||||
"countries.kw": "Kuwejt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Liban",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litwa",
|
||||
"countries.lu": "Luksemburg",
|
||||
"countries.lv": "Łotwa",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Mołdawia",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Malediwy",
|
||||
"countries.mx": "Meksyk",
|
||||
"countries.mh": "Wyspy Marshalla",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Birma",
|
||||
"countries.me": "Czarnogóra",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauretania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malezja",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nikaragua",
|
||||
"countries.nl": "Holandia",
|
||||
"countries.no": "Norwegia",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Nowa Zelandia",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipiny",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Nowa Gwinea",
|
||||
"countries.pl": "Polska",
|
||||
"countries.kp": "Korea Północna",
|
||||
"countries.pt": "Portugalia",
|
||||
"countries.py": "Paragwaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunia",
|
||||
"countries.ru": "Rosja",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Arabia Saudyjska",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Wyspy Salomona",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "Salwador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "Sudan Południowy",
|
||||
"countries.st": "Wyspy Świętego Tomasza i Książęca",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Słowacja",
|
||||
"countries.si": "Słowenia",
|
||||
"countries.se": "Szwecja",
|
||||
"countries.sz": "Suazi",
|
||||
"countries.sc": "Seszele",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Czad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Tajlandia",
|
||||
"countries.tj": "Tadżykistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor Wschodni",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trynidad i Tobago",
|
||||
"countries.tn": "Tunezja",
|
||||
"countries.tr": "Turcja",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraina",
|
||||
"countries.uy": "Urugwaj",
|
||||
"countries.us": "Stany Zjednoczone",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Watykan",
|
||||
"countries.vc": "Saint Vincent i Grenadyny",
|
||||
"countries.ve": "Wenezuela",
|
||||
"countries.vn": "Wietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Republika Południowej Afryki",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afryka",
|
||||
"continents.an": "Antarktyda",
|
||||
"continents.as": "Azja",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Ameryka Północna",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "Ameryka południowa"
|
||||
}
|
||||
"settings.inspire": "\"Sztuka bycia mądrym to sztuka wiedzieć, co przeoczyć.\"",
|
||||
"settings.locale": "pl",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Zespół %s",
|
||||
"emails.verification.subject": "Weryfikacja konta",
|
||||
"emails.verification.hello": "Cześć {{name}}",
|
||||
"emails.verification.body": "Przejdź do tego linku, aby zweryfikować swój adres e-mail.",
|
||||
"emails.verification.footer": "Jeśli to nie Ty prosiłeś o zweryfikowanie tego adresu, możesz zignorować tę wiadomość.",
|
||||
"emails.verification.thanks": "Dziękujemy",
|
||||
"emails.verification.signature": "Zespół {{project}}",
|
||||
"emails.magicSession.subject": "Logowanie",
|
||||
"emails.magicSession.hello": "Cześć,",
|
||||
"emails.magicSession.body": "Przejdź do tego linku, aby zalogować się.",
|
||||
"emails.magicSession.footer": "Jeśli to nie Ty prosiłeś o logowanie przy użyciu tego adresu e-mail, możesz zignorować tę wiadomość.",
|
||||
"emails.magicSession.thanks": "Dziękujemy",
|
||||
"emails.magicSession.signature": "Zespół {{project}}",
|
||||
"emails.recovery.subject": "Resetowanie hasła",
|
||||
"emails.recovery.hello": "Cześć {{name}}",
|
||||
"emails.recovery.body": "Przejdź do tego linku, aby zresetować hasło dla {{project}}.",
|
||||
"emails.recovery.footer": "Jeśli to nie Ty prosiłeś o zresetowanie swojego hasła, możesz zignorować tę wiadomość.",
|
||||
"emails.recovery.thanks": "Dziękujemy",
|
||||
"emails.recovery.signature": "Zespół {{project}}",
|
||||
"emails.invitation.subject": "Zaproszenie do zespołu %s w %s",
|
||||
"emails.invitation.hello": "Cześć",
|
||||
"emails.invitation.body": "Otrzymujesz tę wiadomość, ponieważ {{owner}} zaprasza Cię do grona członków zespołu {{team}} w projekcie {{project}}.",
|
||||
"emails.invitation.footer": "Jeśli nie jesteś zainteresowany, możesz zignorować tę wiadomość.",
|
||||
"emails.invitation.thanks": "Dziękujemy",
|
||||
"emails.invitation.signature": "Zespół {{project}}",
|
||||
"locale.country.unknown": "Nieznany",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andora",
|
||||
"countries.ae": "Zjednoczone Emiraty Arabskie",
|
||||
"countries.ar": "Argentyna",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua i Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbejdżan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgia",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesz",
|
||||
"countries.bg": "Bułgaria",
|
||||
"countries.bh": "Bahrajn",
|
||||
"countries.bs": "Bahamy",
|
||||
"countries.ba": "Bośnia i Hercegowina",
|
||||
"countries.by": "Białoruś",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Boliwia",
|
||||
"countries.br": "Brazylia",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Republika Środkowoafrykańska",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Szwajcaria",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Chiny",
|
||||
"countries.ci": "Wybrzeże Kości Słoniowej",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republika Konga",
|
||||
"countries.co": "Kolumbia",
|
||||
"countries.km": "Komory",
|
||||
"countries.cv": "Republika Zielonego Przylądka",
|
||||
"countries.cr": "Kostaryka",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cypr",
|
||||
"countries.cz": "Czechy",
|
||||
"countries.de": "Niemcy",
|
||||
"countries.dj": "Dżibuti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Dania",
|
||||
"countries.do": "Republika Dominikańska",
|
||||
"countries.dz": "Algieria",
|
||||
"countries.ec": "Ekwador",
|
||||
"countries.eg": "Egipt",
|
||||
"countries.er": "Erytrea",
|
||||
"countries.es": "Hiszpania",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Etiopia",
|
||||
"countries.fi": "Finlandia",
|
||||
"countries.fj": "Fidżi",
|
||||
"countries.fr": "Francja",
|
||||
"countries.fm": "Mikronezja",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Wielka Brytania",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Gwinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Gwinea Bissau",
|
||||
"countries.gq": "Gwinea Równikowa",
|
||||
"countries.gr": "Grecja",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gwatemala",
|
||||
"countries.gy": "Gujana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorwacja",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Węgry",
|
||||
"countries.id": "Indonezja",
|
||||
"countries.in": "Indie",
|
||||
"countries.ie": "Irlandia",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Islandia",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Włochy",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japonia",
|
||||
"countries.kz": "Kazachstan",
|
||||
"countries.ke": "Kenia",
|
||||
"countries.kg": "Kirgistan",
|
||||
"countries.kh": "Kambodża",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts i Nevis",
|
||||
"countries.kr": "Korea Południowa",
|
||||
"countries.kw": "Kuwejt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Liban",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litwa",
|
||||
"countries.lu": "Luksemburg",
|
||||
"countries.lv": "Łotwa",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Mołdawia",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Malediwy",
|
||||
"countries.mx": "Meksyk",
|
||||
"countries.mh": "Wyspy Marshalla",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Birma",
|
||||
"countries.me": "Czarnogóra",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauretania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malezja",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nikaragua",
|
||||
"countries.nl": "Holandia",
|
||||
"countries.no": "Norwegia",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Nowa Zelandia",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipiny",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Nowa Gwinea",
|
||||
"countries.pl": "Polska",
|
||||
"countries.kp": "Korea Północna",
|
||||
"countries.pt": "Portugalia",
|
||||
"countries.py": "Paragwaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunia",
|
||||
"countries.ru": "Rosja",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Arabia Saudyjska",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Wyspy Salomona",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "Salwador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "Sudan Południowy",
|
||||
"countries.st": "Wyspy Świętego Tomasza i Książęca",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Słowacja",
|
||||
"countries.si": "Słowenia",
|
||||
"countries.se": "Szwecja",
|
||||
"countries.sz": "Suazi",
|
||||
"countries.sc": "Seszele",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Czad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Tajlandia",
|
||||
"countries.tj": "Tadżykistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor Wschodni",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trynidad i Tobago",
|
||||
"countries.tn": "Tunezja",
|
||||
"countries.tr": "Turcja",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraina",
|
||||
"countries.uy": "Urugwaj",
|
||||
"countries.us": "Stany Zjednoczone",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Watykan",
|
||||
"countries.vc": "Saint Vincent i Grenadyny",
|
||||
"countries.ve": "Wenezuela",
|
||||
"countries.vn": "Wietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Republika Południowej Afryki",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afryka",
|
||||
"continents.an": "Antarktyda",
|
||||
"continents.as": "Azja",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Ameryka Północna",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "Ameryka południowa"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "pt-br",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Time %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verificação da Conta",
|
||||
"emails.verification.hello": "Olá {{name}}",
|
||||
"emails.verification.body": "Clique neste link para verificar o seu endereço de e-mail.",
|
||||
"emails.verification.footer": "Se não você que solicitou essa verificação deste e-mail, você pode ignorar essa mensagem",
|
||||
"emails.verification.thanks": "Muito obrigado",
|
||||
"emails.verification.signature": "Time {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Olá,",
|
||||
"emails.magicSession.body": "Clique neste link para entrar",
|
||||
"emails.magicSession.footer": "Se não você que solicitou essa verificação deste e-mail, você pode ignorar essa mensagem",
|
||||
"emails.magicSession.thanks": "Muito obrigado",
|
||||
"emails.magicSession.signature": "Time {{project}}",
|
||||
"emails.recovery.subject": "Redefinação de senha",
|
||||
"emails.recovery.hello": "Olá {{name}}",
|
||||
"emails.recovery.body": "Clique neste link para redefinir sua senha do {{project}}.",
|
||||
"emails.recovery.footer": "Se você não solicitou a redefinição da sua senha, você pode ignorar essa mensagem",
|
||||
"emails.recovery.thanks": "Muito obrigado",
|
||||
"emails.recovery.signature": "Time {{project}}",
|
||||
"emails.invitation.subject": "Convite para o Time %s em %s",
|
||||
"emails.invitation.hello": "Olá",
|
||||
"emails.invitation.body": "Este email foi enviado porque o {{owner}} deseja convidar você a se tornar membro do Time {{team}} em {{project}}.",
|
||||
"emails.invitation.footer": "Se você não está interessado, você pode ignorar essa mensagem",
|
||||
"emails.invitation.thanks": "Muito obrigado",
|
||||
"emails.invitation.signature": "Time {{project}}",
|
||||
"locale.country.unknown": "Desconhecido",
|
||||
"countries.af": "Afeganistão",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "pt-pt",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Equipa %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verificação de contas",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Siga esta ligação para verificar o seu endereço de correio electrónico.",
|
||||
"emails.verification.footer": "Se não pediu para verificar este endereço, pode ignorar esta mensagem.",
|
||||
"emails.verification.thanks": "Obrigado",
|
||||
"emails.verification.signature": "Equipa {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Olá ,",
|
||||
"emails.magicSession.body": "Siga esta ligação para iniciar sessão.",
|
||||
"emails.magicSession.footer": "Se não pediu para entrar usando este e-mail, pode ignorar esta mensagem.",
|
||||
"emails.magicSession.thanks": "Obrigado",
|
||||
"emails.magicSession.signature": "Equipa {{project}}",
|
||||
"emails.recovery.subject": "Redefinição de senha",
|
||||
"emails.recovery.hello": "Olá {{name}}",
|
||||
"emails.recovery.body": "tilize este link para redefinir a palavra-passe do seu projecto {{project}}",
|
||||
"emails.recovery.footer": "Se não pediu para redefinir a sua palavra-passe, pode ignorar esta mensagem.",
|
||||
"emails.recovery.thanks": "Obrigado",
|
||||
"emails.recovery.signature": "Equipa {{project}}",
|
||||
"emails.invitation.subject": "Convite à equipa de %s às %s",
|
||||
"emails.invitation.hello": "Olá",
|
||||
"emails.invitation.body": "Este correio foi-lhe enviado porque {{owner}} queria convidá-lo a tornar-se membro da equipa {{team}} da {{project}}.",
|
||||
"emails.invitation.footer": "Se não estiver interessado, pode ignorar esta mensagem.",
|
||||
"emails.invitation.thanks": "Obrigado",
|
||||
"emails.invitation.signature": "Equipa {{project}}",
|
||||
"locale.country.unknown": "Desconhecido",
|
||||
"countries.af": "Afeganistão",
|
||||
"countries.ao": "Angola",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "América do Norte",
|
||||
"continents.oc": "Oceânia",
|
||||
"continents.sa": "América do Sul"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ro",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Echipa",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verificare cont",
|
||||
"emails.verification.hello": "Bună ziua, {{name}}",
|
||||
"emails.verification.body": "Click pe acest link pentru a valida adresa de email.",
|
||||
"emails.verification.footer": "Dacă nu ai cerut validarea adresei de email, poți ignora acest mesaj.",
|
||||
"emails.verification.thanks": "Mulțumim",
|
||||
"emails.verification.signature": "Echipa {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Bună ziua,",
|
||||
"emails.magicSession.body": "Urmează acest link pentru logare.",
|
||||
"emails.magicSession.footer": "Dacă nu ai incercat să te loghezi folosing această adresa de email, poți ignora acest mesaj.",
|
||||
"emails.magicSession.thanks": "Mulțumim",
|
||||
"emails.magicSession.signature": "Echipa {{project}}",
|
||||
"emails.recovery.subject": "Resetare parolă",
|
||||
"emails.recovery.hello": "Bună ziua, {{name}}",
|
||||
"emails.recovery.body": "Click aici pentru a reseta parola pentru {{project}}",
|
||||
"emails.recovery.footer": "Dacă nu ai cerut să îți schimbi parola, ignoră acest mesaj.",
|
||||
"emails.recovery.thanks": "Mulțumim",
|
||||
"emails.recovery.signature": "Echipa {{project}}",
|
||||
"emails.invitation.subject": "Invitatie catre %s Echipa la %s",
|
||||
"emails.invitation.hello": "Bună ziua",
|
||||
"emails.invitation.body": "Acest email a fost trimis pentru că {{owner}} a vrut ca tu să devii membru al echipei {{team}} la {{project}}.",
|
||||
"emails.invitation.footer": "Dacă nu esti interesat, poți ignora acest email.",
|
||||
"emails.invitation.thanks": "Mulțumim",
|
||||
"emails.invitation.signature": "Echipa {{project}}",
|
||||
"locale.country.unknown": "Necunoscut",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "ru",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Команда %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Верификация аккаунта",
|
||||
"emails.verification.hello": "Здравствуйте, {{name}}",
|
||||
"emails.verification.body": "Перейдите по ссылке, чтобы подтвердить свой адрес электронной почты.",
|
||||
"emails.verification.footer": "Если вы не запрашивали подтверждение этого адреса, проигнорируйте это сообщение.",
|
||||
"emails.verification.thanks": "Спасибо",
|
||||
"emails.verification.signature": "команда {{project}}",
|
||||
"emails.magicSession.subject": "Логин",
|
||||
"emails.magicSession.hello": "Здравствуйте,",
|
||||
"emails.magicSession.body": "Перейдите по ссылке, чтобы войти.",
|
||||
"emails.magicSession.footer": "Если вы не просили войти, используя этот адрес электронной почты, проигнорируйте это сообщение.",
|
||||
"emails.magicSession.thanks": "Спасибо",
|
||||
"emails.magicSession.signature": "команда {{project}}",
|
||||
"emails.recovery.subject": "Сброс пароля",
|
||||
"emails.recovery.hello": "Здравствуйте, {{name}}",
|
||||
"emails.recovery.body": "Перейдите по этой ссылке для того чтобы сбросить свой пароль для проекта {{project}}",
|
||||
"emails.recovery.footer": "Если вы не запрашивали сброс пароля, проигнорируйте это сообщение.",
|
||||
"emails.recovery.thanks": "Спасибо",
|
||||
"emails.recovery.signature": "команда {{project}}",
|
||||
"emails.invitation.subject": "Приглашение в команду %s по проекту %s",
|
||||
"emails.invitation.hello": "Здравствуйте",
|
||||
"emails.invitation.body": "Это письмо отправлено вам, потому что {{owner}} приглашает стать членом команды {{team}} в проекте {{project}}.",
|
||||
"emails.invitation.footer": "Если вы не заинтересованы, проигнорируйте это сообщение.",
|
||||
"emails.invitation.thanks": "Спасибо",
|
||||
"emails.invitation.signature": "команда {{project}}",
|
||||
"locale.country.unknown": "Неизвестно",
|
||||
"countries.af": "Афганистан",
|
||||
"countries.ao": "Ангола",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Северная Америка",
|
||||
"continents.oc": "Океания",
|
||||
"continents.sa": "Южная Америка"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
232
app/config/locale/translations/sa.json
Normal file
232
app/config/locale/translations/sa.json
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"किं हेयमित्यस्य ज्ञानमेव ज्ञानिलक्षणम्।\"",
|
||||
"settings.locale": "sa",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s गणः",
|
||||
"emails.verification.subject": "पञ्जिकानिर्णायनम्",
|
||||
"emails.verification.hello": "अयि {{name}}",
|
||||
"emails.verification.body": "ई-पत्रनिर्णायनार्थमिदं संयोगसूत्रमनुसरतु।",
|
||||
"emails.verification.footer": "यदि अस्य संकेतस्य निर्णायनं नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्।",
|
||||
"emails.verification.thanks": "धन्यवादः",
|
||||
"emails.verification.signature": "{{project}} गणः",
|
||||
"emails.magicSession.subject": "संप्रवेशः",
|
||||
"emails.magicSession.hello": "अयि,",
|
||||
"emails.magicSession.body": "संप्रवेशार्थमिदं संयोगसूत्रमनुसरतु।",
|
||||
"emails.magicSession.footer": "अनेन ई-पत्रण यदि संप्रवेशो नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्।",
|
||||
"emails.magicSession.thanks": "धन्यवादः",
|
||||
"emails.magicSession.signature": "{{project}} गणः",
|
||||
"emails.recovery.subject": "कूटशब्दपुनयाेजनम्",
|
||||
"emails.recovery.hello": "अयि भो {{name}}",
|
||||
"emails.recovery.body": "{{project}} कूटशब्दपुनयाेजनाय संयोगमेनमनुसरतु।",
|
||||
"emails.recovery.footer": "यदि कूटशब्दस्य पुनयाेजनं नेष्यते तर्हि वात्र्तामिमामुपेक्षताम्।",
|
||||
"emails.recovery.thanks": "धन्यवादः",
|
||||
"emails.recovery.signature": "{{project}} गणः",
|
||||
"emails.invitation.subject": "गणस्य आमन्त्रणम् %s इति %s",
|
||||
"emails.invitation.hello": "अयि भो",
|
||||
"emails.invitation.body": "{{owner}} {{team}} गणे {{project}} मध्ये भवद्योगदानमच्छितीति हेतोः पत्रमदिं भवत्सकाशं प्रेषतिम्।",
|
||||
"emails.invitation.footer": "यदि भवदनिच्छा तर्हि वात्र्तामिमामुपेक्षताम्।",
|
||||
"emails.invitation.thanks": "धन्यवादः",
|
||||
"emails.invitation.signature": "{{project}} गणः",
|
||||
"locale.country.unknown": "अज्ञातम् ",
|
||||
"countries.af": "आफगानिस्थानम्",
|
||||
"countries.ao": "आङ्गोला",
|
||||
"countries.al": "आलबनिआ",
|
||||
"countries.ad": "आण्डोरा",
|
||||
"countries.ae": "संयुक्त आरब गणराज्यम्",
|
||||
"countries.ar": "अर्जेंटीना",
|
||||
"countries.am": "अर्मेनिआ",
|
||||
"countries.ag": "आण्टिगुआ बर्वुदा च",
|
||||
"countries.au": "अष्ट्रेलिआ",
|
||||
"countries.at": "अष्ट्रिआ",
|
||||
"countries.az": "आज़रबाइजान्",
|
||||
"countries.bi": "बुरुन्दि",
|
||||
"countries.be": "बेल्जिअम्",
|
||||
"countries.bj": "बेनिन्",
|
||||
"countries.bf": "बुर्किना फाशो",
|
||||
"countries.bd": "बाङ्गलादेशः",
|
||||
"countries.bg": "बुल्गेरिआ",
|
||||
"countries.bh": "बाहारिन्",
|
||||
"countries.bs": "बाहामस्",
|
||||
"countries.ba": "बोसिनिआ हर्जेगोविन च",
|
||||
"countries.by": "बेलारुष्",
|
||||
"countries.bz": "बेलिज",
|
||||
"countries.bo": "बोलिभिआ",
|
||||
"countries.br": "ब्राजिल",
|
||||
"countries.bb": "बर्बादोस्",
|
||||
"countries.bn": "ब्रुनेइ",
|
||||
"countries.bt": "भुटान्",
|
||||
"countries.bw": "बोटस्वान",
|
||||
"countries.cf": "केन्द्रिय आफ़्रीका गणराज्यम्",
|
||||
"countries.ca": "कनाडा",
|
||||
"countries.ch": "स्विट्ज़रलैंड",
|
||||
"countries.cl": "चिली",
|
||||
"countries.cn": "चीन",
|
||||
"countries.ci": "आइभोरि कोष्ट",
|
||||
"countries.cm": "कामेरुन्",
|
||||
"countries.cd": "कांगो लोकतांत्रिक गणराज्यम्",
|
||||
"countries.cg": "कोलंबिया",
|
||||
"countries.co": "कोलंबिया",
|
||||
"countries.km": "कोमोरोस",
|
||||
"countries.cv": "केप् वर्दे",
|
||||
"countries.cr": "कोष्टारिका",
|
||||
"countries.cu": "क्युवा",
|
||||
"countries.cy": "साइप्रस्",
|
||||
"countries.cz": "चेकिया",
|
||||
"countries.de": "जर्मनी",
|
||||
"countries.dj": "जिबूती",
|
||||
"countries.dm": "डोमिनिका",
|
||||
"countries.dk": "डेनमार्क",
|
||||
"countries.do": "डोमिनिका गणराज्यम्",
|
||||
"countries.dz": "एलजीरिया",
|
||||
"countries.ec": "इक्वेडोर",
|
||||
"countries.eg": "मिस्र",
|
||||
"countries.er": "एरिट्रिआ",
|
||||
"countries.es": "स्पेन्",
|
||||
"countries.ee": "एस्तोनिया",
|
||||
"countries.et": "इथिओपिआ",
|
||||
"countries.fi": "फिनलैंड",
|
||||
"countries.fj": "फ़िजी",
|
||||
"countries.fr": "फ्रांस",
|
||||
"countries.fm": "माइक्रोनेशिया",
|
||||
"countries.ga": "गैबॉन",
|
||||
"countries.gb": "संयुक्त राज्यम्",
|
||||
"countries.ge": "जॉर्जिया",
|
||||
"countries.gh": "घाना",
|
||||
"countries.gn": "गिन्नी",
|
||||
"countries.gm": "गाम्बिया",
|
||||
"countries.gw": "गिनी-बिसाऊ",
|
||||
"countries.gq": "भूमध्यवर्ती गिनी",
|
||||
"countries.gr": "ग्रीस्",
|
||||
"countries.gd": "ग्रेनेडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गुयाना",
|
||||
"countries.hn": "होंडुरस्",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
"countries.hu": "हङ्गेरी",
|
||||
"countries.id": "इंडोनेशिया",
|
||||
"countries.in": "भारत",
|
||||
"countries.ie": "आयरलैंड",
|
||||
"countries.ir": "ईरान",
|
||||
"countries.iq": "इराक",
|
||||
"countries.is": "आइसलैंड",
|
||||
"countries.il": "इजराइल",
|
||||
"countries.it": "इटली",
|
||||
"countries.jm": "जमैका",
|
||||
"countries.jo": "जॉर्डन",
|
||||
"countries.jp": "जापान",
|
||||
"countries.kz": "कजाखस्तान",
|
||||
"countries.ke": "केन्या",
|
||||
"countries.kg": "किर्गिज़स्तान",
|
||||
"countries.kh": "कंबोडिया",
|
||||
"countries.ki": "किरिबाती",
|
||||
"countries.kn": "सेंट किट्ट्स नेविस च",
|
||||
"countries.kr": "दक्षिण कोरिया",
|
||||
"countries.kw": "कुवैट",
|
||||
"countries.la": "लाओस",
|
||||
"countries.lb": "लेबनान्",
|
||||
"countries.lr": "लाइबेरिया",
|
||||
"countries.ly": "लीबिया",
|
||||
"countries.lc": "सेंट लूसिया",
|
||||
"countries.li": "लिकटेंस्टाइन्",
|
||||
"countries.lk": "श्री लंका",
|
||||
"countries.ls": "लिसोटो",
|
||||
"countries.lt": "लिथुआनिया",
|
||||
"countries.lu": "लक्समबर्ग",
|
||||
"countries.lv": "लातविया",
|
||||
"countries.ma": "मोरक्को",
|
||||
"countries.mc": "मोनाको",
|
||||
"countries.md": "मोलदोवा",
|
||||
"countries.mg": "मेडागास्कर",
|
||||
"countries.mv": "मालद्वीप",
|
||||
"countries.mx": "मेक्सिको",
|
||||
"countries.mh": "मार्शल द्वीप समूह",
|
||||
"countries.mk": "मैसेडोनिया",
|
||||
"countries.ml": "माली",
|
||||
"countries.mt": "माल्टा",
|
||||
"countries.mm": "म्यांमार",
|
||||
"countries.me": "मोंटेनेग्रो",
|
||||
"countries.mn": "मंगोलिया",
|
||||
"countries.mz": "मोजाम्बिक्",
|
||||
"countries.mr": "मॉरिटानिया",
|
||||
"countries.mu": "मॉरीशस्",
|
||||
"countries.mw": "मलावी",
|
||||
"countries.my": "मलेशिया",
|
||||
"countries.na": "नामीबिया",
|
||||
"countries.ne": "नाइजर्",
|
||||
"countries.ng": "नाइजीरिया",
|
||||
"countries.ni": "निकारागुआ",
|
||||
"countries.nl": "नीदरलैंड",
|
||||
"countries.no": "नॉर्वे",
|
||||
"countries.np": "नेपाल",
|
||||
"countries.nr": "नाउरू",
|
||||
"countries.nz": "न्यूजीलैंड",
|
||||
"countries.om": "ओमान",
|
||||
"countries.pk": "पाकिस्तान",
|
||||
"countries.pa": "पनामा",
|
||||
"countries.pe": "पेरू",
|
||||
"countries.ph": "फिलीपींस",
|
||||
"countries.pw": "पलाउ",
|
||||
"countries.pg": "पापुआ न्यू गिनी",
|
||||
"countries.pl": "पोलैंड",
|
||||
"countries.kp": "उत्तर कोरिया",
|
||||
"countries.pt": "पुर्तगाल",
|
||||
"countries.py": "परागुआ",
|
||||
"countries.qa": "कतर",
|
||||
"countries.ro": "रोमानिया",
|
||||
"countries.ru": "रूस्",
|
||||
"countries.rw": "रुआण्डा",
|
||||
"countries.sa": "सऊदी अरब",
|
||||
"countries.sd": "सूडान",
|
||||
"countries.sn": "सेनेगल",
|
||||
"countries.sg": "सिंगापुर",
|
||||
"countries.sb": "सोलोमन द्वीप",
|
||||
"countries.sl": "सियरा लिओन",
|
||||
"countries.sv": "अल साल्वाडोर",
|
||||
"countries.sm": "सैन् मैरीनो",
|
||||
"countries.so": "सोमालिया",
|
||||
"countries.rs": "सर्बिया",
|
||||
"countries.ss": "दक्षिण सूडान",
|
||||
"countries.st": "साओ टोमे प्रिंसिपे च",
|
||||
"countries.sr": "सूरीनाम",
|
||||
"countries.sk": "स्लोवाकिया",
|
||||
"countries.si": "स्लोवेनिया",
|
||||
"countries.se": "स्विडेन",
|
||||
"countries.sz": "स्वाजीलैंड",
|
||||
"countries.sc": "सेशेल्स",
|
||||
"countries.sy": "सीरिया",
|
||||
"countries.td": "चाड़",
|
||||
"countries.tg": "टोगो",
|
||||
"countries.th": "थाईलैंड",
|
||||
"countries.tj": "तजाकिस्तान",
|
||||
"countries.tm": "तुर्कमेनिस्तान",
|
||||
"countries.tl": "तिमोर-लेस्ते",
|
||||
"countries.to": "टोंगा",
|
||||
"countries.tt": "त्रिनिदाद टोबैगो च",
|
||||
"countries.tn": "ट्यूनीशिया",
|
||||
"countries.tr": "तुर्की",
|
||||
"countries.tv": "तुवालु",
|
||||
"countries.tz": "तंजानिया",
|
||||
"countries.ug": "युगांडा",
|
||||
"countries.ua": "यूक्रेन",
|
||||
"countries.uy": "उरुग्वे",
|
||||
"countries.us": "संयुक्तराष्ट्रम्",
|
||||
"countries.uz": "उज़्बेकिस्तान",
|
||||
"countries.va": "वेटिकन सिटी",
|
||||
"countries.vc": "सेंट विंसेंट ग्रेनडीनेस च",
|
||||
"countries.ve": "वेनेजुएला",
|
||||
"countries.vn": "वियतनाम",
|
||||
"countries.vu": "वानुअतु",
|
||||
"countries.ws": "समोआ",
|
||||
"countries.ye": "यमन",
|
||||
"countries.za": "दक्षिण अफ्रीका",
|
||||
"countries.zm": "जाम्बिया",
|
||||
"countries.zw": "जिम्बाब्वे",
|
||||
"continents.af": "अफ्रीका",
|
||||
"continents.an": "अंटार्कटिका",
|
||||
"continents.as": "एशिया",
|
||||
"continents.eu": "यूरोप",
|
||||
"continents.na": "उत्तरी अमेरिका",
|
||||
"continents.oc": "ओशिनिया",
|
||||
"continents.sa": "दक्षिण अमेरिका"
|
||||
}
|
||||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
232
app/config/locale/translations/sk.json
Normal file
232
app/config/locale/translations/sk.json
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"settings.inspire": "\"Umenie múdrosti je umenie vedieť, čo prehliadnuť.\"",
|
||||
"settings.locale": "sk",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Tím",
|
||||
"emails.verification.subject": "Overenie účtu",
|
||||
"emails.verification.hello": "Ahoj {{name}}",
|
||||
"emails.verification.body": "Použi tento link pre overenie svojej emailovej adresy.",
|
||||
"emails.verification.footer": "Ak si nepožiadal o overenie tejto adresy, môžeš túto správu ignorovať.",
|
||||
"emails.verification.thanks": "Ďakujeme.",
|
||||
"emails.verification.signature": "{{project}} tím",
|
||||
"emails.magicSession.subject": "Prihlásenie",
|
||||
"emails.magicSession.hello": "Ahoj,",
|
||||
"emails.magicSession.body": "Použi tento link pre prihlásenie.",
|
||||
"emails.magicSession.footer": "Ak si nepožiadal o prihlásenie cez email, túto správu môžeš ignorovať.",
|
||||
"emails.magicSession.thanks": "Ďakujeme",
|
||||
"emails.magicSession.signature": "{{project}} tím",
|
||||
"emails.recovery.subject": "Obnovenie hesla",
|
||||
"emails.recovery.hello": "Ahoj {{name}}",
|
||||
"emails.recovery.body": "Použi tento link pre obnovenie svojho {{project}} hesla.",
|
||||
"emails.recovery.footer": "Ak si nepožiadal o obnovu svojho hesla, túto správu môžeš ignorovať.",
|
||||
"emails.recovery.thanks": "Ďakujeme",
|
||||
"emails.recovery.signature": "{{project}} tím",
|
||||
"emails.invitation.subject": "Pozvánka do %s Tímu v %s",
|
||||
"emails.invitation.hello": "Ahoj",
|
||||
"emails.invitation.body": "Tento email ti bol zaslaný, pretože {{owner}} ťa pozval, aby si sa stal členom {{team}} tímu v projekte {{project}}.",
|
||||
"emails.invitation.footer": "Ak nemáš záujem, môžeš túto správu ignorovať.",
|
||||
"emails.invitation.thanks": "Ďakujeme",
|
||||
"emails.invitation.signature": "{{project}} tím",
|
||||
"locale.country.unknown": "Neznámy",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albánsko",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Spojené arabské emiráty",
|
||||
"countries.ar": "Argentína",
|
||||
"countries.am": "Arménsko",
|
||||
"countries.ag": "Antigua a Barbuda",
|
||||
"countries.au": "Austrália",
|
||||
"countries.at": "Rakúsko",
|
||||
"countries.az": "Azerbajdžan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgicko",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladéš",
|
||||
"countries.bg": "Bulharsko",
|
||||
"countries.bh": "Bahrajn",
|
||||
"countries.bs": "Bahamy",
|
||||
"countries.ba": "Bosnia and Herzegovina",
|
||||
"countries.by": "Bielorusko",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolívia",
|
||||
"countries.br": "Brazília",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunej",
|
||||
"countries.bt": "Bhután",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Stredoafrická republika",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Švajčiarsko",
|
||||
"countries.cl": "Čile",
|
||||
"countries.cn": "Čína",
|
||||
"countries.ci": "Pobrežie Slonoviny",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "Konžská demokratická republika",
|
||||
"countries.cg": "Kongo",
|
||||
"countries.co": "Kolumbia",
|
||||
"countries.km": "Komory",
|
||||
"countries.cv": "Kapverdy",
|
||||
"countries.cr": "Kostarika",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cyprus",
|
||||
"countries.cz": "Česko",
|
||||
"countries.de": "Nemecko",
|
||||
"countries.dj": "Džibutsko",
|
||||
"countries.dm": "Dominika",
|
||||
"countries.dk": "Denmark",
|
||||
"countries.do": "Dominikánska republika",
|
||||
"countries.dz": "Alžírsko",
|
||||
"countries.ec": "Ekvádor",
|
||||
"countries.eg": "Egypt",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Španielsko",
|
||||
"countries.ee": "Estónsko",
|
||||
"countries.et": "Etiópia",
|
||||
"countries.fi": "Fínsko",
|
||||
"countries.fj": "Fidži",
|
||||
"countries.fr": "Francúzsko",
|
||||
"countries.fm": "Mikronézia",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Spojené kráľovstvo",
|
||||
"countries.ge": "Gruzínsko",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Rovníková Guinea",
|
||||
"countries.gr": "Grécko",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorvátsko",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Maďarsko",
|
||||
"countries.id": "Indonézia",
|
||||
"countries.in": "India",
|
||||
"countries.ie": "Írsko",
|
||||
"countries.ir": "Irán",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Izrael",
|
||||
"countries.it": "Taliansko",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordánsko",
|
||||
"countries.jp": "Japonsko",
|
||||
"countries.kz": "Kazachstan",
|
||||
"countries.ke": "Keňa",
|
||||
"countries.kg": "Kirgizsko",
|
||||
"countries.kh": "Kambodža",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Svätý Krištof a Nevis",
|
||||
"countries.kr": "Južná Kórea",
|
||||
"countries.kw": "Kuvajt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Libéria",
|
||||
"countries.ly": "Líbya",
|
||||
"countries.lc": "Svätá Lucia",
|
||||
"countries.li": "Lichtenštajnsko",
|
||||
"countries.lk": "Srí Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litva",
|
||||
"countries.lu": "Luxembursko",
|
||||
"countries.lv": "Lotyšsko",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monako",
|
||||
"countries.md": "Moldavsko",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldivy",
|
||||
"countries.mx": "Mexiko",
|
||||
"countries.mh": "Marshall Islands",
|
||||
"countries.mk": "Macedónsko",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Mjanmarsko",
|
||||
"countries.me": "Čierna Hora",
|
||||
"countries.mn": "Monglosko",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauritánia",
|
||||
"countries.mu": "Maurícius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malajzia",
|
||||
"countries.na": "Namíbia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigéria",
|
||||
"countries.ni": "Nikaragua",
|
||||
"countries.nl": "Holandsko",
|
||||
"countries.no": "Nórsko",
|
||||
"countries.np": "Nepál",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Nový Zéland",
|
||||
"countries.om": "Omán",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipíny",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua-Nová Guinea",
|
||||
"countries.pl": "Poľsko",
|
||||
"countries.kp": "Severná Kórea",
|
||||
"countries.pt": "Portugalsko",
|
||||
"countries.py": "Paraguaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunsko",
|
||||
"countries.ru": "Rusko",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudská Arábia",
|
||||
"countries.sd": "Sudán",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Šalamúnove ostrovy",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "Salvádor",
|
||||
"countries.sm": "San Maríno",
|
||||
"countries.so": "Somálsko",
|
||||
"countries.rs": "Srbsko",
|
||||
"countries.ss": "Južný Sudán",
|
||||
"countries.st": "Svätý Tomáš a Princov ostrov",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovensko",
|
||||
"countries.si": "Slovinsko",
|
||||
"countries.se": "Švédsko",
|
||||
"countries.sz": "Svazijsko",
|
||||
"countries.sc": "Seychely",
|
||||
"countries.sy": "Sýria",
|
||||
"countries.td": "Čad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thajsko",
|
||||
"countries.tj": "Tadžikistan",
|
||||
"countries.tm": "Turkménsko",
|
||||
"countries.tl": "Východný Timor",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad a Tobago",
|
||||
"countries.tn": "Tunisko",
|
||||
"countries.tr": "Turecko",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzánia",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukrajna",
|
||||
"countries.uy": "Uruguaj",
|
||||
"countries.us": "Spojené štáty",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatikán",
|
||||
"countries.vc": "Svätý Vincent a Grenadíny",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Južná Afrika",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktída",
|
||||
"continents.as": "Ázia",
|
||||
"continents.eu": "Európa",
|
||||
"continents.na": "Severná Amerika",
|
||||
"continents.oc": "Oceánia",
|
||||
"continents.sa": "Južná Amerika"
|
||||
}
|
||||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "sv",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s-teamet",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verifiera konto",
|
||||
"emails.verification.hello": "Hej {{name}}",
|
||||
"emails.verification.body": "Klicka på denna länk för att verifiera din email",
|
||||
"emails.verification.footer": "Om du inte bad om att verifiera den här e-postadressen kan du ignorera detta mail.",
|
||||
"emails.verification.thanks": "Tack",
|
||||
"emails.verification.signature": "{{project}} teamet",
|
||||
"emails.magicSession.subject": "Logga in",
|
||||
"emails.magicSession.hello": "Hej,",
|
||||
"emails.magicSession.body": "Klicka på denna länk för att logga in.",
|
||||
"emails.magicSession.footer": "Om du inte bad om att logga in med denna e-postadress kan du ignorera detta mail.",
|
||||
"emails.magicSession.thanks": "Tack",
|
||||
"emails.magicSession.signature": "{{project}} teamet",
|
||||
"emails.recovery.subject": "Återställ lösenord",
|
||||
"emails.recovery.hello": "Hej {{name}}",
|
||||
"emails.recovery.body": "Klicka på denna länk för att återställa lösenordet på {{project}}",
|
||||
"emails.recovery.footer": "Om du inte bad om att återställa ditt lösenord kan du ignorera detta mail.",
|
||||
"emails.recovery.thanks": "Tack",
|
||||
"emails.recovery.signature": "{{project}} teamet",
|
||||
"emails.invitation.subject": "Inbjudan till %s teamet på %s",
|
||||
"emails.invitation.hello": "Hej",
|
||||
"emails.invitation.body": "Detta mail skickades till dig eftersom {{owner}} ville bjuda in dig att bli medlem i teamet {{team}} på {{project}}.",
|
||||
"emails.invitation.footer": "Om du inte är intresserad kan du ignorera detta mail.",
|
||||
"emails.invitation.thanks": "Tack",
|
||||
"emails.invitation.signature": "{{project}} teamet",
|
||||
"locale.country.unknown": "Okänt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,32 @@
|
|||
{
|
||||
"settings.inspire": "\"ศิลปะแห่งความฉลาดคือศิลปะแห่งการรู้ว่าจะมองข้ามอะไร\"",
|
||||
"settings.inspire": "\"ศิลปะของการมีปัญญา คือการตระหนักได้ว่าควรจะมองข้ามเรื่องอะไร\"",
|
||||
"settings.locale": "th",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s ทีม",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.sender": "ทีม %s",
|
||||
"emails.verification.subject": "การยืนยันบัญชีผู้ใช้",
|
||||
"emails.verification.hello": "เรียนคุณ {{name}}",
|
||||
"emails.verification.body": "กดเข้าไปที่ลิงก์นี้เพื่อยืนยันอีเมลของท่าน",
|
||||
"emails.verification.footer": "หากท่านไม่ได้ต้องการที่จะยืนยันอีเมลนี้ ท่านสามารถเพิกเฉยข้อความนี้ได้",
|
||||
"emails.verification.thanks": "ขอบคุณ",
|
||||
"emails.verification.signature": "ทีม {{project}}",
|
||||
"emails.magicSession.subject": "เข้าสู่ระบบ",
|
||||
"emails.magicSession.hello": "เรียนผู้ใช้งาน,",
|
||||
"emails.magicSession.body": "กดเข้าไปที่ลิงก์นี้เพื่อเข้าสู่ระบบ",
|
||||
"emails.magicSession.footer": "หากท่านไม่ได้ต้องการที่จะเข้าสู่ระบบด้วยอีเมลนี้ ท่านสามารถเพิกเฉยข้อความนี้ได้",
|
||||
"emails.magicSession.thanks": "ขอบคุณ",
|
||||
"emails.magicSession.signature": "ทีม {{project}}",
|
||||
"emails.recovery.subject": "รีเซ็ตรหัสผ่าน",
|
||||
"emails.recovery.hello": "เรียนคุณ {{name}}",
|
||||
"emails.recovery.body": "กดเข้าไปที่ลิงก์นี้เพื่อรีเซ็ตรหัสผ่านสำหรับโปรเจกต์ {{project}} ของท่าน",
|
||||
"emails.recovery.footer": "หากท่านไม่ได้ต้องการที่จะรีเซ็ตรหัสผ่านของท่าน ท่านสามารถเพิกเฉยข้อความนี้ได้",
|
||||
"emails.recovery.thanks": "ขอบคุณ",
|
||||
"emails.recovery.signature": "ทีม {{project}}",
|
||||
"emails.invitation.subject": "เรียนเชิญเข้าร่วม ทีม %s จากโปรเจกต์ %s",
|
||||
"emails.invitation.hello": "สวัสดี",
|
||||
"emails.invitation.body": "ท่านได้รับอีเมลฉบับนี้เนื่องจาก {{owner}} ต้องการที่จะเชิญชวนคุณเข้าร่วมเป็นส่วนหนึ่งของ ทีม {{team}} จากโปรเจกต์ {{project}}",
|
||||
"emails.invitation.footer": "หากท่านไม่ได้สนใจที่จะเข้าร่วม ท่านสามารถเพิกเฉยข้อความนี้ได้",
|
||||
"emails.invitation.thanks": "ขอบคุณ",
|
||||
"emails.invitation.signature": "ทีม {{project}}",
|
||||
"locale.country.unknown": "ไม่ทราบ",
|
||||
"countries.af": "อัฟกานิสถาน",
|
||||
"countries.ao": "แองโกลา",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,32 @@
|
|||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"Мистецтво бути мудрим - це мистецтво знати, чим можна знехтувати\"",
|
||||
"settings.locale": "uk",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Команда %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Верифікація акаунта",
|
||||
"emails.verification.hello": "Вітаємо, {{name}}",
|
||||
"emails.verification.body": "Перейдіть за цим посиланням, щоб підтвердити свою електронну адресу.",
|
||||
"emails.verification.footer": "Якщо ви не запитували підтвердження цієї адреси, ви можете ігнорувати це повідомлення.",
|
||||
"emails.verification.thanks": "Дякуємо",
|
||||
"emails.verification.signature": "команда {{project}}",
|
||||
"emails.magicSession.subject": "Логін",
|
||||
"emails.magicSession.hello": "Вітаємо,",
|
||||
"emails.magicSession.body": "Перейдіть за цим посиланням, щоб увійти.",
|
||||
"emails.magicSession.footer": "Якщо ви не просили увійти за допомогою цієї електронної пошти, ви можете ігнорувати це повідомлення.",
|
||||
"emails.magicSession.thanks": "Дякуємо",
|
||||
"emails.magicSession.signature": "команда {{project}}",
|
||||
"emails.recovery.subject": "Скидання пароля",
|
||||
"emails.recovery.hello": "Вітаємо, {{name}}",
|
||||
"emails.recovery.body": "Перейдіть за цим посиланням для того щоб скинути свій пароль для проекту {{project}}",
|
||||
"emails.recovery.footer": "Якщо ви не запитували скидання паролю, проігноруйте це повідомлення.",
|
||||
"emails.recovery.thanks": "Дякуємо",
|
||||
"emails.recovery.signature": "команда {{project}}",
|
||||
"emails.invitation.subject": "Запрошення до %s Команди у %s",
|
||||
"emails.invitation.hello": "Вітаємо",
|
||||
"emails.invitation.body": "Цей лист був надісланий вам тому що {{owner}} запрошує вас стати членом команди {{team}} у проекті {{project}}.",
|
||||
"emails.invitation.footer": "Якщо ви не зацікавлені, проігноруйте це повідомлення.",
|
||||
"emails.invitation.thanks": "Дякуємо",
|
||||
"emails.invitation.signature": "команда {{project}}",
|
||||
"locale.country.unknown": "Невідомо",
|
||||
"countries.af": "Афганістан",
|
||||
"countries.ao": "Ангола",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "Північна Америка",
|
||||
"continents.oc": "Океанія",
|
||||
"continents.sa": "Південна Америка"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -3,24 +3,30 @@
|
|||
"settings.locale": "zh",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s 小组",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "帐户验证",
|
||||
"emails.verification.hello": "你好 {{name}}",
|
||||
"emails.verification.body": "点此链接验证您的电子邮件地址。",
|
||||
"emails.verification.footer": "如果您没有要求验证此地址,则可忽略此消息。",
|
||||
"emails.verification.thanks": "谢谢",
|
||||
"emails.verification.signature": "{{project}} 团队",
|
||||
"emails.magicSession.subject": "登录",
|
||||
"emails.magicSession.hello": "你好,",
|
||||
"emails.magicSession.body": "点此链接登录。",
|
||||
"emails.magicSession.footer": "如果您没有要求使用此电子邮件登录,则可忽略此消息。",
|
||||
"emails.magicSession.thanks": "谢谢",
|
||||
"emails.magicSession.signature": "{{project}} 团队",
|
||||
"emails.recovery.subject": "重设密码",
|
||||
"emails.recovery.hello": "你好 {{name}}",
|
||||
"emails.recovery.body": "点此链接重置您的 {{project}} 密码。",
|
||||
"emails.recovery.footer": "如果您没有要求重置密码,则可以忽略此消息。",
|
||||
"emails.recovery.thanks": "谢谢",
|
||||
"emails.recovery.signature": "{{project}} 团队",
|
||||
"emails.invitation.subject": "邀请 %s 团队在 %s",
|
||||
"emails.invitation.hello": "你好",
|
||||
"emails.invitation.body": "这封邮件发送给您是因为 {{owner}} 想邀请您成为 {{team}} 团队在 {{project}}.",
|
||||
"emails.invitation.footer": "如果您不感兴趣,可以忽略此消息。",
|
||||
"emails.invitation.thanks": "谢谢",
|
||||
"emails.invitation.signature": "{{project}} 团队",
|
||||
"locale.country.unknown": "未知",
|
||||
"countries.af": "阿富汗",
|
||||
"countries.ao": "安哥拉",
|
||||
|
|
@ -223,4 +229,4 @@
|
|||
"continents.na": "北美洲",
|
||||
"continents.oc": "大洋洲",
|
||||
"continents.sa": "南美洲"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ return [
|
|||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '3.2.0',
|
||||
'version' => '4.0.3',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -62,11 +62,11 @@ return [
|
|||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '0.7.1',
|
||||
'version' => '2.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'beta' => false,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
|
|
@ -111,7 +111,7 @@ return [
|
|||
[
|
||||
'key' => 'android',
|
||||
'name' => 'Android',
|
||||
'version' => '0.0.1',
|
||||
'version' => '0.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-android',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android',
|
||||
'enabled' => true,
|
||||
|
|
@ -156,7 +156,7 @@ return [
|
|||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Console',
|
||||
'version' => '2.1.0',
|
||||
'version' => '4.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-console',
|
||||
'package' => '',
|
||||
'enabled' => true,
|
||||
|
|
@ -183,7 +183,7 @@ return [
|
|||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '2.4.0',
|
||||
'version' => '2.5.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -200,7 +200,7 @@ return [
|
|||
[
|
||||
'key' => 'deno',
|
||||
'name' => 'Deno',
|
||||
'version' => '0.3.0',
|
||||
'version' => '0.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-deno',
|
||||
'package' => 'https://deno.land/x/appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -217,7 +217,7 @@ return [
|
|||
[
|
||||
'key' => 'php',
|
||||
'name' => 'PHP',
|
||||
'version' => '2.2.0',
|
||||
'version' => '2.3.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-php',
|
||||
'package' => 'https://packagist.org/packages/appwrite/appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -234,7 +234,7 @@ return [
|
|||
[
|
||||
'key' => 'python',
|
||||
'name' => 'Python',
|
||||
'version' => '0.4.0',
|
||||
'version' => '0.5.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-python',
|
||||
'package' => 'https://pypi.org/project/appwrite/',
|
||||
'enabled' => true,
|
||||
|
|
@ -251,7 +251,7 @@ return [
|
|||
[
|
||||
'key' => 'ruby',
|
||||
'name' => 'Ruby',
|
||||
'version' => '2.3.0',
|
||||
'version' => '2.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-ruby',
|
||||
'package' => 'https://rubygems.org/gems/appwrite',
|
||||
'enabled' => true,
|
||||
|
|
@ -319,11 +319,11 @@ return [
|
|||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '0.7.0',
|
||||
'version' => '1.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'beta' => false,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
|
|
@ -336,7 +336,7 @@ return [
|
|||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '0.11.0',
|
||||
'version' => '0.12.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'enabled' => true,
|
||||
|
|
@ -353,7 +353,7 @@ return [
|
|||
[
|
||||
'key' => 'kotlin',
|
||||
'name' => 'Kotlin',
|
||||
'version' => '0.0.1',
|
||||
'version' => '0.1.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
|
||||
'enabled' => true,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ return [
|
|||
'key' => 'homepage',
|
||||
'name' => 'Homepage',
|
||||
'subtitle' => '',
|
||||
'description' => '',
|
||||
'controller' => 'web/home.php',
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
|
|
@ -16,6 +17,8 @@ return [
|
|||
'console' => [
|
||||
'key' => 'console',
|
||||
'name' => 'Console',
|
||||
'subtitle' => '',
|
||||
'description' => '',
|
||||
'controller' => 'web/console.php',
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
|
|
@ -93,6 +96,7 @@ return [
|
|||
'key' => 'projects',
|
||||
'name' => 'Projects',
|
||||
'subtitle' => 'The Project service allows you to manage all the projects in your Appwrite server.',
|
||||
'description' => '',
|
||||
'controller' => 'api/projects.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
app/config/specs/0.11.x.client.json
Normal file
1
app/config/specs/0.11.x.client.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/0.11.x.console.json
Normal file
1
app/config/specs/0.11.x.console.json
Normal file
File diff suppressed because one or more lines are too long
1
app/config/specs/0.11.x.server.json
Normal file
1
app/config/specs/0.11.x.server.json
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -471,6 +471,33 @@ return [
|
|||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => 'DOCKERHUB_PULL_USERNAME',
|
||||
'description' => 'The username for hub.docker.com. This variable is used to pull images from hub.docker.com.',
|
||||
'introduction' => '0.10.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => 'DOCKERHUB_PULL_PASSWORD',
|
||||
'description' => 'The password for hub.docker.com. This variable is used to pull images from hub.docker.com.',
|
||||
'introduction' => '0.10.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => 'DOCKERHUB_PULL_EMAIL',
|
||||
'description' => 'The email for hub.docker.com. This variable is used to pull images from hub.docker.com.',
|
||||
'introduction' => '0.10.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
],
|
||||
[
|
||||
'category' => 'Maintenance',
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ use Utopia\Validator\Assoc;
|
|||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
$oauthDefaultSuccess = App::getEnv('_APP_HOME') . '/auth/oauth2/success';
|
||||
$oauthDefaultFailure = App::getEnv('_APP_HOME') . '/auth/oauth2/failure';
|
||||
$oauthDefaultSuccess = '/v1/auth/oauth2/success';
|
||||
$oauthDefaultFailure = '/v1/auth/oauth2/failure';
|
||||
|
||||
App::post('/v1/account')
|
||||
->desc('Create Account')
|
||||
|
|
@ -78,7 +78,9 @@ App::post('/v1/account')
|
|||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if ($limit !== 0) {
|
||||
$sum = $dbForInternal->count('users', [], APP_LIMIT_USERS);
|
||||
$sum = $dbForInternal->count('users', [
|
||||
new Query('deleted', Query::TYPE_EQUAL, [false]),
|
||||
], APP_LIMIT_USERS);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
|
|
@ -105,6 +107,8 @@ App::post('/v1/account')
|
|||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
'memberships' => [],
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'deleted' => false
|
||||
]));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
|
|
@ -165,7 +169,7 @@ App::post('/v1/account/sessions')
|
|||
$email = \strtolower($email);
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
$profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
|
||||
if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) {
|
||||
$audits
|
||||
|
|
@ -202,8 +206,8 @@ App::post('/v1/account/sessions')
|
|||
Authorization::setRole('user:' . $profile->getId());
|
||||
|
||||
$session = $dbForInternal->createDocument('sessions', $session
|
||||
->setAttribute('$read', ['user:' . $profile->getId()])
|
||||
->setAttribute('$write', ['user:' . $profile->getId()])
|
||||
->setAttribute('$read', ['user:' . $profile->getId()])
|
||||
->setAttribute('$write', ['user:' . $profile->getId()])
|
||||
);
|
||||
|
||||
$profile->setAttribute('sessions', $session, Document::SET_TYPE_APPEND);
|
||||
|
|
@ -256,14 +260,14 @@ App::get('/v1/account/sessions/oauth2/:provider')
|
|||
->label('sdk.methodType', 'webAuth')
|
||||
->label('abuse-limit', 50)
|
||||
->label('abuse-key', 'ip:{ip}')
|
||||
->param('provider', '', new WhiteList(\array_keys(Config::getParam('providers')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('providers'), function ($node) {return (!$node['mock']);}))) . '.')
|
||||
->param('success', $oauthDefaultSuccess, function ($clients) {return new Host($clients);}, 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients'])
|
||||
->param('failure', $oauthDefaultFailure, function ($clients) {return new Host($clients);}, 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients'])
|
||||
->param('provider', '', new WhiteList(\array_keys(Config::getParam('providers')), true), 'OAuth2 Provider. Currently, supported providers are: ' . \implode(', ', \array_keys(\array_filter(Config::getParam('providers'), function($node) {return (!$node['mock']);}))).'.')
|
||||
->param('success', '', function ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients'])
|
||||
->param('failure', '', function ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients'])
|
||||
->param('scopes', [], new ArrayList(new Text(128)), 'A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes.', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->action(function ($provider, $success, $failure, $scopes, $request, $response, $project) {
|
||||
->action(function ($provider, $success, $failure, $scopes, $request, $response, $project) use ($oauthDefaultSuccess, $oauthDefaultFailure) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
|
|
@ -288,6 +292,14 @@ App::get('/v1/account/sessions/oauth2/:provider')
|
|||
throw new Exception('Provider is not supported', 501);
|
||||
}
|
||||
|
||||
if(empty($success)) {
|
||||
$success = $protocol . '://' . $request->getHostname() . $oauthDefaultSuccess;
|
||||
}
|
||||
|
||||
if(empty($failure)) {
|
||||
$failure = $protocol . '://' . $request->getHostname() . $oauthDefaultFailure;
|
||||
}
|
||||
|
||||
$oauth2 = new $className($appId, $appSecret, $callback, ['success' => $success, 'failure' => $failure], $scopes);
|
||||
|
||||
$response
|
||||
|
|
@ -462,13 +474,13 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$name = $oauth2->getUserName($accessToken);
|
||||
$email = $oauth2->getUserEmail($accessToken);
|
||||
|
||||
$user = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
$user = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
|
||||
if ($user === false || $user->isEmpty()) { // Last option -> create the user, generate random password
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if ($limit !== 0) {
|
||||
$sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT);
|
||||
$sum = $dbForInternal->count('users', [ new Query('deleted', Query::TYPE_EQUAL, [false]),], APP_LIMIT_COUNT);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
|
|
@ -495,6 +507,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
'memberships' => [],
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'deleted' => false
|
||||
]));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
|
|
@ -544,8 +558,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
Authorization::setRole('user:' . $user->getId());
|
||||
|
||||
$session = $dbForInternal->createDocument('sessions', $session
|
||||
->setAttribute('$read', ['user:' . $user->getId()])
|
||||
->setAttribute('$write', ['user:' . $user->getId()])
|
||||
->setAttribute('$read', ['user:' . $user->getId()])
|
||||
->setAttribute('$write', ['user:' . $user->getId()])
|
||||
);
|
||||
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
|
|
@ -571,7 +585,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
}
|
||||
|
||||
// Add keys for non-web platforms - TODO - add verification phase to aviod session sniffing
|
||||
if (parse_url($state['success'], PHP_URL_PATH) === parse_url($oauthDefaultSuccess, PHP_URL_PATH)) {
|
||||
if (parse_url($state['success'], PHP_URL_PATH) === $oauthDefaultSuccess) {
|
||||
$state['success'] = URLParser::parse($state['success']);
|
||||
$query = URLParser::parseQuery($state['success']['query']);
|
||||
$query['project'] = $project->getId();
|
||||
|
|
@ -591,6 +605,281 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
;
|
||||
});
|
||||
|
||||
|
||||
App::post('/v1/account/sessions/magic-url')
|
||||
->desc('Create Magic URL session')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'public')
|
||||
->label('auth.type', 'magic-url')
|
||||
->label('sdk.auth', [])
|
||||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'createMagicURLSession')
|
||||
->label('sdk.description', '/docs/references/account/create-magic-url-session.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_TOKEN)
|
||||
->label('abuse-limit', 10)
|
||||
->label('abuse-key', 'url:{url},email:{param-email}')
|
||||
->param('userId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('email', '', new Email(), 'User email.')
|
||||
->param('url', '', function ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients'])
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForInternal')
|
||||
->inject('locale')
|
||||
->inject('audits')
|
||||
->inject('events')
|
||||
->inject('mails')
|
||||
->action(function ($userId, $email, $url, $request, $response, $project, $dbForInternal, $locale, $audits, $events, $mails) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
$user = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]);
|
||||
|
||||
if (!$user) {
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if ($limit !== 0) {
|
||||
$sum = $dbForInternal->count('users', [
|
||||
new Query('deleted', Query::TYPE_EQUAL, [false]),
|
||||
], APP_LIMIT_COUNT);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
}
|
||||
}
|
||||
|
||||
$userId = $userId == 'unique()' ? $dbForInternal->getId() : $userId;
|
||||
|
||||
$user = Authorization::skip(function () use ($dbForInternal, $userId, $email) {
|
||||
return $dbForInternal->createDocument('users', new Document([
|
||||
'$id' => $userId,
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['user:' . $userId],
|
||||
'email' => $email,
|
||||
'emailVerification' => false,
|
||||
'status' => true,
|
||||
'password' => null,
|
||||
'passwordUpdate' => \time(),
|
||||
'registration' => \time(),
|
||||
'reset' => false,
|
||||
'prefs' => [],
|
||||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
'memberships' => [],
|
||||
'search' => implode(' ', [$userId, $email]),
|
||||
'deleted' => false
|
||||
]));
|
||||
});
|
||||
|
||||
$mails->setParam('event', 'users.create');
|
||||
$audits->setParam('event', 'users.create');
|
||||
}
|
||||
|
||||
$loginSecret = Auth::tokenGenerator();
|
||||
|
||||
$expire = \time() + Auth::TOKEN_EXPIRATION_CONFIRM;
|
||||
|
||||
$token = new Document([
|
||||
'$id' => $dbForInternal->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'type' => Auth::TOKEN_TYPE_MAGIC_URL,
|
||||
'secret' => Auth::hash($loginSecret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
'ip' => $request->getIP(),
|
||||
]);
|
||||
|
||||
Authorization::setRole('user:'.$user->getId());
|
||||
|
||||
$user->setAttribute('tokens', $token, Document::SET_TYPE_APPEND);
|
||||
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed to save user to DB', 500);
|
||||
}
|
||||
|
||||
if(empty($url)) {
|
||||
$url = $request->getProtocol().'://'.$request->getHostname().'/auth/magic-url';
|
||||
}
|
||||
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $loginSecret, 'expire' => $expire, 'project' => $project->getId()]);
|
||||
$url = Template::unParseURL($url);
|
||||
|
||||
$mails
|
||||
->setParam('from', $project->getId())
|
||||
->setParam('recipient', $user->getAttribute('email'))
|
||||
->setParam('url', $url)
|
||||
->setParam('locale', $locale->default)
|
||||
->setParam('project', $project->getAttribute('name', ['[APP-NAME]']))
|
||||
->setParam('type', MAIL_TYPE_MAGIC_SESSION)
|
||||
->trigger()
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData',
|
||||
$response->output($token->setAttribute('secret', $loginSecret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
;
|
||||
|
||||
$token // Hide secret for clients
|
||||
->setAttribute('secret',
|
||||
($isPrivilegedUser || $isAppUser) ? $loginSecret : '');
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('resource', 'users/'.$user->getId())
|
||||
;
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($token, Response::MODEL_TOKEN)
|
||||
;
|
||||
});
|
||||
|
||||
App::put('/v1/account/sessions/magic-url')
|
||||
->desc('Create Magic URL session (confirmation)')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'public')
|
||||
->label('event', 'account.sessions.create')
|
||||
->label('sdk.auth', [])
|
||||
->label('sdk.namespace', 'account')
|
||||
->label('sdk.method', 'updateMagicURLSession')
|
||||
->label('sdk.description', '/docs/references/account/update-magic-url-session.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_SESSION)
|
||||
->label('abuse-limit', 10)
|
||||
->label('abuse-key', 'url:{url},userId:{param-userId}')
|
||||
->param('userId', '', new CustomId(), 'User unique ID.')
|
||||
->param('secret', '', new Text(256), 'Valid verification token.')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audits')
|
||||
->action(function ($userId, $secret, $request, $response, $dbForInternal, $locale, $geodb, $audits) {
|
||||
/** @var string $userId */
|
||||
/** @var string $secret */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$token = Auth::tokenVerify($user->getAttribute('tokens', []), Auth::TOKEN_TYPE_MAGIC_URL, $secret);
|
||||
|
||||
if (!$token) {
|
||||
throw new Exception('Invalid login token', 401);
|
||||
}
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$secret = Auth::tokenGenerator();
|
||||
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$session = new Document(array_merge(
|
||||
[
|
||||
'$id' => $dbForInternal->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'provider' => Auth::SESSION_PROVIDER_MAGIC_URL,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expiry,
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
'ip' => $request->getIP(),
|
||||
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
|
||||
],
|
||||
$detector->getOS(),
|
||||
$detector->getClient(),
|
||||
$detector->getDevice()
|
||||
));
|
||||
|
||||
Authorization::setRole('user:' . $user->getId());
|
||||
|
||||
$session = $dbForInternal->createDocument('sessions', $session
|
||||
->setAttribute('$read', ['user:' . $user->getId()])
|
||||
->setAttribute('$write', ['user:' . $user->getId()])
|
||||
);
|
||||
|
||||
$tokens = $user->getAttribute('tokens', []);
|
||||
|
||||
/**
|
||||
* We act like we're updating and validating
|
||||
* the recovery token but actually we don't need it anymore.
|
||||
*/
|
||||
foreach ($tokens as $key => $singleToken) {
|
||||
if ($token === $singleToken->getId()) {
|
||||
unset($tokens[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$user
|
||||
->setAttribute('sessions', $session, Document::SET_TYPE_APPEND)
|
||||
->setAttribute('tokens', $tokens);
|
||||
|
||||
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.sessions.create')
|
||||
->setParam('resource', 'users/'.$user->getId())
|
||||
;
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
$response
|
||||
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
|
||||
;
|
||||
}
|
||||
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$response
|
||||
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
|
||||
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
;
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
|
||||
$session
|
||||
->setAttribute('current', true)
|
||||
->setAttribute('countryName', $countryName)
|
||||
;
|
||||
|
||||
$response->dynamic($session, Response::MODEL_SESSION);
|
||||
});
|
||||
|
||||
App::post('/v1/account/sessions/anonymous')
|
||||
->desc('Create Anonymous Session')
|
||||
->groups(['api', 'account', 'auth'])
|
||||
|
|
@ -639,7 +928,9 @@ App::post('/v1/account/sessions/anonymous')
|
|||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if ($limit !== 0) {
|
||||
$sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT);
|
||||
$sum = $dbForInternal->count('users', [
|
||||
new Query('deleted', Query::TYPE_EQUAL, [false]),
|
||||
], APP_LIMIT_COUNT);
|
||||
|
||||
if ($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
|
|
@ -665,6 +956,8 @@ App::post('/v1/account/sessions/anonymous')
|
|||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
'memberships' => [],
|
||||
'search' => $userId,
|
||||
'deleted' => false
|
||||
]));
|
||||
|
||||
Authorization::reset();
|
||||
|
|
@ -1032,7 +1325,10 @@ App::patch('/v1/account/name')
|
|||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('name', $name));
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email')]))
|
||||
);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
|
|
@ -1131,11 +1427,18 @@ App::patch('/v1/account/email')
|
|||
}
|
||||
|
||||
$email = \strtolower($email);
|
||||
$profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
|
||||
if ($profile) {
|
||||
throw new Exception('User already registered', 409);
|
||||
}
|
||||
|
||||
try {
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user
|
||||
->setAttribute('password', $isAnonymousUser ? Auth::passwordHash($password) : $user->getAttribute('password', ''))
|
||||
->setAttribute('email', $email)
|
||||
->setAttribute('emailVerification', false) // After this user needs to confirm mail again
|
||||
->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name'), $user->getAttribute('email')]))
|
||||
);
|
||||
} catch(Duplicate $th) {
|
||||
throw new Exception('Email already exists', 409);
|
||||
|
|
@ -1221,6 +1524,8 @@ App::delete('/v1/account')
|
|||
$protocol = $request->getProtocol();
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('status', false));
|
||||
|
||||
// TODO Seems to be related to users.php/App::delete('/v1/users/:userId'). Can we share code between these two? Do todos below apply to users.php?
|
||||
|
||||
// TODO delete all tokens or only current session?
|
||||
// TODO delete all user data according to GDPR. Make sure everything is backed up and backups are deleted later
|
||||
/*
|
||||
|
|
@ -1459,11 +1764,15 @@ App::post('/v1/account/recovery')
|
|||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
$email = \strtolower($email);
|
||||
$profile = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
$profile = $dbForInternal->findOne('users', [new Query('deleted', Query::TYPE_EQUAL, [false]), new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
|
||||
if (!$profile) {
|
||||
throw new Exception('User not found', 404);
|
||||
|
|
@ -1533,7 +1842,7 @@ App::post('/v1/account/recovery')
|
|||
});
|
||||
|
||||
App::put('/v1/account/recovery')
|
||||
->desc('Complete Password Recovery')
|
||||
->desc('Create Password Recovery (confirmation)')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'public')
|
||||
->label('event', 'account.recovery.update')
|
||||
|
|
@ -1566,7 +1875,7 @@ App::put('/v1/account/recovery')
|
|||
|
||||
$profile = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($profile->isEmpty()) {
|
||||
if ($profile->isEmpty() || $profile->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -1586,10 +1895,9 @@ App::put('/v1/account/recovery')
|
|||
);
|
||||
|
||||
/**
|
||||
* We act like we're updating and validating
|
||||
* the recovery token but actually we don't need it anymore.
|
||||
*/
|
||||
|
||||
* We act like we're updating and validating
|
||||
* the recovery token but actually we don't need it anymore.
|
||||
*/
|
||||
foreach ($tokens as $key => $token) {
|
||||
if ($recovery === $token->getId()) {
|
||||
$recovery = $token;
|
||||
|
|
@ -1648,6 +1956,10 @@ App::post('/v1/account/verification')
|
|||
/** @var Appwrite\Event\Event $mails */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
|
|
@ -1712,7 +2024,7 @@ App::post('/v1/account/verification')
|
|||
});
|
||||
|
||||
App::put('/v1/account/verification')
|
||||
->desc('Complete Email Verification')
|
||||
->desc('Create Email Verification (confirmation)')
|
||||
->groups(['api', 'account'])
|
||||
->label('scope', 'public')
|
||||
->label('event', 'account.verification.update')
|
||||
|
|
@ -1757,9 +2069,9 @@ App::put('/v1/account/verification')
|
|||
$profile = $dbForInternal->updateDocument('users', $profile->getId(), $profile->setAttribute('emailVerification', true));
|
||||
|
||||
/**
|
||||
* We act like we're updating and validating
|
||||
* the verification token but actually we don't need it anymore.
|
||||
*/
|
||||
* We act like we're updating and validating
|
||||
* the verification token but actually we don't need it anymore.
|
||||
*/
|
||||
foreach ($tokens as $key => $token) {
|
||||
if ($token->getId() === $verification) {
|
||||
$verification = $token;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
|
|||
throw new Exception('Cannot set default value for required attribute', 400);
|
||||
}
|
||||
|
||||
$attribute = new Document([
|
||||
try {
|
||||
$attribute = new Document([
|
||||
'$id' => $collectionId.'_'.$attributeId,
|
||||
'key' => $attributeId,
|
||||
'collectionId' => $collectionId,
|
||||
|
|
@ -89,9 +90,8 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
|
|||
'array' => $array,
|
||||
'format' => $format,
|
||||
'formatOptions' => $formatOptions,
|
||||
]);
|
||||
]);
|
||||
|
||||
try {
|
||||
$dbForInternal->checkAttribute($collection, $attribute);
|
||||
$attribute = $dbForInternal->createDocument('attributes', $attribute);
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ function createAttribute($collectionId, $attribute, $response, $dbForInternal, $
|
|||
throw new Exception('Attribute limit exceeded', 400);
|
||||
}
|
||||
|
||||
$dbForInternal->purgeDocument('collections', $collectionId);
|
||||
$dbForInternal->deleteCachedDocument('collections', $collectionId);
|
||||
|
||||
// Pass clone of $attribute object to workers
|
||||
// so we can later modify Document to fit response model
|
||||
|
|
@ -200,33 +200,34 @@ App::get('/v1/database/collections')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 40000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the collection used as the starting point for the query, excluding the collection itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the collection used as the starting point for the query, excluding the collection itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForInternal, $usage) {
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorCollection = $dbForInternal->getDocument('collections', $cursor);
|
||||
|
||||
if ($cursorCollection->isEmpty()) {
|
||||
throw new Exception("Collection '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('name', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterCollection = $dbForInternal->getDocument('collections', $after);
|
||||
|
||||
if ($afterCollection->isEmpty()) {
|
||||
throw new Exception("Collection '{$after}' for the 'after' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$usage->setParam('database.collections.read', 1);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'collections' => $dbForInternal->find('collections', $queries, $limit, $offset, [], [$orderType], $afterCollection ?? null),
|
||||
'collections' => $dbForInternal->find('collections', $queries, $limit, $offset, [], [$orderType], $cursorCollection ?? null, $cursorDirection),
|
||||
'sum' => $dbForInternal->count('collections', $queries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_COLLECTION_LIST);
|
||||
});
|
||||
|
|
@ -669,7 +670,7 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-string.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_STRING)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('size', null, new Integer(), 'Attribute size for text attributes, in number of characters.')
|
||||
|
|
@ -717,7 +718,7 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-email.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_EMAIL)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
|
|
@ -748,6 +749,61 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
|
|||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_EMAIL);
|
||||
});
|
||||
|
||||
App::post('/v1/database/collections/:collectionId/attributes/enum')
|
||||
->desc('Create Enum Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.method', 'createEnumAttribute')
|
||||
->label('sdk.description', '/docs/references/database/create-attribute-enum.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_ENUM)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('elements', [], new ArrayList(new Text(0)), 'Array of elements in enumerated type. Uses length of longest element to determine size.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('default', null, new Text(0), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
|
||||
->param('array', false, new Boolean(), 'Is attribute an array?', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $attributeId, $elements, $required, $default, $array, $response, $dbForInternal, $database, $audits, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
// use length of longest string as attribute size
|
||||
$size = 0;
|
||||
foreach ($elements as $element) {
|
||||
$length = \strlen($element);
|
||||
if ($length === 0) {
|
||||
throw new Exception('Each enum element must not be empty', 400);
|
||||
|
||||
}
|
||||
$size = ($length > $size) ? $length : $size;
|
||||
}
|
||||
|
||||
$attribute = createAttribute($collectionId, new Document([
|
||||
'$id' => $attributeId,
|
||||
'type' => Database::VAR_STRING,
|
||||
'size' => $size,
|
||||
'required' => $required,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => APP_DATABASE_ATTRIBUTE_ENUM,
|
||||
'formatOptions' => ['elements' => $elements],
|
||||
]), $response, $dbForInternal, $database, $audits, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_ENUM);
|
||||
});
|
||||
|
||||
App::post('/v1/database/collections/:collectionId/attributes/ip')
|
||||
->desc('Create IP Address Attribute')
|
||||
->groups(['api', 'database'])
|
||||
|
|
@ -759,7 +815,7 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-ip.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_IP)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
|
|
@ -801,7 +857,7 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-url.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_URL)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
|
|
@ -843,7 +899,7 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-integer.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_INTEGER)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
|
|
@ -907,7 +963,7 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-float.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_FLOAT)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
|
|
@ -971,7 +1027,7 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean')
|
|||
->label('sdk.description', '/docs/references/database/create-attribute-boolean.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_BOOLEAN)
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
|
|
@ -1046,7 +1102,15 @@ App::get('/v1/database/collections/:collectionId/attributes/:attributeId')
|
|||
->label('sdk.description', '/docs/references/database/get-attribute.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_ATTRIBUTE)
|
||||
->label('sdk.response.model', [
|
||||
Response::MODEL_ATTRIBUTE_BOOLEAN,
|
||||
Response::MODEL_ATTRIBUTE_INTEGER,
|
||||
Response::MODEL_ATTRIBUTE_FLOAT,
|
||||
Response::MODEL_ATTRIBUTE_EMAIL,
|
||||
Response::MODEL_ATTRIBUTE_ENUM,
|
||||
Response::MODEL_ATTRIBUTE_URL,
|
||||
Response::MODEL_ATTRIBUTE_IP,
|
||||
Response::MODEL_ATTRIBUTE_STRING,])// needs to be last, since its condition would dominate any other string attribute
|
||||
->param('collectionId', '', new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).')
|
||||
->param('attributeId', '', new Key(), 'Attribute ID.')
|
||||
->inject('response')
|
||||
|
|
@ -1078,6 +1142,7 @@ App::get('/v1/database/collections/:collectionId/attributes/:attributeId')
|
|||
Database::VAR_FLOAT => Response::MODEL_ATTRIBUTE_FLOAT,
|
||||
Database::VAR_STRING => match($format) {
|
||||
APP_DATABASE_ATTRIBUTE_EMAIL => Response::MODEL_ATTRIBUTE_EMAIL,
|
||||
APP_DATABASE_ATTRIBUTE_ENUM => Response::MODEL_ATTRIBUTE_ENUM,
|
||||
APP_DATABASE_ATTRIBUTE_IP => Response::MODEL_ATTRIBUTE_IP,
|
||||
APP_DATABASE_ATTRIBUTE_URL => Response::MODEL_ATTRIBUTE_URL,
|
||||
default => Response::MODEL_ATTRIBUTE_STRING,
|
||||
|
|
@ -1130,7 +1195,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId')
|
|||
}
|
||||
|
||||
$attribute = $dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
|
||||
$dbForInternal->purgeDocument('collections', $collectionId);
|
||||
$dbForInternal->deleteCachedDocument('collections', $collectionId);
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE)
|
||||
|
|
@ -1237,7 +1302,7 @@ App::post('/v1/database/collections/:collectionId/indexes')
|
|||
throw new Exception('Index already exists', 409);
|
||||
}
|
||||
|
||||
$dbForInternal->purgeDocument('collections', $collectionId);
|
||||
$dbForInternal->deleteCachedDocument('collections', $collectionId);
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_CREATE_INDEX)
|
||||
|
|
@ -1382,7 +1447,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:indexId')
|
|||
}
|
||||
|
||||
$index = $dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting'));
|
||||
$dbForInternal->purgeDocument('collections', $collectionId);
|
||||
$dbForInternal->deleteCachedDocument('collections', $collectionId);
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_DELETE_INDEX)
|
||||
|
|
@ -1435,7 +1500,7 @@ App::post('/v1/database/collections/:collectionId/documents')
|
|||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
||||
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
|
||||
|
||||
if (empty($data)) {
|
||||
|
|
@ -1445,7 +1510,7 @@ App::post('/v1/database/collections/:collectionId/documents')
|
|||
if (isset($data['$id'])) {
|
||||
throw new Exception('$id is not allowed for creating new documents, try update instead', 400);
|
||||
}
|
||||
|
||||
|
||||
$collection = $dbForInternal->getDocument('collections', $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
|
|
@ -1512,14 +1577,15 @@ App::get('/v1/database/collections/:collectionId/documents')
|
|||
->param('queries', [], new ArrayList(new Text(128)), 'Array of query strings.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the document used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the document used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderAttributes', [], new ArrayList(new Text(128)), 'Array of attributes used to sort results.', true)
|
||||
->param('orderTypes', [], new ArrayList(new WhiteList(['DESC', 'ASC'], true)), 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->inject('dbForExternal')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $queries, $limit, $offset, $after, $orderAttributes, $orderTypes, $response, $dbForInternal, $dbForExternal, $usage) {
|
||||
->action(function ($collectionId, $queries, $limit, $offset, $cursor, $cursorDirection, $orderAttributes, $orderTypes, $response, $dbForInternal, $dbForExternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Database\Database $dbForExternal */
|
||||
|
|
@ -1550,28 +1616,29 @@ App::get('/v1/database/collections/:collectionId/documents')
|
|||
throw new Exception($validator->getDescription(), 400);
|
||||
}
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterDocument = $dbForExternal->getDocument($collectionId, $after);
|
||||
$cursorDocument = null;
|
||||
if (!empty($cursor)) {
|
||||
$cursorDocument = $dbForExternal->getDocument($collectionId, $cursor);
|
||||
|
||||
if ($afterDocument->isEmpty()) {
|
||||
throw new Exception("Document '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception("Document '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
if ($collection->getAttribute('permission') === 'collection') {
|
||||
/** @var Document[] $documents */
|
||||
$documents = Authorization::skip(function() use ($dbForExternal, $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $afterDocument) {
|
||||
return $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $afterDocument ?? null);
|
||||
$documents = Authorization::skip(function() use ($dbForExternal, $collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument, $cursorDirection) {
|
||||
return $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection);
|
||||
});
|
||||
} else {
|
||||
$documents = $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $afterDocument ?? null);
|
||||
$documents = $dbForExternal->find($collectionId, $queries, $limit, $offset, $orderAttributes, $orderTypes, $cursorDocument ?? null, $cursorDirection);
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('database.documents.read', 1)
|
||||
->setParam('collectionId', $collectionId)
|
||||
;
|
||||
|
||||
;
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'sum' => $dbForExternal->count($collectionId, $queries, APP_LIMIT_COUNT),
|
||||
'documents' => $documents,
|
||||
|
|
@ -1675,7 +1742,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId/logs')
|
|||
|
||||
$audit = new Audit($dbForInternal);
|
||||
|
||||
$logs = $audit->getLogsByResource('database/document/'.$document->getId());
|
||||
$logs = $audit->getLogsByResource('document/'.$document->getId());
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -53,8 +53,9 @@ App::post('/v1/functions')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$functionId = ($functionId == 'unique()') ? $dbForInternal->getId() : $functionId;
|
||||
$function = $dbForInternal->createDocument('functions', new Document([
|
||||
'$id' => $functionId == 'unique()' ? $dbForInternal->getId() : $functionId,
|
||||
'$id' => $functionId,
|
||||
'execute' => $execute,
|
||||
'dateCreated' => time(),
|
||||
'dateUpdated' => time(),
|
||||
|
|
@ -68,6 +69,7 @@ App::post('/v1/functions')
|
|||
'schedulePrevious' => 0,
|
||||
'scheduleNext' => 0,
|
||||
'timeout' => $timeout,
|
||||
'search' => implode(' ', [$functionId, $name, $runtime]),
|
||||
]));
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
|
@ -88,26 +90,31 @@ App::get('/v1/functions')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForInternal) {
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
|
||||
if (!empty($cursor)) {
|
||||
$cursorFunction = $dbForInternal->getDocument('functions', $cursor);
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterFunction = $dbForInternal->getDocument('functions', $after);
|
||||
|
||||
if ($afterFunction->isEmpty()) {
|
||||
throw new Exception("Function '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorFunction->isEmpty()) {
|
||||
throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, [], [$orderType], $afterFunction ?? null),
|
||||
'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection),
|
||||
'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_FUNCTION_LIST);
|
||||
});
|
||||
|
|
@ -271,6 +278,7 @@ App::put('/v1/functions/:functionId')
|
|||
'schedule' => $schedule,
|
||||
'scheduleNext' => (int)$next,
|
||||
'timeout' => $timeout,
|
||||
'search' => implode(' ', [$functionId, $name, $function->getAttribute('runtime')]),
|
||||
])));
|
||||
|
||||
if ($next && $schedule !== $original) {
|
||||
|
|
@ -447,8 +455,9 @@ App::post('/v1/functions/:functionId/tags')
|
|||
throw new Exception('Failed moving file', 500);
|
||||
}
|
||||
|
||||
$tagId = $dbForInternal->getId();
|
||||
$tag = $dbForInternal->createDocument('tags', new Document([
|
||||
'$id' => $dbForInternal->getId(),
|
||||
'$id' => $tagId,
|
||||
'$read' => [],
|
||||
'$write' => [],
|
||||
'functionId' => $function->getId(),
|
||||
|
|
@ -456,6 +465,7 @@ App::post('/v1/functions/:functionId/tags')
|
|||
'command' => $command,
|
||||
'path' => $path,
|
||||
'size' => $size,
|
||||
'search' => implode(' ', [$tagId, $command]),
|
||||
]));
|
||||
|
||||
$usage
|
||||
|
|
@ -481,11 +491,12 @@ App::get('/v1/functions/:functionId/tags')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the tag used as the starting point for the query, excluding the tag itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the tag used as the starting point for the query, excluding the tag itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $search, $limit, $offset, $after, $orderType, $response, $dbForInternal) {
|
||||
->action(function ($functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
|
|
@ -495,17 +506,23 @@ App::get('/v1/functions/:functionId/tags')
|
|||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]);
|
||||
if (!empty($cursor)) {
|
||||
$cursorTag = $dbForInternal->getDocument('tags', $cursor);
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterTag = $dbForInternal->getDocument('tags', $after);
|
||||
|
||||
if ($afterTag->isEmpty()) {
|
||||
throw new Exception("Tag '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorTag->isEmpty()) {
|
||||
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('tags', $queries, $limit, $offset, [], [$orderType], $afterTag ?? null);
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]);
|
||||
|
||||
$results = $dbForInternal->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
|
@ -665,8 +682,10 @@ App::post('/v1/functions/:functionId/executions')
|
|||
|
||||
Authorization::disable();
|
||||
|
||||
$executionId = $dbForInternal->getId();
|
||||
|
||||
$execution = $dbForInternal->createDocument('executions', new Document([
|
||||
'$id' => $dbForInternal->getId(),
|
||||
'$id' => $executionId,
|
||||
'$read' => (!$user->isEmpty()) ? ['user:' . $user->getId()] : [],
|
||||
'$write' => [],
|
||||
'dateCreated' => time(),
|
||||
|
|
@ -678,13 +697,14 @@ App::post('/v1/functions/:functionId/executions')
|
|||
'stdout' => '',
|
||||
'stderr' => '',
|
||||
'time' => 0.0,
|
||||
'search' => implode(' ', [$functionId, $executionId]),
|
||||
]));
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
|
||||
$jwt = ''; // initialize
|
||||
if (!$user->isEmpty()) { // If userId exists, generate a JWT for function
|
||||
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$current = new Document();
|
||||
|
||||
|
|
@ -732,36 +752,41 @@ App::get('/v1/functions/:functionId/executions')
|
|||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $limit, $offset, $after, $response, $dbForInternal) {
|
||||
->action(function ($functionId, $limit, $offset, $search, $cursor, $cursorDirection, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
Authorization::disable();
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
Authorization::reset();
|
||||
$function = Authorization::skip(function() use ($dbForInternal, $functionId) {
|
||||
return $dbForInternal->getDocument('functions', $functionId);
|
||||
});
|
||||
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterExecution = $dbForInternal->getDocument('executions', $after);
|
||||
if (!empty($cursor)) {
|
||||
$cursorExecution = $dbForInternal->getDocument('executions', $cursor);
|
||||
|
||||
if ($afterExecution->isEmpty()) {
|
||||
throw new Exception("Execution '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorExecution->isEmpty()) {
|
||||
throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('executions', [
|
||||
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]),
|
||||
], $limit, $offset, [], [Database::ORDER_DESC], $afterExecution ?? null);
|
||||
$queries = [
|
||||
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()])
|
||||
];
|
||||
|
||||
$sum = $dbForInternal->count('executions', [
|
||||
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]),
|
||||
], APP_LIMIT_COUNT);
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('executions', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'executions' => $results,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use Appwrite\Network\Validator\URL;
|
|||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Abuse\Adapters\TimeLimit;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\CLI;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
|
|
@ -78,6 +79,7 @@ App::post('/v1/projects')
|
|||
$auths[$method['key'] ?? ''] = true;
|
||||
}
|
||||
|
||||
$projectId = ($projectId == 'unique()') ? $dbForConsole->getId() : $projectId;
|
||||
$project = $dbForConsole->createDocument('projects', new Document([
|
||||
'$id' => $projectId == 'unique()' ? $dbForConsole->getId() : $projectId,
|
||||
'$read' => ['team:' . $teamId],
|
||||
|
|
@ -95,11 +97,13 @@ App::post('/v1/projects')
|
|||
'legalAddress' => $legalAddress,
|
||||
'legalTaxId' => $legalTaxId,
|
||||
'services' => new stdClass(),
|
||||
'platforms' => [],
|
||||
'webhooks' => [],
|
||||
'keys' => [],
|
||||
'domains' => [],
|
||||
'platforms' => null,
|
||||
'providers' => [],
|
||||
'webhooks' => null,
|
||||
'keys' => null,
|
||||
'domains' => null,
|
||||
'auths' => $auths,
|
||||
'search' => implode(' ', [$projectId, $name]),
|
||||
]));
|
||||
|
||||
$collections = Config::getParam('collections2', []); /** @var array $collections */
|
||||
|
|
@ -112,7 +116,7 @@ App::post('/v1/projects')
|
|||
$audit = new Audit($dbForInternal);
|
||||
$audit->setup();
|
||||
|
||||
$adapter = new TimeLimit("", 0, 1, $dbForInternal);
|
||||
$adapter = new TimeLimit('', 0, 1, $dbForInternal);
|
||||
$adapter->setup();
|
||||
|
||||
foreach ($collections as $key => $collection) {
|
||||
|
|
@ -163,25 +167,30 @@ App::get('/v1/projects')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the project used as the starting point for the query, excluding the project itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the project used as the starting point for the query, excluding the project itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForConsole) {
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForConsole) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
|
||||
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
|
||||
if (!empty($cursor)) {
|
||||
$cursorProject = $dbForConsole->getDocument('projects', $cursor);
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterProject = $dbForConsole->getDocument('projects', $after);
|
||||
|
||||
if ($afterProject->isEmpty()) {
|
||||
throw new Exception("Project '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorProject->isEmpty()) {
|
||||
throw new Exception("Project '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$results = $dbForConsole->find('projects', $queries, $limit, $offset, [], [$orderType], $afterProject ?? null);
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$results = $dbForConsole->find('projects', $queries, $limit, $offset, [], [$orderType], $cursorProject ?? null, $cursorDirection);
|
||||
$sum = $dbForConsole->count('projects', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
|
@ -356,6 +365,7 @@ App::patch('/v1/projects/:projectId')
|
|||
->setAttribute('legalCity', $legalCity)
|
||||
->setAttribute('legalAddress', $legalAddress)
|
||||
->setAttribute('legalTaxId', $legalTaxId)
|
||||
->setAttribute('search', implode(' ', [$projectId, $name]))
|
||||
);
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
|
|
@ -379,6 +389,7 @@ App::patch('/v1/projects/:projectId/service')
|
|||
->action(function ($projectId, $service, $status, $response, $dbForConsole) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
/** @var Boolean $status */
|
||||
|
||||
$project = $dbForConsole->getDocument('projects', $projectId);
|
||||
|
||||
|
|
@ -457,7 +468,7 @@ App::patch('/v1/projects/:projectId/auth/limit')
|
|||
$auths['limit'] = $limit;
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('auths', $auths)
|
||||
->setAttribute('auths', $auths)
|
||||
);
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
|
|
@ -581,6 +592,9 @@ App::post('/v1/projects/:projectId/webhooks')
|
|||
|
||||
$webhook = new Document([
|
||||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectId' => $project->getId(),
|
||||
'name' => $name,
|
||||
'events' => $events,
|
||||
'url' => $url,
|
||||
|
|
@ -589,9 +603,9 @@ App::post('/v1/projects/:projectId/webhooks')
|
|||
'httpPass' => $httpPass,
|
||||
]);
|
||||
|
||||
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('webhooks', $webhook, Document::SET_TYPE_APPEND)
|
||||
);
|
||||
$webhook = $dbForConsole->createDocument('webhooks', $webhook);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
|
||||
|
|
@ -620,7 +634,9 @@ App::get('/v1/projects/:projectId/webhooks')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$webhooks = $project->getAttribute('webhooks', []);
|
||||
$webhooks = $dbForConsole->find('webhooks', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'webhooks' => $webhooks,
|
||||
|
|
@ -652,9 +668,12 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$webhook = $project->find('$id', $webhookId, 'webhooks');
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($webhook) || !$webhook instanceof Document) {
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
throw new Exception('Webhook not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -693,22 +712,27 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
|
||||
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
|
||||
|
||||
$webhook = $project->find('$id', $webhookId, 'webhooks');
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($webhook) || !$webhook instanceof Document) {
|
||||
if ($webhook === false || $webhook->isEmpty()) {
|
||||
throw new Exception('Webhook not found', 404);
|
||||
}
|
||||
|
||||
$project->findAndReplace('$id', $webhook->getId(), $webhook
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('events', $events)
|
||||
->setAttribute('url', $url)
|
||||
->setAttribute('security', $security)
|
||||
->setAttribute('httpUser', $httpUser)
|
||||
->setAttribute('httpPass', $httpPass)
|
||||
, 'webhooks');
|
||||
$webhook
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('events', $events)
|
||||
->setAttribute('url', $url)
|
||||
->setAttribute('security', $security)
|
||||
->setAttribute('httpUser', $httpUser)
|
||||
->setAttribute('httpPass', $httpPass)
|
||||
;
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
|
||||
});
|
||||
|
|
@ -736,11 +760,18 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
if (!$project->findAndRemove('$id', $webhookId, 'webhooks')) {
|
||||
$webhook = $dbForConsole->findOne('webhooks', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$webhookId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if($webhook === false || $webhook->isEmpty()) {
|
||||
throw new Exception('Webhook not found', 404);
|
||||
}
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->deleteDocument('webhooks', $webhook->getId());
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
|
@ -774,14 +805,17 @@ App::post('/v1/projects/:projectId/keys')
|
|||
|
||||
$key = new Document([
|
||||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectId' => $project->getId(),
|
||||
'name' => $name,
|
||||
'scopes' => $scopes,
|
||||
'secret' => \bin2hex(\random_bytes(128)),
|
||||
]);
|
||||
|
||||
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('keys', $key, Document::SET_TYPE_APPEND)
|
||||
);
|
||||
$key = $dbForConsole->createDocument('keys', $key);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($key, Response::MODEL_KEY);
|
||||
|
|
@ -810,7 +844,9 @@ App::get('/v1/projects/:projectId/keys')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$keys = $project->getAttribute('keys', []);
|
||||
$keys = $dbForConsole->find('keys', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()]),
|
||||
], 5000);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'keys' => $keys,
|
||||
|
|
@ -833,15 +869,21 @@ App::get('/v1/projects/:projectId/keys/:keyId')
|
|||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->action(function ($projectId, $keyId, $response, $dbForConsole) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
|
||||
$project = $dbForConsole->getDocument('projects', $projectId);
|
||||
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$key = $project->find('$id', $keyId, 'keys');
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($key) || !$key instanceof Document) {
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
throw new Exception('Key not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -874,18 +916,23 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$key = $project->find('$id', $keyId, 'keys');
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($key) || !$key instanceof Document) {
|
||||
if ($key === false || $key->isEmpty()) {
|
||||
throw new Exception('Key not found', 404);
|
||||
}
|
||||
|
||||
$project->findAndReplace('$id', $key->getId(), $key
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('scopes', $scopes)
|
||||
, 'keys');
|
||||
$key
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('scopes', $scopes)
|
||||
;
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->updateDocument('keys', $key->getId(), $key);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($key, Response::MODEL_KEY);
|
||||
});
|
||||
|
|
@ -913,11 +960,18 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
if (!$project->findAndRemove('$id', $keyId, 'keys')) {
|
||||
$key = $dbForConsole->findOne('keys', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$keyId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if($key === false || $key->isEmpty()) {
|
||||
throw new Exception('Key not found', 404);
|
||||
}
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->deleteDocument('keys', $key->getId());
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
|
@ -954,6 +1008,9 @@ App::post('/v1/projects/:projectId/platforms')
|
|||
|
||||
$platform = new Document([
|
||||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectId' => $project->getId(),
|
||||
'type' => $type,
|
||||
'name' => $name,
|
||||
'key' => $key,
|
||||
|
|
@ -963,9 +1020,9 @@ App::post('/v1/projects/:projectId/platforms')
|
|||
'dateUpdated' => \time(),
|
||||
]);
|
||||
|
||||
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('platforms', $platform, Document::SET_TYPE_APPEND)
|
||||
);
|
||||
$platform = $dbForConsole->createDocument('platforms', $platform);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($platform, Response::MODEL_PLATFORM);
|
||||
|
|
@ -994,7 +1051,9 @@ App::get('/v1/projects/:projectId/platforms')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$platforms = $project->getAttribute('platforms', []);
|
||||
$platforms = $dbForConsole->find('platforms', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
], 5000);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'platforms' => $platforms,
|
||||
|
|
@ -1026,9 +1085,12 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$platform = $project->find('$id', $platformId, 'platforms');
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($platform) || !$platform instanceof Document) {
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
throw new Exception('Platform not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -1063,9 +1125,12 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$platform = $project->find('$id', $platformId, 'platforms');
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($platform) || !$platform instanceof Document) {
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
throw new Exception('Platform not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -1077,15 +1142,9 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
|||
->setAttribute('hostname', $hostname)
|
||||
;
|
||||
|
||||
$project->findAndReplace('$id', $platform->getId(), $platform
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('dateUpdated', \time())
|
||||
->setAttribute('key', $key)
|
||||
->setAttribute('store', $store)
|
||||
->setAttribute('hostname', $hostname)
|
||||
, 'platforms');
|
||||
$dbForConsole->updateDocument('platforms', $platform->getId(), $platform);
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($platform, Response::MODEL_PLATFORM);
|
||||
});
|
||||
|
|
@ -1113,11 +1172,18 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
if (!$project->findAndRemove('$id', $platformId, 'platforms')) {
|
||||
$platform = $dbForConsole->findOne('platforms', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$platformId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if ($platform === false || $platform->isEmpty()) {
|
||||
throw new Exception('Platform not found', 404);
|
||||
}
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->deleteDocument('platforms', $platformId);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
|
@ -1148,9 +1214,12 @@ App::post('/v1/projects/:projectId/domains')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$document = $project->find('domain', $domain, 'domains');
|
||||
$document = $dbForConsole->findOne('domains', [
|
||||
new Query('domain', Query::TYPE_EQUAL, [$domain]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()]),
|
||||
]);
|
||||
|
||||
if ($document) {
|
||||
if ($document && !$document->isEmpty()) {
|
||||
throw new Exception('Domain already exists', 409);
|
||||
}
|
||||
|
||||
|
|
@ -1164,6 +1233,9 @@ App::post('/v1/projects/:projectId/domains')
|
|||
|
||||
$domain = new Document([
|
||||
'$id' => $dbForConsole->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['role:all'],
|
||||
'projectId' => $project->getId(),
|
||||
'updated' => \time(),
|
||||
'domain' => $domain->get(),
|
||||
'tld' => $domain->getSuffix(),
|
||||
|
|
@ -1172,9 +1244,9 @@ App::post('/v1/projects/:projectId/domains')
|
|||
'certificateId' => null,
|
||||
]);
|
||||
|
||||
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('domains', $domain, Document::SET_TYPE_APPEND)
|
||||
);
|
||||
$domain = $dbForConsole->createDocument('domains', $domain);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($domain, Response::MODEL_DOMAIN);
|
||||
|
|
@ -1203,7 +1275,9 @@ App::get('/v1/projects/:projectId/domains')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$domains = $project->getAttribute('domains', []);
|
||||
$domains = $dbForConsole->find('domains', [
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
], 5000);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'domains' => $domains,
|
||||
|
|
@ -1235,9 +1309,12 @@ App::get('/v1/projects/:projectId/domains/:domainId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$domain = $project->find('$id', $domainId, 'domains');
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($domain) || !$domain instanceof Document) {
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
throw new Exception('Domain not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -1268,9 +1345,12 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$domain = $project->find('$id', $domainId, 'domains');
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (empty($domain) || !$domain instanceof Document) {
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
throw new Exception('Domain not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -1290,11 +1370,9 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
|
|||
throw new Exception('Failed to verify domain', 401);
|
||||
}
|
||||
|
||||
$project->findAndReplace('$id', $domain->getId(), $domain
|
||||
->setAttribute('verification', true)
|
||||
, 'domains');
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->updateDocument('domains', $domain->getId(), $domain->setAttribute('verification', true));
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
// Issue a TLS certificate when domain is verified
|
||||
Resque::enqueue('v1-certificates', 'CertificatesV1', [
|
||||
|
|
@ -1329,13 +1407,18 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
|
|||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
$domain = $project->find('$id', $domainId, 'domains');
|
||||
$domain = $dbForConsole->findOne('domains', [
|
||||
new Query('_uid', Query::TYPE_EQUAL, [$domainId]),
|
||||
new Query('projectId', Query::TYPE_EQUAL, [$project->getId()])
|
||||
]);
|
||||
|
||||
if (!$project->findAndRemove('$id', $domainId, 'domains')) {
|
||||
if ($domain === false || $domain->isEmpty()) {
|
||||
throw new Exception('Domain not found', 404);
|
||||
}
|
||||
|
||||
$dbForConsole->updateDocument('projects', $project->getId(), $project);
|
||||
$dbForConsole->deleteDocument('domains', $domain->getId());
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_CERTIFICATES)
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ App::post('/v1/storage/files')
|
|||
// Save to storage
|
||||
$size = $device->getFileSize($file['tmp_name']);
|
||||
$path = $device->getPath(\uniqid().'.'.\pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
|
||||
|
||||
if (!$device->upload($file['tmp_name'], $path)) { // TODO deprecate 'upload' and replace with 'move'
|
||||
throw new Exception('Failed moving file', 500);
|
||||
}
|
||||
|
|
@ -124,14 +124,15 @@ App::post('/v1/storage/files')
|
|||
}
|
||||
|
||||
$sizeActual = $device->getFileSize($path);
|
||||
|
||||
|
||||
$fileId = ($fileId == 'unique()') ? $dbForInternal->getId() : $fileId;
|
||||
$file = $dbForInternal->createDocument('files', new Document([
|
||||
'$id' => $fileId == 'unique()' ? $dbForInternal->getId() : $fileId,
|
||||
'$id' => $fileId,
|
||||
'$read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
|
||||
'$write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
|
||||
'dateCreated' => \time(),
|
||||
'bucketId' => '',
|
||||
'name' => $file['name'],
|
||||
'name' => $file['name'] ?? '',
|
||||
'path' => $path,
|
||||
'signature' => $device->getFileHash($path),
|
||||
'mimeType' => $mimeType,
|
||||
|
|
@ -143,6 +144,7 @@ App::post('/v1/storage/files')
|
|||
'openSSLCipher' => OpenSSL::CIPHER_AES_128_GCM,
|
||||
'openSSLTag' => \bin2hex($tag),
|
||||
'openSSLIV' => \bin2hex($iv),
|
||||
'search' => implode(' ', [$fileId, $file['name'] ?? '',]),
|
||||
]));
|
||||
|
||||
$audits
|
||||
|
|
@ -175,33 +177,38 @@ App::get('/v1/storage/files')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the file used as the starting point for the query, excluding the file itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the file used as the starting point for the query, excluding the file itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForInternal, $usage) {
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, $search)] : [];
|
||||
if (!empty($cursor)) {
|
||||
$cursorFile = $dbForInternal->getDocument('files', $cursor);
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterFile = $dbForInternal->getDocument('files', $after);
|
||||
|
||||
if ($afterFile->isEmpty()) {
|
||||
throw new Exception("File '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorFile->isEmpty()) {
|
||||
throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.read', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'files' => $dbForInternal->find('files', $queries, $limit, $offset, [], [$orderType], $afterFile ?? null),
|
||||
'files' => $dbForInternal->find('files', $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection),
|
||||
'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_FILE_LIST);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use Utopia\Validator\Text;
|
|||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
use Utopia\Database\Query;
|
||||
|
|
@ -39,10 +40,12 @@ App::post('/v1/teams')
|
|||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($teamId, $name, $roles, $response, $user, $dbForInternal) {
|
||||
->inject('events')
|
||||
->action(function ($teamId, $name, $roles, $response, $user, $dbForInternal, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
|
|
@ -57,6 +60,7 @@ App::post('/v1/teams')
|
|||
'name' => $name,
|
||||
'sum' => ($isPrivilegedUser || $isAppUser) ? 0 : 1,
|
||||
'dateCreated' => \time(),
|
||||
'search' => implode(' ', [$teamId, $name]),
|
||||
]));
|
||||
|
||||
Authorization::reset();
|
||||
|
|
@ -81,6 +85,10 @@ App::post('/v1/teams')
|
|||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
}
|
||||
|
||||
if (!empty($user->getId())) {
|
||||
$events->setParam('userId', $user->getId());
|
||||
}
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($team, Response::MODEL_TEAM);
|
||||
});
|
||||
|
|
@ -99,25 +107,30 @@ App::get('/v1/teams')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the team used as the starting point for the query, excluding the team itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the team used as the starting point for the query, excluding the team itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForInternal) {
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$queries = ($search) ? [new Query('name', Query::TYPE_SEARCH, [$search])] : [];
|
||||
if (!empty($cursor)) {
|
||||
$cursorTeam = $dbForInternal->getDocument('teams', $cursor);
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterTeam = $dbForInternal->getDocument('teams', $after);
|
||||
|
||||
if ($afterTeam->isEmpty()) {
|
||||
throw new Exception("Team '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorTeam->isEmpty()) {
|
||||
throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('teams', $queries, $limit, $offset, [], [$orderType], $afterTeam ?? null);
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
|
|
@ -179,7 +192,10 @@ App::put('/v1/teams/:teamId')
|
|||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('name', $name));
|
||||
$team = $dbForInternal->updateDocument('teams', $team->getId(),$team
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('search', implode(' ', [$teamId, $name]))
|
||||
);
|
||||
|
||||
$response->dynamic($team, Response::MODEL_TEAM);
|
||||
});
|
||||
|
|
@ -255,9 +271,9 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
->label('abuse-limit', 10)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('email', '', new Email(), 'New team member email.')
|
||||
->param('name', '', new Text(128), 'New team member name. Max length: 128 chars.', true)
|
||||
->param('roles', [], new ArrayList(new Key()), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.')
|
||||
->param('url', '', function ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients'])
|
||||
->param('url', '', function ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients']) // TODO add our own built-in confirm page
|
||||
->param('name', '', new Text(128), 'New team member name. Max length: 128 chars.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
|
|
@ -265,7 +281,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
->inject('locale')
|
||||
->inject('audits')
|
||||
->inject('mails')
|
||||
->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) {
|
||||
->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
|
@ -273,9 +289,13 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
|
||||
$email = \strtolower($email);
|
||||
$name = (empty($name)) ? $email : $name;
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
|
@ -289,10 +309,10 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
if (empty($invitee)) { // Create new user if no user with same email found
|
||||
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
|
||||
if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed.
|
||||
$sum = $dbForInternal->count('users', [], APP_LIMIT_USERS);
|
||||
|
||||
|
||||
if($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
}
|
||||
|
|
@ -323,6 +343,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
'memberships' => [],
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
]));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
|
|
@ -377,7 +398,7 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
}
|
||||
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'teamId' => $team->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url = Template::unParseURL($url);
|
||||
|
||||
if (!$isPrivilegedUser && !$isAppUser) { // No need of confirmation when in admin or app mode
|
||||
|
|
@ -424,11 +445,12 @@ App::get('/v1/teams/:teamId/memberships')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the membership used as the starting point for the query, excluding the membership itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the membership used as the starting point for the query, excluding the membership itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($teamId, $search, $limit, $offset, $after, $orderType, $response, $dbForInternal) {
|
||||
->action(function ($teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
|
|
@ -438,15 +460,15 @@ App::get('/v1/teams/:teamId/memberships')
|
|||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterMembership = $dbForInternal->getDocument('memberships', $after);
|
||||
if (!empty($cursor)) {
|
||||
$cursorMembership = $dbForInternal->getDocument('memberships', $cursor);
|
||||
|
||||
if ($afterMembership->isEmpty()) {
|
||||
throw new Exception("Membership '{$after}' for the 'after' value not found.", 400);
|
||||
if ($cursorMembership->isEmpty()) {
|
||||
throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$memberships = $dbForInternal->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $afterMembership ?? null);
|
||||
$memberships = $dbForInternal->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $cursorMembership ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], APP_LIMIT_COUNT);
|
||||
$users = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ App::post('/v1/users')
|
|||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
'memberships' => [],
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'deleted' => false
|
||||
]));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
|
|
@ -93,34 +95,40 @@ App::get('/v1/users')
|
|||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('after', '', new UID(), 'ID of the user used as the starting point for the query, excluding the user itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the user used as the starting point for the query, excluding the user itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($search, $limit, $offset, $after, $orderType, $response, $dbForInternal, $usage) {
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
if (!empty($after)) {
|
||||
$afterUser = $dbForInternal->getDocument('users', $after);
|
||||
if (!empty($cursor)) {
|
||||
$cursorUser = $dbForInternal->getDocument('users', $cursor);
|
||||
|
||||
if ($afterUser->isEmpty()) {
|
||||
throw new Exception('User for after not found', 400);
|
||||
if ($cursorUser->isEmpty()) {
|
||||
throw new Exception("User '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('users', [], $limit, $offset, [], [$orderType], $afterUser ?? null);
|
||||
$sum = $dbForInternal->count('users', [], APP_LIMIT_COUNT);
|
||||
|
||||
$queries = [
|
||||
new Query('deleted', Query::TYPE_EQUAL, [false])
|
||||
];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('users.read', 1)
|
||||
;
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'users' => $results,
|
||||
'sum' => $sum,
|
||||
'users' => $dbForInternal->find('users', $queries, $limit, $offset, [], [$orderType], $cursorUser ?? null, $cursorDirection),
|
||||
'sum' => $dbForInternal->count('users', $queries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_USER_LIST);
|
||||
});
|
||||
|
||||
|
|
@ -146,7 +154,7 @@ App::get('/v1/users/:userId')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -178,7 +186,7 @@ App::get('/v1/users/:userId/prefs')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +222,7 @@ App::get('/v1/users/:userId/sessions')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -266,7 +274,7 @@ App::get('/v1/users/:userId/logs')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -374,7 +382,7 @@ App::patch('/v1/users/:userId/status')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -410,7 +418,7 @@ App::patch('/v1/users/:userId/verification')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -443,10 +451,10 @@ App::patch('/v1/users/:userId/name')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -485,12 +493,15 @@ App::patch('/v1/users/:userId/password')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('password', Auth::passwordHash($password))
|
||||
->setAttribute('passwordUpdate', \time()));
|
||||
$user
|
||||
->setAttribute('password', Auth::passwordHash($password))
|
||||
->setAttribute('passwordUpdate', \time());
|
||||
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
|
|
@ -525,11 +536,17 @@ App::patch('/v1/users/:userId/email')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$email = \strtolower($email);
|
||||
$isAnonymousUser = is_null($user->getAttribute('email')) && is_null($user->getAttribute('password')); // Check if request is from an anonymous account for converting
|
||||
if (!$isAnonymousUser) {
|
||||
//TODO: Remove previous unique ID.
|
||||
}
|
||||
|
||||
$email = \strtolower($email);
|
||||
|
||||
try {
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('email', $email));
|
||||
} catch(Duplicate $th) {
|
||||
|
|
@ -538,7 +555,7 @@ App::patch('/v1/users/:userId/email')
|
|||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.update.email')
|
||||
->setParam('event', 'users.update.email')
|
||||
->setParam('resource', 'user/'.$user->getId())
|
||||
;
|
||||
|
||||
|
|
@ -569,7 +586,7 @@ App::patch('/v1/users/:userId/prefs')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -606,7 +623,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -620,7 +637,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
|
|||
$dbForInternal->deleteDocument('sessions', $session->getId());
|
||||
|
||||
$user->setAttribute('sessions', $sessions);
|
||||
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($user, Response::MODEL_USER))
|
||||
;
|
||||
|
|
@ -661,7 +678,7 @@ App::delete('/v1/users/:userId/sessions')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
|
|
@ -710,26 +727,35 @@ App::delete('/v1/users/:userId')
|
|||
|
||||
$user = $dbForInternal->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
if ($user->isEmpty() || $user->getAttribute('deleted')) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
if (!$dbForInternal->deleteDocument('users', $userId)) {
|
||||
throw new Exception('Failed to remove user from DB', 500);
|
||||
}
|
||||
// clone user object to send to workers
|
||||
$clone = clone $user;
|
||||
|
||||
$user
|
||||
->setAttribute("name", null)
|
||||
->setAttribute("email", null)
|
||||
->setAttribute("password", null)
|
||||
->setAttribute("deleted", true)
|
||||
;
|
||||
|
||||
$dbForInternal->updateDocument('users', $userId, $user);
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $user)
|
||||
->setParam('document', $clone)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($user, Response::MODEL_USER))
|
||||
->setParam('eventData', $response->output($clone, Response::MODEL_USER))
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('users.delete', 1)
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ Config::setParam('cookieDomain', 'localhost');
|
|||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $dbForConsole, $user, $locale, $clients) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
/** @var Utopia\Database\Document $console */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var array $clients */
|
||||
|
|
@ -41,6 +42,8 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
if (empty($domain->get()) || !$domain->isKnown() || $domain->isTest()) {
|
||||
$domains[$domain->get()] = false;
|
||||
Console::warning($domain->get() . ' is not a publicly accessible domain. Skipping SSL certificate generation.');
|
||||
} elseif(str_starts_with($request->getURI(), '/.well-known/acme-challenge')) {
|
||||
Console::warning('Skipping SSL certificates generation on ACME challenge.');
|
||||
} else {
|
||||
Authorization::disable();
|
||||
|
||||
|
|
@ -94,7 +97,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
|
||||
$refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()).'://'.((\in_array($origin, $clients))
|
||||
? $origin : 'localhost').(!empty($port) ? ':'.$port : '');
|
||||
|
||||
|
||||
$refDomain = (!$route->getLabel('origin', false)) // This route is publicly accessible
|
||||
? $refDomain
|
||||
: (!empty($protocol) ? $protocol : $request->getProtocol()).'://'.$origin.(!empty($port) ? ':'.$port : '');
|
||||
|
|
@ -115,7 +118,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
Config::setParam('domainVerification',
|
||||
($selfDomain->getRegisterable() === $endDomain->getRegisterable()) &&
|
||||
$endDomain->getRegisterable() !== '');
|
||||
|
||||
|
||||
Config::setParam('cookieDomain', (
|
||||
$request->getHostname() === 'localhost' ||
|
||||
$request->getHostname() === 'localhost:'.$request->getPort() ||
|
||||
|
|
@ -185,7 +188,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
&& empty($request->getHeader('x-appwrite-key', ''))) {
|
||||
throw new Exception($originValidator->getDescription(), 403);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ACL Check
|
||||
*/
|
||||
|
|
@ -219,7 +222,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
if (!empty($authKey)) { // API Key authentication
|
||||
// Check if given key match project API keys
|
||||
$key = $project->find('secret', $authKey, 'keys');
|
||||
|
||||
|
||||
/*
|
||||
* Try app auth when we have project key and no user
|
||||
* Mock user to app and grant API key scopes in addition to default app scopes
|
||||
|
|
@ -236,25 +239,16 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
$role = Auth::USER_ROLE_APP;
|
||||
$scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', []));
|
||||
|
||||
Authorization::setRole('role:'.Auth::USER_ROLE_APP);
|
||||
Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys.
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->getId()) {
|
||||
Authorization::setRole('user:'.$user->getId());
|
||||
}
|
||||
|
||||
Authorization::setRole('role:'.$role);
|
||||
|
||||
\array_map(function ($node) {
|
||||
if (isset($node['teamId']) && isset($node['roles'])) {
|
||||
Authorization::setRole('team:'.$node['teamId']);
|
||||
|
||||
foreach ($node['roles'] as $nodeRole) { // Set all team roles
|
||||
Authorization::setRole('team:'.$node['teamId'].'/'.$nodeRole);
|
||||
}
|
||||
}
|
||||
}, $user->getAttribute('memberships', []));
|
||||
foreach (Auth::getRoles($user) as $authRole) {
|
||||
Authorization::setRole($authRole);
|
||||
}
|
||||
|
||||
$service = $route->getLabel('sdk.namespace','');
|
||||
if(!empty($service)) {
|
||||
|
|
@ -269,7 +263,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
if ($project->isEmpty()) { // Check if permission is denied because project is missing
|
||||
throw new Exception('Project not found', 404);
|
||||
}
|
||||
|
||||
|
||||
throw new Exception($user->getAttribute('email', 'User').' (role: '.\strtolower($roles[$role]['label']).') missing scope ('.$scope.')', 401);
|
||||
}
|
||||
|
||||
|
|
@ -316,12 +310,12 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
|||
|
||||
if (php_sapi_name() === 'cli') {
|
||||
Console::error('[Error] Timestamp: '.date('c', time()));
|
||||
|
||||
|
||||
if($route) {
|
||||
Console::error('[Error] Method: '.$route->getMethod());
|
||||
Console::error('[Error] URL: '.$route->getPath());
|
||||
}
|
||||
|
||||
|
||||
Console::error('[Error] Type: '.get_class($error));
|
||||
Console::error('[Error] Message: '.$error->getMessage());
|
||||
Console::error('[Error] File: '.$error->getFile());
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\Abuse\Adapters\TimeLimit;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
|
||||
|
|
@ -141,6 +143,12 @@ App::init(function ($utopia, $request, $project) {
|
|||
}
|
||||
break;
|
||||
|
||||
case 'magic-url':
|
||||
if($project->getAttribute('usersAuthMagicURL', true) === false) {
|
||||
throw new Exception('Magic URL authentication is disabled for this project', 501);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'anonymous':
|
||||
if(($auths['anonymous'] ?? true) === false) {
|
||||
throw new Exception('Anonymous authentication is disabled for this project', 501);
|
||||
|
|
@ -166,7 +174,7 @@ App::init(function ($utopia, $request, $project) {
|
|||
|
||||
}, ['utopia', 'request', 'project'], 'auth');
|
||||
|
||||
App::shutdown(function ($utopia, $request, $response, $project, $register, $events, $audits, $usage, $deletes, $database, $mode) {
|
||||
App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $database, $mode) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
|
@ -176,7 +184,6 @@ App::shutdown(function ($utopia, $request, $response, $project, $register, $even
|
|||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $functions */
|
||||
/** @var bool $mode */
|
||||
|
||||
if (!empty($events->getParam('event'))) {
|
||||
|
|
@ -196,12 +203,29 @@ App::shutdown(function ($utopia, $request, $response, $project, $register, $even
|
|||
->setQueue('v1-functions')
|
||||
->setClass('FunctionsV1')
|
||||
->trigger();
|
||||
|
||||
if ($project->getId() !== 'console') {
|
||||
$payload = new Document($response->getPayload());
|
||||
$target = Realtime::fromPayload($events->getParam('event'), $payload);
|
||||
|
||||
Realtime::send(
|
||||
$project->getId(),
|
||||
$response->getPayload(),
|
||||
$events->getParam('event'),
|
||||
$target['channels'],
|
||||
$target['roles'],
|
||||
[
|
||||
'permissionsChanged' => $target['permissionsChanged'],
|
||||
'userId' => $events->getParam('userId')
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!empty($audits->getParam('event'))) {
|
||||
$audits->trigger();
|
||||
}
|
||||
|
||||
|
||||
if (!empty($deletes->getParam('type')) && !empty($deletes->getParam('document'))) {
|
||||
$deletes->trigger();
|
||||
}
|
||||
|
|
@ -209,13 +233,13 @@ App::shutdown(function ($utopia, $request, $response, $project, $register, $even
|
|||
if (!empty($database->getParam('type')) && !empty($database->getParam('document'))) {
|
||||
$database->trigger();
|
||||
}
|
||||
|
||||
|
||||
$route = $utopia->match($request);
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled'
|
||||
&& $project->getId()
|
||||
&& $mode !== APP_MODE_ADMIN // TODO: add check to make sure user is admin
|
||||
&& !empty($route->getLabel('sdk.namespace', null))) { // Don't calculate console usage on admin mode
|
||||
|
||||
|
||||
$usage
|
||||
->setParam('networkRequestSize', $request->getSize() + $usage->getParam('storage'))
|
||||
->setParam('networkResponseSize', $response->getSize())
|
||||
|
|
@ -223,4 +247,4 @@ App::shutdown(function ($utopia, $request, $response, $project, $register, $even
|
|||
;
|
||||
}
|
||||
|
||||
}, ['utopia', 'request', 'response', 'project', 'register', 'events', 'audits', 'usage', 'deletes', 'database', 'mode'], 'api');
|
||||
}, ['utopia', 'request', 'response', 'project', 'events', 'audits', 'usage', 'deletes', 'database', 'mode'], 'api');
|
||||
|
|
@ -328,6 +328,7 @@ App::get('/console/users')
|
|||
$page
|
||||
->setParam('auth', Config::getParam('auth'))
|
||||
->setParam('providers', Config::getParam('providers'))
|
||||
->setParam('smtpEnabled', (!empty(App::getEnv('_APP_SMTP_HOST'))))
|
||||
;
|
||||
|
||||
$layout
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue