Compare commits
130 Commits
v3.2.0-bet
...
v3.4.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38fdb38b92 | ||
|
|
bc0a38a857 | ||
|
|
f2c81b6a5c | ||
|
|
34c8d16c7d | ||
|
|
75f07a9d7f | ||
|
|
74f1c10826 | ||
|
|
168467d648 | ||
|
|
d527900991 | ||
|
|
f3acec7daf | ||
|
|
bbaa036d85 | ||
|
|
fc73e25d51 | ||
|
|
e50ffe7907 | ||
|
|
dda6a8c47f | ||
|
|
eba2df3dd9 | ||
|
|
11731f78d1 | ||
|
|
3a7b71ae3e | ||
|
|
3c3bd719db | ||
|
|
a6aa97bcfa | ||
|
|
1a7b6cfb99 | ||
|
|
da7cebdfed | ||
|
|
318f00993e | ||
|
|
4d061db29a | ||
|
|
39abb4fa02 | ||
|
|
91e3bbc9d9 | ||
|
|
415eea6fab | ||
|
|
ad5aa30b9f | ||
|
|
dcd6c5667d | ||
|
|
ff48fa320e | ||
|
|
5fe70b4bce | ||
|
|
854c10d13f | ||
|
|
7e158eb0d3 | ||
|
|
8b6194217e | ||
|
|
15d3bffd6d | ||
|
|
5dd3bd5f7e | ||
|
|
1d2530db6d | ||
|
|
b04af33fdb | ||
|
|
f3db19930a | ||
|
|
5a601277ab | ||
|
|
d5615bdcec | ||
|
|
58588d6663 | ||
|
|
2db7795eb7 | ||
|
|
dd5a9e2216 | ||
|
|
00d1543f08 | ||
|
|
d1eeb8c7f7 | ||
|
|
a98a91a394 | ||
|
|
5278fbea68 | ||
|
|
773942dc3b | ||
|
|
83483d6374 | ||
|
|
aab01b3195 | ||
|
|
fe5e07139f | ||
|
|
93a75324b8 | ||
|
|
67a01c196f | ||
|
|
483b1de701 | ||
|
|
40ceed6686 | ||
|
|
3878c629c6 | ||
|
|
31e874a34f | ||
|
|
74a346349a | ||
|
|
a9e8bf89a9 | ||
|
|
f824b84787 | ||
|
|
71b0c301f6 | ||
|
|
1c738b718a | ||
|
|
4dc6bc0c98 | ||
|
|
3436466cff | ||
|
|
84f550023a | ||
|
|
9923eb9b8f | ||
|
|
db43f1cb7a | ||
|
|
bedef0bbf2 | ||
|
|
2bfed23db3 | ||
|
|
85ad0d19c7 | ||
|
|
34b1c97db0 | ||
|
|
dc731cff10 | ||
|
|
ab4efdc66c | ||
|
|
4f883260b9 | ||
|
|
0cc85b5d85 | ||
|
|
e11d14fda0 | ||
|
|
7413b3f931 | ||
|
|
b24aab17b1 | ||
|
|
9a7847bc10 | ||
|
|
ef24a760e4 | ||
|
|
8a3fe9fb2c | ||
|
|
04b0a64b18 | ||
|
|
0774012058 | ||
|
|
2253b1bf68 | ||
|
|
10c6f7236d | ||
|
|
45d9d8c1d4 | ||
|
|
ea5b4cefbd | ||
|
|
02faabf688 | ||
|
|
eb36b2211b | ||
|
|
0761c2f5c1 | ||
|
|
476a455329 | ||
|
|
5ec60b8e39 | ||
|
|
5d190fa686 | ||
|
|
1fb9f13c16 | ||
|
|
4a077da11d | ||
|
|
adc8731fb7 | ||
|
|
d9cb738132 | ||
|
|
aeb827265b | ||
|
|
04a0dbb71e | ||
|
|
ed75b6b880 | ||
|
|
f7393da3bb | ||
|
|
529152f70b | ||
|
|
fcc45f6f61 | ||
|
|
8c7856b28c | ||
|
|
77e9fafa32 | ||
|
|
01e2b5e63d | ||
|
|
2d6baef810 | ||
|
|
afad78b7da | ||
|
|
74cd886e9c | ||
|
|
df34b13f25 | ||
|
|
61dfc91110 | ||
|
|
130e6facb7 | ||
|
|
525f4f3041 | ||
|
|
8a21345706 | ||
|
|
1169c633cc | ||
|
|
2242c9c1e6 | ||
|
|
939919df39 | ||
|
|
a579cf37ce | ||
|
|
2647aa07b4 | ||
|
|
f68c580e11 | ||
|
|
9b39a2b856 | ||
|
|
6d17ce699a | ||
|
|
20dbb35d44 | ||
|
|
36d9dd7354 | ||
|
|
5129f9bff8 | ||
|
|
496a56676d | ||
|
|
57e25524c7 | ||
|
|
614a9b468a | ||
|
|
94a5359080 | ||
|
|
38c5cd7b32 | ||
|
|
c664be5cc5 |
@@ -12,9 +12,6 @@ GITHUB_CLIENT_SECRET_FILE=github_client_secret_file
|
|||||||
GOOGLE_CLIENT_ID=google_client_id
|
GOOGLE_CLIENT_ID=google_client_id
|
||||||
GOOGLE_CLIENT_SECRET=google_client_secret
|
GOOGLE_CLIENT_SECRET=google_client_secret
|
||||||
GOOGLE_CLIENT_SECRET_FILE=google_client_secret_file
|
GOOGLE_CLIENT_SECRET_FILE=google_client_secret_file
|
||||||
TAILSCALE_CLIENT_ID=tailscale_client_id
|
|
||||||
TAILSCALE_CLIENT_SECRET=tailscale_client_secret
|
|
||||||
TAILSCALE_CLIENT_SECRET_FILE=tailscale__client_secret_file
|
|
||||||
GENERIC_CLIENT_ID=generic_client_id
|
GENERIC_CLIENT_ID=generic_client_id
|
||||||
GENERIC_CLIENT_SECRET=generic_client_secret
|
GENERIC_CLIENT_SECRET=generic_client_secret
|
||||||
GENERIC_CLIENT_SECRET_FILE=generic_client_secret_file
|
GENERIC_CLIENT_SECRET_FILE=generic_client_secret_file
|
||||||
@@ -29,4 +26,8 @@ SESSION_EXPIRY=7200
|
|||||||
LOGIN_TIMEOUT=300
|
LOGIN_TIMEOUT=300
|
||||||
LOGIN_MAX_RETRIES=5
|
LOGIN_MAX_RETRIES=5
|
||||||
LOG_LEVEL=0
|
LOG_LEVEL=0
|
||||||
APP_TITLE=Tinyauth SSO
|
APP_TITLE=Tinyauth SSO
|
||||||
|
FORGOT_PASSWORD_MESSAGE=Some message about resetting the password
|
||||||
|
OAUTH_AUTO_REDIRECT=none
|
||||||
|
BACKGROUND_IMAGE=some_image_url
|
||||||
|
GENERIC_SKIP_SSL=false
|
||||||
26
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "bun"
|
||||||
|
directory: "/frontend"
|
||||||
|
groups:
|
||||||
|
minor-patch:
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
- "minor"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "gomod"
|
||||||
|
directory: "/"
|
||||||
|
groups:
|
||||||
|
minor-patch:
|
||||||
|
update-types:
|
||||||
|
- "patch"
|
||||||
|
- "minor"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
18
.github/workflows/ci.yml
vendored
@@ -4,31 +4,31 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
ci:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Setup go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "^1.23.2"
|
go-version: "^1.23.2"
|
||||||
|
|
||||||
- name: Setup bun
|
|
||||||
uses: oven-sh/setup-bun@v2
|
|
||||||
with:
|
|
||||||
bun-version: latest
|
|
||||||
|
|
||||||
- name: Install frontend dependencies
|
- name: Install frontend dependencies
|
||||||
run: |
|
run: |
|
||||||
cd frontend
|
cd frontend
|
||||||
bun install
|
bun install
|
||||||
|
|
||||||
|
- name: Set version
|
||||||
|
run: |
|
||||||
|
echo testing > internal/assets/version
|
||||||
|
|
||||||
- name: Build frontend
|
- name: Build frontend
|
||||||
run: |
|
run: |
|
||||||
cd frontend
|
cd frontend
|
||||||
|
|||||||
298
.github/workflows/nightly.yml
vendored
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
name: Nightly Release
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Delete old release
|
||||||
|
run: gh release delete --cleanup-tag --yes nightly || echo release not found
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
OWNER: ${{ github.repository_owner }}
|
||||||
|
REPO: ${{ github.event.repository.name }}
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
prerelease: true
|
||||||
|
tag_name: nightly
|
||||||
|
|
||||||
|
generate-metadata:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: create-release
|
||||||
|
outputs:
|
||||||
|
VERSION: ${{ steps.metadata.outputs.VERSION }}
|
||||||
|
COMMIT_HASH: ${{ steps.metadata.outputs.COMMIT_HASH }}
|
||||||
|
BUILD_TIMESTAMP: ${{ steps.metadata.outputs.BUILD_TIMESTAMP }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
|
- name: Generate metadata
|
||||||
|
id: metadata
|
||||||
|
run: |
|
||||||
|
echo "VERSION=nightly" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "COMMIT_HASH=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "BUILD_TIMESTAMP=$(date '+%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
binary-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- create-release
|
||||||
|
- generate-metadata
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
|
- name: Install bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Install go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "^1.23.2"
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun install
|
||||||
|
|
||||||
|
- name: Install backend dependencies
|
||||||
|
run: |
|
||||||
|
go mod download
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cp -r frontend/dist internal/assets/dist
|
||||||
|
go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: tinyauth-amd64
|
||||||
|
path: tinyauth-amd64
|
||||||
|
|
||||||
|
binary-build-arm:
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
needs:
|
||||||
|
- create-release
|
||||||
|
- generate-metadata
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
|
- name: Install bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Install go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "^1.23.2"
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun install
|
||||||
|
|
||||||
|
- name: Install backend dependencies
|
||||||
|
run: |
|
||||||
|
go mod download
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cp -r frontend/dist internal/assets/dist
|
||||||
|
go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: tinyauth-arm64
|
||||||
|
path: tinyauth-arm64
|
||||||
|
|
||||||
|
image-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- create-release
|
||||||
|
- generate-metadata
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
id: build
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
tags: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
|
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
||||||
|
build-args: |
|
||||||
|
VERSION=${{ needs.generate-metadata.outputs.VERSION }}
|
||||||
|
COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }}
|
||||||
|
BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}
|
||||||
|
|
||||||
|
- name: Export digest
|
||||||
|
run: |
|
||||||
|
mkdir -p ${{ runner.temp }}/digests
|
||||||
|
digest="${{ steps.build.outputs.digest }}"
|
||||||
|
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||||
|
|
||||||
|
- name: Upload digest
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: digests-linux-amd64
|
||||||
|
path: ${{ runner.temp }}/digests/*
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
image-build-arm:
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
needs:
|
||||||
|
- create-release
|
||||||
|
- generate-metadata
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Set version
|
||||||
|
run: |
|
||||||
|
echo nightly > internal/assets/version
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
id: build
|
||||||
|
with:
|
||||||
|
platforms: linux/arm64
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
tags: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
|
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
||||||
|
build-args: |
|
||||||
|
VERSION=${{ needs.generate-metadata.outputs.VERSION }}
|
||||||
|
COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }}
|
||||||
|
BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}
|
||||||
|
|
||||||
|
- name: Export digest
|
||||||
|
run: |
|
||||||
|
mkdir -p ${{ runner.temp }}/digests
|
||||||
|
digest="${{ steps.build.outputs.digest }}"
|
||||||
|
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||||
|
|
||||||
|
- name: Upload digest
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: digests-linux-arm64
|
||||||
|
path: ${{ runner.temp }}/digests/*
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
image-merge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- image-build
|
||||||
|
- image-build-arm
|
||||||
|
steps:
|
||||||
|
- name: Download digests
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ${{ runner.temp }}/digests
|
||||||
|
pattern: digests-*
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.repository_owner }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
|
tags: |
|
||||||
|
type=raw,nightly
|
||||||
|
|
||||||
|
- name: Create manifest list and push
|
||||||
|
working-directory: ${{ runner.temp }}/digests
|
||||||
|
run: |
|
||||||
|
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
|
$(printf 'ghcr.io/${{ github.repository_owner }}/tinyauth@sha256:%s ' *)
|
||||||
|
|
||||||
|
update-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- binary-build
|
||||||
|
- binary-build-arm
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: tinyauth-*
|
||||||
|
path: binaries
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: binaries/*
|
||||||
|
tag_name: nightly
|
||||||
140
.github/workflows/release.yml
vendored
@@ -6,8 +6,111 @@ on:
|
|||||||
- "v*"
|
- "v*"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
generate-metadata:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
VERSION: ${{ steps.metadata.outputs.VERSION }}
|
||||||
|
COMMIT_HASH: ${{ steps.metadata.outputs.COMMIT_HASH }}
|
||||||
|
BUILD_TIMESTAMP: ${{ steps.metadata.outputs.BUILD_TIMESTAMP }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: nightly
|
||||||
|
|
||||||
|
- name: Generate metadata
|
||||||
|
id: metadata
|
||||||
|
run: |
|
||||||
|
echo "VERSION=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "COMMIT_HASH=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "BUILD_TIMESTAMP=$(date '+%Y-%m-%dT%H:%M:%S')" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
binary-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- generate-metadata
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Install go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "^1.23.2"
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun install
|
||||||
|
|
||||||
|
- name: Install backend dependencies
|
||||||
|
run: |
|
||||||
|
go mod download
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cp -r frontend/dist internal/assets/dist
|
||||||
|
go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-amd64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: tinyauth-amd64
|
||||||
|
path: tinyauth-amd64
|
||||||
|
|
||||||
|
binary-build-arm:
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
needs:
|
||||||
|
- generate-metadata
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Install go
|
||||||
|
uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "^1.23.2"
|
||||||
|
|
||||||
|
- name: Install frontend dependencies
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun install
|
||||||
|
|
||||||
|
- name: Install backend dependencies
|
||||||
|
run: |
|
||||||
|
go mod download
|
||||||
|
|
||||||
|
- name: Build frontend
|
||||||
|
run: |
|
||||||
|
cd frontend
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
cp -r frontend/dist internal/assets/dist
|
||||||
|
go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${{ needs.generate-metadata.outputs.VERSION }} -X tinyauth/internal/constants.CommitHash=${{ needs.generate-metadata.outputs.COMMIT_HASH }} -X tinyauth/internal/constants.BuildTimestamp=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}" -o tinyauth-arm64
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: tinyauth-arm64
|
||||||
|
path: tinyauth-arm64
|
||||||
|
|
||||||
|
image-build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- generate-metadata
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -36,6 +139,10 @@ jobs:
|
|||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
tags: ghcr.io/${{ github.repository_owner }}/tinyauth
|
tags: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
||||||
|
build-args: |
|
||||||
|
VERSION=${{ needs.generate-metadata.outputs.VERSION }}
|
||||||
|
COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }}
|
||||||
|
BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}
|
||||||
|
|
||||||
- name: Export digest
|
- name: Export digest
|
||||||
run: |
|
run: |
|
||||||
@@ -51,8 +158,10 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
build-arm:
|
image-build-arm:
|
||||||
runs-on: ubuntu-24.04-arm
|
runs-on: ubuntu-24.04-arm
|
||||||
|
needs:
|
||||||
|
- generate-metadata
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -81,6 +190,10 @@ jobs:
|
|||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
tags: ghcr.io/${{ github.repository_owner }}/tinyauth
|
tags: ghcr.io/${{ github.repository_owner }}/tinyauth
|
||||||
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
|
||||||
|
build-args: |
|
||||||
|
VERSION=${{ needs.generate-metadata.outputs.VERSION }}
|
||||||
|
COMMIT_HASH=${{ needs.generate-metadata.outputs.COMMIT_HASH }}
|
||||||
|
BUILD_TIMESTAMP=${{ needs.generate-metadata.outputs.BUILD_TIMESTAMP }}
|
||||||
|
|
||||||
- name: Export digest
|
- name: Export digest
|
||||||
run: |
|
run: |
|
||||||
@@ -96,11 +209,11 @@ jobs:
|
|||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
merge:
|
image-merge:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs:
|
||||||
- build
|
- image-build
|
||||||
- build-arm
|
- image-build-arm
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -134,3 +247,20 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||||
$(printf 'ghcr.io/${{ github.repository_owner }}/tinyauth@sha256:%s ' *)
|
$(printf 'ghcr.io/${{ github.repository_owner }}/tinyauth@sha256:%s ' *)
|
||||||
|
|
||||||
|
update-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- binary-build
|
||||||
|
- binary-build-arm
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: tinyauth-*
|
||||||
|
path: binaries
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: binaries/*
|
||||||
|
|||||||
31
.github/workflows/sponsors.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
name: Generate Sponsors List
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate-sponsors:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Generate Sponsors
|
||||||
|
uses: JamesIves/github-sponsors-readme-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.SPONSORS_GENERATOR_PAT }}
|
||||||
|
active-only: false
|
||||||
|
file: "README.md"
|
||||||
|
template: '<a href="https://github.com/{{{ login }}}"><img src="{{{ avatarUrl }}}" width="64px" alt="User avatar: {{{ login }}}" /></a> '
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
commit-message: |
|
||||||
|
docs: regenerate readme sponsors list
|
||||||
|
committer: GitHub <noreply@github.com>
|
||||||
|
author: GitHub <noreply@github.com>
|
||||||
|
branch: docs/update-readme
|
||||||
|
title: |
|
||||||
|
docs: regenerate readme sponsors list
|
||||||
|
labels: bot
|
||||||
20
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: Close stale issues and PRs
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: 0 10 * * *
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
days-before-stale: 30
|
||||||
|
stale-pr-message: This PR has been inactive for 30 days and will be marked as stale.
|
||||||
|
stale-issue-message: This issue has been inactive for 30 days and will be marked as stale.
|
||||||
|
close-issue-message: Closed for inactivity.
|
||||||
|
close-pr-message: Closed for inactivity.
|
||||||
|
stale-issue-label: stale
|
||||||
|
stale-pr-label: stale
|
||||||
|
exempt-issue-labels: pinned
|
||||||
|
exempt-pr-labels: pinned
|
||||||
98
.github/workflows/translations.yml
vendored
@@ -1,98 +0,0 @@
|
|||||||
name: Publish translations
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- i18n_v*
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: pages
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
get-branches:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
i18n-branches: ${{ steps.get-branches.outputs.result }}
|
|
||||||
steps:
|
|
||||||
- name: Get branches
|
|
||||||
id: get-branches
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const { data: repos } = await github.rest.repos.listBranches({
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
})
|
|
||||||
|
|
||||||
const i18nBranches = repos.filter((branch) => branch.name.startsWith("i18n_v"))
|
|
||||||
const i18nBranchNames = i18nBranches.map((branch) => branch.name)
|
|
||||||
|
|
||||||
return i18nBranchNames
|
|
||||||
|
|
||||||
get-translations:
|
|
||||||
needs: get-branches
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
branch: ${{ fromJson(needs.get-branches.outputs.i18n-branches) }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ matrix.branch }}
|
|
||||||
|
|
||||||
- name: Get translation version
|
|
||||||
id: get-version
|
|
||||||
run: |
|
|
||||||
branch=${{ matrix.branch }}
|
|
||||||
version=${branch#i18n_}
|
|
||||||
echo "version=$version" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Upload translations
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ steps.get-version.outputs.version }}
|
|
||||||
path: frontend/src/lib/i18n/locales
|
|
||||||
|
|
||||||
build:
|
|
||||||
needs: get-translations
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Pages
|
|
||||||
uses: actions/configure-pages@v4
|
|
||||||
|
|
||||||
- name: Prepare output directory
|
|
||||||
run: |
|
|
||||||
mkdir -p dist/i18n/
|
|
||||||
|
|
||||||
- name: Download translations
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: dist/i18n/
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-pages-artifact@v3
|
|
||||||
with:
|
|
||||||
path: dist
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Deploy
|
|
||||||
steps:
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
id: deployment
|
|
||||||
uses: actions/deploy-pages@v4
|
|
||||||
5
.gitignore
vendored
@@ -24,4 +24,7 @@ secret_oauth.txt
|
|||||||
.env
|
.env
|
||||||
|
|
||||||
# tmp directory
|
# tmp directory
|
||||||
tmp
|
tmp
|
||||||
|
|
||||||
|
# version files
|
||||||
|
internal/assets/version
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Contributing is relatively easy, you just need to follow the steps carefully and you will be up and running with a development server in less than 5 minutes.
|
Contributing is relatively easy, you just need to follow the steps below and you will be up and running with a development server in less than five minutes.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ cd tinyauth
|
|||||||
|
|
||||||
## Install requirements
|
## Install requirements
|
||||||
|
|
||||||
Although you will not need the requirements in your machine since the development will happen in docker, I still recommend to install them because this way you will not have import errors, to install the go requirements, run:
|
Although you will not need the requirements in your machine since the development will happen in docker, I still recommend to install them because this way you will not have import errors. To install the go requirements run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go mod tidy
|
go mod tidy
|
||||||
@@ -35,7 +35,7 @@ bun install
|
|||||||
|
|
||||||
## Create your `.env` file
|
## Create your `.env` file
|
||||||
|
|
||||||
In order to configure the app you need to create an environment file, this can be done by copying the `.env.example` file to `.env` and modifying the environment variables inside to suit your needs.
|
In order to configure the app you need to create an environment file, this can be done by copying the `.env.example` file to `.env` and modifying the environment variables to suit your needs.
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
@@ -46,11 +46,14 @@ I have designed the development workflow to be entirely in docker, this is becau
|
|||||||
dev.example.com -> 127.0.0.1
|
dev.example.com -> 127.0.0.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Then you can just make sure the domains are correct in the example docker compose file and run:
|
> [!TIP]
|
||||||
|
> You can use [sslip.io](https://sslip.io) as a domain if you don't have one to develop with.
|
||||||
|
|
||||||
|
Then you can just make sure the domains are correct in the development docker compose file and run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker compose -f docker-compose.dev.yml up --build
|
docker compose -f docker-compose.dev.yml up --build
|
||||||
```
|
```
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> I would recommend copying the example `docker-compose.dev.yml` into a `docker-compose.test.yml` file, so as you don't accidentally commit any sensitive information.
|
> I recommend copying the example `docker-compose.dev.yml` into a `docker-compose.test.yml` file, so as you don't accidentally commit any sensitive information.
|
||||||
|
|||||||
18
Dockerfile
@@ -1,10 +1,10 @@
|
|||||||
# Site builder
|
# Site builder
|
||||||
FROM oven/bun:1.1.45-alpine AS frontend-builder
|
FROM oven/bun:1.2.15-alpine AS frontend-builder
|
||||||
|
|
||||||
WORKDIR /frontend
|
WORKDIR /frontend
|
||||||
|
|
||||||
COPY ./frontend/package.json ./
|
COPY ./frontend/package.json ./
|
||||||
COPY ./frontend/bun.lockb ./
|
COPY ./frontend/bun.lock ./
|
||||||
|
|
||||||
RUN bun install
|
RUN bun install
|
||||||
|
|
||||||
@@ -16,12 +16,15 @@ COPY ./frontend/tsconfig.json ./
|
|||||||
COPY ./frontend/tsconfig.app.json ./
|
COPY ./frontend/tsconfig.app.json ./
|
||||||
COPY ./frontend/tsconfig.node.json ./
|
COPY ./frontend/tsconfig.node.json ./
|
||||||
COPY ./frontend/vite.config.ts ./
|
COPY ./frontend/vite.config.ts ./
|
||||||
COPY ./frontend/postcss.config.cjs ./
|
|
||||||
|
|
||||||
RUN bun run build
|
RUN bun run build
|
||||||
|
|
||||||
# Builder
|
# Builder
|
||||||
FROM golang:1.23-alpine3.21 AS builder
|
FROM golang:1.24-alpine3.21 AS builder
|
||||||
|
|
||||||
|
ARG VERSION
|
||||||
|
ARG COMMIT_HASH
|
||||||
|
ARG BUILD_TIMESTAMP
|
||||||
|
|
||||||
WORKDIR /tinyauth
|
WORKDIR /tinyauth
|
||||||
|
|
||||||
@@ -35,8 +38,8 @@ COPY ./cmd ./cmd
|
|||||||
COPY ./internal ./internal
|
COPY ./internal ./internal
|
||||||
COPY --from=frontend-builder /frontend/dist ./internal/assets/dist
|
COPY --from=frontend-builder /frontend/dist ./internal/assets/dist
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 go build -ldflags "-s -w"
|
RUN go build -ldflags "-s -w -X tinyauth/internal/constants.Version=${VERSION} -X tinyauth/internal/constants.CommitHash=${COMMIT_HASH} -X tinyauth/internal/constants.BuildTimestamp=${BUILD_TIMESTAMP}"
|
||||||
|
|
||||||
# Runner
|
# Runner
|
||||||
FROM alpine:3.21 AS runner
|
FROM alpine:3.21 AS runner
|
||||||
|
|
||||||
@@ -48,7 +51,4 @@ COPY --from=builder /tinyauth/tinyauth ./
|
|||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
HEALTHCHECK --interval=10s --timeout=5s \
|
|
||||||
CMD curl -f http://localhost:3000/api/healthcheck || exit 1
|
|
||||||
|
|
||||||
ENTRYPOINT ["./tinyauth"]
|
ENTRYPOINT ["./tinyauth"]
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.23-alpine3.21
|
FROM golang:1.24-alpine3.21
|
||||||
|
|
||||||
WORKDIR /tinyauth
|
WORKDIR /tinyauth
|
||||||
|
|
||||||
@@ -12,9 +12,6 @@ COPY ./internal ./internal
|
|||||||
COPY ./main.go ./
|
COPY ./main.go ./
|
||||||
COPY ./air.toml ./
|
COPY ./air.toml ./
|
||||||
|
|
||||||
RUN mkdir -p ./internal/assets/dist && \
|
|
||||||
echo "app running" > ./internal/assets/dist/index.html
|
|
||||||
|
|
||||||
RUN go install github.com/air-verse/air@v1.61.7
|
RUN go install github.com/air-verse/air@v1.61.7
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|||||||
33
README.md
@@ -1,5 +1,5 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<img alt="Tinyauth" title="Tinyauth" width="256" src="frontend/public/logo.png">
|
<img alt="Tinyauth" title="Tinyauth" width="96" src="assets/logo-rounded.png">
|
||||||
<h1>Tinyauth</h1>
|
<h1>Tinyauth</h1>
|
||||||
<p>The easiest way to secure your apps with a login screen.</p>
|
<p>The easiest way to secure your apps with a login screen.</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<img alt="License" src="https://img.shields.io/github/license/steveiliop56/tinyauth">
|
<img alt="License" src="https://img.shields.io/github/license/steveiliop56/tinyauth">
|
||||||
<img alt="Release" src="https://img.shields.io/github/v/release/steveiliop56/tinyauth">
|
<img alt="Release" src="https://img.shields.io/github/v/release/steveiliop56/tinyauth">
|
||||||
<img alt="Commit activity" src="https://img.shields.io/github/commit-activity/w/steveiliop56/tinyauth">
|
|
||||||
<img alt="Issues" src="https://img.shields.io/github/issues/steveiliop56/tinyauth">
|
<img alt="Issues" src="https://img.shields.io/github/issues/steveiliop56/tinyauth">
|
||||||
<img alt="Tinyauth CI" src="https://github.com/steveiliop56/tinyauth/actions/workflows/ci.yml/badge.svg">
|
<img alt="Tinyauth CI" src="https://github.com/steveiliop56/tinyauth/actions/workflows/ci.yml/badge.svg">
|
||||||
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/tinyauth"><img src="https://badges.crowdin.net/tinyauth/localized.svg"></a>
|
<a title="Crowdin" target="_blank" href="https://crowdin.com/project/tinyauth"><img src="https://badges.crowdin.net/tinyauth/localized.svg"></a>
|
||||||
@@ -15,25 +14,31 @@
|
|||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
Tinyauth is a simple authentication middleware that adds simple username/password login or OAuth with Google, Github and any generic OAuth provider to all of your docker apps. It is made for traefik but it can be extended to work with all reverse proxies like caddy and nginx.
|
Tinyauth is a simple authentication middleware that adds simple username/password login or OAuth with Google, Github and any generic provider to all of your docker apps. It is designed for traefik but it can be extended to work with other reverse proxies like caddy and nginx.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> Tinyauth is in active development and configuration may change often. Please make sure to carefully read the release notes before updating.
|
> Tinyauth is in active development and configuration may change often. Please make sure to carefully read the release notes before updating.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> Tinyauth is intended for homelab use and it is not made for production use cases. If you are looking for something production ready please use [authentik](https://goauthentik.io).
|
> Tinyauth is intended for homelab use only and it is not made for production use cases. If you are looking for something production ready please use [authentik](https://goauthentik.io) instead.
|
||||||
|
|
||||||
## Discord
|
|
||||||
|
|
||||||
I just made a Discord server for Tinyauth! It is not only for Tinyauth but general self-hosting because I just like chatting with people! The link is [here](https://discord.gg/eHzVaCzRRd), see you there!
|
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
You can easily get started with tinyauth by following the guide on the [documentation](https://tinyauth.app/docs/getting-started.html). There is also an available [docker compose file](./docker-compose.example.yml) that has traefik, nginx and tinyauth to demonstrate its capabilities.
|
You can easily get started with tinyauth by following the guide in the [documentation](https://tinyauth.app/docs/getting-started.html). There is also an available [docker compose file](./docker-compose.example.yml) that has traefik, whoami and tinyauth to demonstrate its capabilities.
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
If you are still not sure if tinyauth suits your needs you can try out the [demo](https://demo.tinyauth.app). The default username is `user` and the default password is `password`.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
You can find documentation and guides on all available configuration of tinyauth [here](https://tinyauth.app).
|
You can find documentation and guides on all of the available configuration of tinyauth in the [website](https://tinyauth.app).
|
||||||
|
|
||||||
|
## Discord
|
||||||
|
|
||||||
|
I just made a Discord server for tinyauth! It is not only for tinyauth but general self-hosting and homelabbing. [See you there!](https://discord.gg/eHzVaCzRRd).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -51,9 +56,7 @@ Tinyauth is licensed under the GNU General Public License v3.0. TL;DR — You ma
|
|||||||
|
|
||||||
Thanks a lot to the following people for providing me with more coffee:
|
Thanks a lot to the following people for providing me with more coffee:
|
||||||
|
|
||||||
| <img height="64" src="https://avatars.githubusercontent.com/u/47644445?v=4" alt="Nicolas"> | <img height="64" src="https://avatars.githubusercontent.com/u/4255748?v=4" alt="Erwin"> |
|
<!-- sponsors --><a href="https://github.com/erwinkramer"><img src="https://github.com/erwinkramer.png" width="64px" alt="User avatar: erwinkramer" /></a> <a href="https://github.com/nicotsx"><img src="https://github.com/nicotsx.png" width="64px" alt="User avatar: nicotsx" /></a> <a href="https://github.com/SimpleHomelab"><img src="https://github.com/SimpleHomelab.png" width="64px" alt="User avatar: SimpleHomelab" /></a> <a href="https://github.com/jmadden91"><img src="https://github.com/jmadden91.png" width="64px" alt="User avatar: jmadden91" /></a> <a href="https://github.com/tribor"><img src="https://github.com/tribor.png" width="64px" alt="User avatar: tribor" /></a> <a href="https://github.com/eliasbenb"><img src="https://github.com/eliasbenb.png" width="64px" alt="User avatar: eliasbenb" /></a> <!-- sponsors -->
|
||||||
| ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
|
|
||||||
| <div align="center"><a href="https://github.com/nicotsx">Nicolas</a></div> | <div align="center"><a href="https://github.com/erwinkramer">Erwin</a></div> |
|
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
@@ -61,7 +64,9 @@ Credits for the logo of this app go to:
|
|||||||
|
|
||||||
- **Freepik** for providing the police hat and badge.
|
- **Freepik** for providing the police hat and badge.
|
||||||
- **Renee French** for the original gopher logo.
|
- **Renee French** for the original gopher logo.
|
||||||
|
- **Coderabbit AI** for providing free AI code reviews.
|
||||||
|
- **Syrhu** for providing the bacgkround image of the app.
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
[](https://www.star-history.com/#steveiliop56/tinyauth&Date)
|
[](https://www.star-history.com/#steveiliop56/tinyauth&Date)
|
||||||
|
|||||||
1
air.toml
@@ -2,6 +2,7 @@ root = "/tinyauth"
|
|||||||
tmp_dir = "tmp"
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
|
pre_cmd = ["mkdir -p internal/assets/dist", "echo 'backend running' > internal/assets/dist/index.html"]
|
||||||
cmd = "go build -o ./tmp/tinyauth ."
|
cmd = "go build -o ./tmp/tinyauth ."
|
||||||
bin = "tmp/tinyauth"
|
bin = "tmp/tinyauth"
|
||||||
include_ext = ["go"]
|
include_ext = ["go"]
|
||||||
|
|||||||
BIN
assets/logo-rounded.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
assets/logo-solid.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
BIN
assets/screenshot.png
Normal file
|
After Width: | Height: | Size: 4.5 MiB |
97
cmd/root.go
@@ -2,14 +2,15 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
totpCmd "tinyauth/cmd/totp"
|
totpCmd "tinyauth/cmd/totp"
|
||||||
userCmd "tinyauth/cmd/user"
|
userCmd "tinyauth/cmd/user"
|
||||||
"tinyauth/internal/api"
|
"tinyauth/internal/api"
|
||||||
"tinyauth/internal/assets"
|
|
||||||
"tinyauth/internal/auth"
|
"tinyauth/internal/auth"
|
||||||
|
"tinyauth/internal/constants"
|
||||||
"tinyauth/internal/docker"
|
"tinyauth/internal/docker"
|
||||||
"tinyauth/internal/handlers"
|
"tinyauth/internal/handlers"
|
||||||
"tinyauth/internal/hooks"
|
"tinyauth/internal/hooks"
|
||||||
@@ -42,7 +43,6 @@ var rootCmd = &cobra.Command{
|
|||||||
config.GithubClientSecret = utils.GetSecret(config.GithubClientSecret, config.GithubClientSecretFile)
|
config.GithubClientSecret = utils.GetSecret(config.GithubClientSecret, config.GithubClientSecretFile)
|
||||||
config.GoogleClientSecret = utils.GetSecret(config.GoogleClientSecret, config.GoogleClientSecretFile)
|
config.GoogleClientSecret = utils.GetSecret(config.GoogleClientSecret, config.GoogleClientSecretFile)
|
||||||
config.GenericClientSecret = utils.GetSecret(config.GenericClientSecret, config.GenericClientSecretFile)
|
config.GenericClientSecret = utils.GetSecret(config.GenericClientSecret, config.GenericClientSecretFile)
|
||||||
config.TailscaleClientSecret = utils.GetSecret(config.TailscaleClientSecret, config.TailscaleClientSecretFile)
|
|
||||||
|
|
||||||
// Validate config
|
// Validate config
|
||||||
validator := validator.New()
|
validator := validator.New()
|
||||||
@@ -51,7 +51,7 @@ var rootCmd = &cobra.Command{
|
|||||||
|
|
||||||
// Logger
|
// Logger
|
||||||
log.Logger = log.Level(zerolog.Level(config.LogLevel))
|
log.Logger = log.Level(zerolog.Level(config.LogLevel))
|
||||||
log.Info().Str("version", assets.Version).Msg("Starting tinyauth")
|
log.Info().Str("version", strings.TrimSpace(constants.Version)).Msg("Starting tinyauth")
|
||||||
|
|
||||||
// Users
|
// Users
|
||||||
log.Info().Msg("Parsing users")
|
log.Info().Msg("Parsing users")
|
||||||
@@ -62,42 +62,47 @@ var rootCmd = &cobra.Command{
|
|||||||
HandleError(errors.New("no users or OAuth configured"), "No users or OAuth configured")
|
HandleError(errors.New("no users or OAuth configured"), "No users or OAuth configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create oauth whitelist
|
|
||||||
oauthWhitelist := utils.Filter(strings.Split(config.OAuthWhitelist, ","), func(val string) bool {
|
|
||||||
return val != ""
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Debug().Msg("Parsed OAuth whitelist")
|
|
||||||
|
|
||||||
// Get domain
|
// Get domain
|
||||||
log.Debug().Msg("Getting domain")
|
log.Debug().Msg("Getting domain")
|
||||||
domain, err := utils.GetUpperDomain(config.AppURL)
|
domain, err := utils.GetUpperDomain(config.AppURL)
|
||||||
HandleError(err, "Failed to get upper domain")
|
HandleError(err, "Failed to get upper domain")
|
||||||
log.Info().Str("domain", domain).Msg("Using domain for cookie store")
|
log.Info().Str("domain", domain).Msg("Using domain for cookie store")
|
||||||
|
|
||||||
|
// Generate cookie name
|
||||||
|
cookieId := utils.GenerateIdentifier(strings.Split(domain, ".")[0])
|
||||||
|
sessionCookieName := fmt.Sprintf("%s-%s", constants.SessionCookieName, cookieId)
|
||||||
|
csrfCookieName := fmt.Sprintf("%s-%s", constants.CsrfCookieName, cookieId)
|
||||||
|
redirectCookieName := fmt.Sprintf("%s-%s", constants.RedirectCookieName, cookieId)
|
||||||
|
|
||||||
// Create OAuth config
|
// Create OAuth config
|
||||||
oauthConfig := types.OAuthConfig{
|
oauthConfig := types.OAuthConfig{
|
||||||
GithubClientId: config.GithubClientId,
|
GithubClientId: config.GithubClientId,
|
||||||
GithubClientSecret: config.GithubClientSecret,
|
GithubClientSecret: config.GithubClientSecret,
|
||||||
GoogleClientId: config.GoogleClientId,
|
GoogleClientId: config.GoogleClientId,
|
||||||
GoogleClientSecret: config.GoogleClientSecret,
|
GoogleClientSecret: config.GoogleClientSecret,
|
||||||
TailscaleClientId: config.TailscaleClientId,
|
GenericClientId: config.GenericClientId,
|
||||||
TailscaleClientSecret: config.TailscaleClientSecret,
|
GenericClientSecret: config.GenericClientSecret,
|
||||||
GenericClientId: config.GenericClientId,
|
GenericScopes: strings.Split(config.GenericScopes, ","),
|
||||||
GenericClientSecret: config.GenericClientSecret,
|
GenericAuthURL: config.GenericAuthURL,
|
||||||
GenericScopes: strings.Split(config.GenericScopes, ","),
|
GenericTokenURL: config.GenericTokenURL,
|
||||||
GenericAuthURL: config.GenericAuthURL,
|
GenericUserURL: config.GenericUserURL,
|
||||||
GenericTokenURL: config.GenericTokenURL,
|
GenericSkipSSL: config.GenericSkipSSL,
|
||||||
GenericUserURL: config.GenericUserURL,
|
AppURL: config.AppURL,
|
||||||
AppURL: config.AppURL,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create handlers config
|
// Create handlers config
|
||||||
handlersConfig := types.HandlersConfig{
|
handlersConfig := types.HandlersConfig{
|
||||||
AppURL: config.AppURL,
|
AppURL: config.AppURL,
|
||||||
DisableContinue: config.DisableContinue,
|
DisableContinue: config.DisableContinue,
|
||||||
Title: config.Title,
|
Title: config.Title,
|
||||||
GenericName: config.GenericName,
|
GenericName: config.GenericName,
|
||||||
|
CookieSecure: config.CookieSecure,
|
||||||
|
Domain: domain,
|
||||||
|
ForgotPasswordMessage: config.FogotPasswordMessage,
|
||||||
|
BackgroundImage: config.BackgroundImage,
|
||||||
|
OAuthAutoRedirect: config.OAuthAutoRedirect,
|
||||||
|
CsrfCookieName: csrfCookieName,
|
||||||
|
RedirectCookieName: redirectCookieName,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create api config
|
// Create api config
|
||||||
@@ -108,14 +113,20 @@ var rootCmd = &cobra.Command{
|
|||||||
|
|
||||||
// Create auth config
|
// Create auth config
|
||||||
authConfig := types.AuthConfig{
|
authConfig := types.AuthConfig{
|
||||||
Users: users,
|
Users: users,
|
||||||
OauthWhitelist: oauthWhitelist,
|
OauthWhitelist: config.OAuthWhitelist,
|
||||||
Secret: config.Secret,
|
Secret: config.Secret,
|
||||||
CookieSecure: config.CookieSecure,
|
CookieSecure: config.CookieSecure,
|
||||||
SessionExpiry: config.SessionExpiry,
|
SessionExpiry: config.SessionExpiry,
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
LoginTimeout: config.LoginTimeout,
|
LoginTimeout: config.LoginTimeout,
|
||||||
LoginMaxRetries: config.LoginMaxRetries,
|
LoginMaxRetries: config.LoginMaxRetries,
|
||||||
|
SessionCookieName: sessionCookieName,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create hooks config
|
||||||
|
hooksConfig := types.HooksConfig{
|
||||||
|
Domain: domain,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create docker service
|
// Create docker service
|
||||||
@@ -135,7 +146,7 @@ var rootCmd = &cobra.Command{
|
|||||||
providers.Init()
|
providers.Init()
|
||||||
|
|
||||||
// Create hooks service
|
// Create hooks service
|
||||||
hooks := hooks.NewHooks(auth, providers)
|
hooks := hooks.NewHooks(hooksConfig, auth, providers)
|
||||||
|
|
||||||
// Create handlers
|
// Create handlers
|
||||||
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker)
|
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker)
|
||||||
@@ -189,9 +200,6 @@ func init() {
|
|||||||
rootCmd.Flags().String("google-client-id", "", "Google OAuth client ID.")
|
rootCmd.Flags().String("google-client-id", "", "Google OAuth client ID.")
|
||||||
rootCmd.Flags().String("google-client-secret", "", "Google OAuth client secret.")
|
rootCmd.Flags().String("google-client-secret", "", "Google OAuth client secret.")
|
||||||
rootCmd.Flags().String("google-client-secret-file", "", "Google OAuth client secret file.")
|
rootCmd.Flags().String("google-client-secret-file", "", "Google OAuth client secret file.")
|
||||||
rootCmd.Flags().String("tailscale-client-id", "", "Tailscale OAuth client ID.")
|
|
||||||
rootCmd.Flags().String("tailscale-client-secret", "", "Tailscale OAuth client secret.")
|
|
||||||
rootCmd.Flags().String("tailscale-client-secret-file", "", "Tailscale OAuth client secret file.")
|
|
||||||
rootCmd.Flags().String("generic-client-id", "", "Generic OAuth client ID.")
|
rootCmd.Flags().String("generic-client-id", "", "Generic OAuth client ID.")
|
||||||
rootCmd.Flags().String("generic-client-secret", "", "Generic OAuth client secret.")
|
rootCmd.Flags().String("generic-client-secret", "", "Generic OAuth client secret.")
|
||||||
rootCmd.Flags().String("generic-client-secret-file", "", "Generic OAuth client secret file.")
|
rootCmd.Flags().String("generic-client-secret-file", "", "Generic OAuth client secret file.")
|
||||||
@@ -200,13 +208,17 @@ func init() {
|
|||||||
rootCmd.Flags().String("generic-token-url", "", "Generic OAuth token URL.")
|
rootCmd.Flags().String("generic-token-url", "", "Generic OAuth token URL.")
|
||||||
rootCmd.Flags().String("generic-user-url", "", "Generic OAuth user info URL.")
|
rootCmd.Flags().String("generic-user-url", "", "Generic OAuth user info URL.")
|
||||||
rootCmd.Flags().String("generic-name", "Generic", "Generic OAuth provider name.")
|
rootCmd.Flags().String("generic-name", "Generic", "Generic OAuth provider name.")
|
||||||
|
rootCmd.Flags().Bool("generic-skip-ssl", false, "Skip SSL verification for the generic OAuth provider.")
|
||||||
rootCmd.Flags().Bool("disable-continue", false, "Disable continue screen and redirect to app directly.")
|
rootCmd.Flags().Bool("disable-continue", false, "Disable continue screen and redirect to app directly.")
|
||||||
rootCmd.Flags().String("oauth-whitelist", "", "Comma separated list of email addresses to whitelist when using OAuth.")
|
rootCmd.Flags().String("oauth-whitelist", "", "Comma separated list of email addresses to whitelist when using OAuth.")
|
||||||
|
rootCmd.Flags().String("oauth-auto-redirect", "none", "Auto redirect to the specified OAuth provider if configured. (available providers: github, google, generic)")
|
||||||
rootCmd.Flags().Int("session-expiry", 86400, "Session (cookie) expiration time in seconds.")
|
rootCmd.Flags().Int("session-expiry", 86400, "Session (cookie) expiration time in seconds.")
|
||||||
rootCmd.Flags().Int("login-timeout", 300, "Login timeout in seconds after max retries reached (0 to disable).")
|
rootCmd.Flags().Int("login-timeout", 300, "Login timeout in seconds after max retries reached (0 to disable).")
|
||||||
rootCmd.Flags().Int("login-max-retries", 5, "Maximum login attempts before timeout (0 to disable).")
|
rootCmd.Flags().Int("login-max-retries", 5, "Maximum login attempts before timeout (0 to disable).")
|
||||||
rootCmd.Flags().Int("log-level", 1, "Log level.")
|
rootCmd.Flags().Int("log-level", 1, "Log level.")
|
||||||
rootCmd.Flags().String("app-title", "Tinyauth", "Title of the app.")
|
rootCmd.Flags().String("app-title", "Tinyauth", "Title of the app.")
|
||||||
|
rootCmd.Flags().String("forgot-password-message", "You can reset your password by changing the `USERS` environment variable.", "Message to show on the forgot password page.")
|
||||||
|
rootCmd.Flags().String("background-image", "/background.jpg", "Background image URL for the login page.")
|
||||||
|
|
||||||
// Bind flags to environment
|
// Bind flags to environment
|
||||||
viper.BindEnv("port", "PORT")
|
viper.BindEnv("port", "PORT")
|
||||||
@@ -223,9 +235,6 @@ func init() {
|
|||||||
viper.BindEnv("google-client-id", "GOOGLE_CLIENT_ID")
|
viper.BindEnv("google-client-id", "GOOGLE_CLIENT_ID")
|
||||||
viper.BindEnv("google-client-secret", "GOOGLE_CLIENT_SECRET")
|
viper.BindEnv("google-client-secret", "GOOGLE_CLIENT_SECRET")
|
||||||
viper.BindEnv("google-client-secret-file", "GOOGLE_CLIENT_SECRET_FILE")
|
viper.BindEnv("google-client-secret-file", "GOOGLE_CLIENT_SECRET_FILE")
|
||||||
viper.BindEnv("tailscale-client-id", "TAILSCALE_CLIENT_ID")
|
|
||||||
viper.BindEnv("tailscale-client-secret", "TAILSCALE_CLIENT_SECRET")
|
|
||||||
viper.BindEnv("tailscale-client-secret-file", "TAILSCALE_CLIENT_SECRET_FILE")
|
|
||||||
viper.BindEnv("generic-client-id", "GENERIC_CLIENT_ID")
|
viper.BindEnv("generic-client-id", "GENERIC_CLIENT_ID")
|
||||||
viper.BindEnv("generic-client-secret", "GENERIC_CLIENT_SECRET")
|
viper.BindEnv("generic-client-secret", "GENERIC_CLIENT_SECRET")
|
||||||
viper.BindEnv("generic-client-secret-file", "GENERIC_CLIENT_SECRET_FILE")
|
viper.BindEnv("generic-client-secret-file", "GENERIC_CLIENT_SECRET_FILE")
|
||||||
@@ -234,13 +243,17 @@ func init() {
|
|||||||
viper.BindEnv("generic-token-url", "GENERIC_TOKEN_URL")
|
viper.BindEnv("generic-token-url", "GENERIC_TOKEN_URL")
|
||||||
viper.BindEnv("generic-user-url", "GENERIC_USER_URL")
|
viper.BindEnv("generic-user-url", "GENERIC_USER_URL")
|
||||||
viper.BindEnv("generic-name", "GENERIC_NAME")
|
viper.BindEnv("generic-name", "GENERIC_NAME")
|
||||||
|
viper.BindEnv("generic-skip-ssl", "GENERIC_SKIP_SSL")
|
||||||
viper.BindEnv("disable-continue", "DISABLE_CONTINUE")
|
viper.BindEnv("disable-continue", "DISABLE_CONTINUE")
|
||||||
viper.BindEnv("oauth-whitelist", "OAUTH_WHITELIST")
|
viper.BindEnv("oauth-whitelist", "OAUTH_WHITELIST")
|
||||||
|
viper.BindEnv("oauth-auto-redirect", "OAUTH_AUTO_REDIRECT")
|
||||||
viper.BindEnv("session-expiry", "SESSION_EXPIRY")
|
viper.BindEnv("session-expiry", "SESSION_EXPIRY")
|
||||||
viper.BindEnv("log-level", "LOG_LEVEL")
|
viper.BindEnv("log-level", "LOG_LEVEL")
|
||||||
viper.BindEnv("app-title", "APP_TITLE")
|
viper.BindEnv("app-title", "APP_TITLE")
|
||||||
viper.BindEnv("login-timeout", "LOGIN_TIMEOUT")
|
viper.BindEnv("login-timeout", "LOGIN_TIMEOUT")
|
||||||
viper.BindEnv("login-max-retries", "LOGIN_MAX_RETRIES")
|
viper.BindEnv("login-max-retries", "LOGIN_MAX_RETRIES")
|
||||||
|
viper.BindEnv("forgot-password-message", "FORGOT_PASSWORD_MESSAGE")
|
||||||
|
viper.BindEnv("background-image", "BACKGROUND_IMAGE")
|
||||||
|
|
||||||
// Bind flags to viper
|
// Bind flags to viper
|
||||||
viper.BindPFlags(rootCmd.Flags())
|
viper.BindPFlags(rootCmd.Flags())
|
||||||
|
|||||||
24
cmd/version.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"tinyauth/internal/constants"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create the version command
|
||||||
|
var versionCmd = &cobra.Command{
|
||||||
|
Use: "version",
|
||||||
|
Short: "Print the version number of Tinyauth",
|
||||||
|
Long: `All software has versions. This is Tinyauth's`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
fmt.Printf("Version: %s\n", constants.Version)
|
||||||
|
fmt.Printf("Commit Hash: %s\n", constants.CommitHash)
|
||||||
|
fmt.Printf("Build Timestamp: %s\n", constants.BuildTimestamp)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(versionCmd)
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
# Ignore artifacts:
|
# Ignore artifacts:
|
||||||
dist
|
dist
|
||||||
node_modules
|
node_modules
|
||||||
|
bun.lock
|
||||||
|
package.json
|
||||||
|
src/lib/i18n/locales
|
||||||
@@ -3,7 +3,7 @@ FROM oven/bun:1.1.45-alpine
|
|||||||
WORKDIR /frontend
|
WORKDIR /frontend
|
||||||
|
|
||||||
COPY ./frontend/package.json ./
|
COPY ./frontend/package.json ./
|
||||||
COPY ./frontend/bun.lockb ./
|
COPY ./frontend/bun.lock ./
|
||||||
|
|
||||||
RUN bun install
|
RUN bun install
|
||||||
|
|
||||||
@@ -16,7 +16,6 @@ COPY ./frontend/tsconfig.json ./
|
|||||||
COPY ./frontend/tsconfig.app.json ./
|
COPY ./frontend/tsconfig.app.json ./
|
||||||
COPY ./frontend/tsconfig.node.json ./
|
COPY ./frontend/tsconfig.node.json ./
|
||||||
COPY ./frontend/vite.config.ts ./
|
COPY ./frontend/vite.config.ts ./
|
||||||
COPY ./frontend/postcss.config.cjs ./
|
|
||||||
|
|
||||||
EXPOSE 5173
|
EXPOSE 5173
|
||||||
|
|
||||||
|
|||||||
1055
frontend/bun.lock
Normal file
21
frontend/components.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://ui.shadcn.com/schema.json",
|
||||||
|
"style": "new-york",
|
||||||
|
"rsc": false,
|
||||||
|
"tsx": true,
|
||||||
|
"tailwind": {
|
||||||
|
"config": "",
|
||||||
|
"css": "src/index.css",
|
||||||
|
"baseColor": "neutral",
|
||||||
|
"cssVariables": true,
|
||||||
|
"prefix": ""
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"components": "@/components",
|
||||||
|
"utils": "@/lib/utils",
|
||||||
|
"ui": "@/components/ui",
|
||||||
|
"lib": "@/lib",
|
||||||
|
"hooks": "@/hooks"
|
||||||
|
},
|
||||||
|
"iconLibrary": "lucide"
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import globals from "globals";
|
|||||||
import reactHooks from "eslint-plugin-react-hooks";
|
import reactHooks from "eslint-plugin-react-hooks";
|
||||||
import reactRefresh from "eslint-plugin-react-refresh";
|
import reactRefresh from "eslint-plugin-react-refresh";
|
||||||
import tseslint from "typescript-eslint";
|
import tseslint from "typescript-eslint";
|
||||||
|
import pluginQuery from "@tanstack/eslint-plugin-query";
|
||||||
|
|
||||||
export default tseslint.config(
|
export default tseslint.config(
|
||||||
{ ignores: ["dist"] },
|
{ ignores: ["dist"] },
|
||||||
@@ -16,6 +17,7 @@ export default tseslint.config(
|
|||||||
plugins: {
|
plugins: {
|
||||||
"react-hooks": reactHooks,
|
"react-hooks": reactHooks,
|
||||||
"react-refresh": reactRefresh,
|
"react-refresh": reactRefresh,
|
||||||
|
"@tanstack/query": pluginQuery,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
...reactHooks.configs.recommended.rules,
|
...reactHooks.configs.recommended.rules,
|
||||||
@@ -23,6 +25,7 @@ export default tseslint.config(
|
|||||||
"warn",
|
"warn",
|
||||||
{ allowConstantExport: true },
|
{ allowConstantExport: true },
|
||||||
],
|
],
|
||||||
|
"@tanstack/query/exhaustive-deps": "error",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,13 +3,15 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<link rel="shortcut icon" href="/favicon.ico" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
<meta name="apple-mobile-web-app-title" content="Tinyauth" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
<link rel="manifest" href="/site.webmanifest" />
|
||||||
<link rel="manifest" href="/frontend.webmanifest" />
|
|
||||||
<title>Tinyauth</title>
|
<title>Tinyauth</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body class="dark">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.tsx"></script>
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
2249
frontend/package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "frontend",
|
"name": "tinyauth-shadcn",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -10,38 +10,49 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mantine/core": "^7.16.0",
|
"@hookform/resolvers": "^5.0.1",
|
||||||
"@mantine/form": "^7.16.0",
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
"@mantine/hooks": "^7.16.0",
|
"@radix-ui/react-select": "^2.2.5",
|
||||||
"@mantine/notifications": "^7.16.0",
|
"@radix-ui/react-separator": "^1.1.7",
|
||||||
"@tanstack/react-query": "4",
|
"@radix-ui/react-slot": "^1.2.3",
|
||||||
"axios": "^1.7.9",
|
"@tailwindcss/vite": "^4.1.8",
|
||||||
"i18next": "^24.2.3",
|
"@tanstack/react-query": "^5.79.0",
|
||||||
"i18next-browser-languagedetector": "^8.0.4",
|
"axios": "^1.9.0",
|
||||||
"i18next-chained-backend": "^4.6.2",
|
"class-variance-authority": "^0.7.1",
|
||||||
"i18next-http-backend": "^3.0.2",
|
"clsx": "^2.1.1",
|
||||||
|
"dompurify": "^3.2.6",
|
||||||
|
"i18next": "^25.2.1",
|
||||||
|
"i18next-browser-languagedetector": "^8.0.5",
|
||||||
"i18next-resources-to-backend": "^1.2.1",
|
"i18next-resources-to-backend": "^1.2.1",
|
||||||
"react": "^18.3.1",
|
"input-otp": "^1.4.2",
|
||||||
"react-dom": "^18.3.1",
|
"lucide-react": "^0.511.0",
|
||||||
"react-i18next": "^15.4.1",
|
"next-themes": "^0.4.6",
|
||||||
"react-router": "^7.1.3",
|
"react": "^19.0.0",
|
||||||
"zod": "^3.24.1"
|
"react-dom": "^19.0.0",
|
||||||
|
"react-hook-form": "^7.56.4",
|
||||||
|
"react-i18next": "^15.5.2",
|
||||||
|
"react-markdown": "^10.1.0",
|
||||||
|
"react-router": "^7.6.1",
|
||||||
|
"sonner": "^2.0.3",
|
||||||
|
"tailwind-merge": "^3.3.0",
|
||||||
|
"tailwindcss": "^4.1.8",
|
||||||
|
"zod": "^3.25.42"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.17.0",
|
"@eslint/js": "^9.27.0",
|
||||||
"@types/react": "^18.3.18",
|
"@tanstack/eslint-plugin-query": "^5.78.0",
|
||||||
"@types/react-dom": "^18.3.5",
|
"@types/node": "^22.15.27",
|
||||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
"@types/react": "^19.1.6",
|
||||||
"eslint": "^9.17.0",
|
"@types/react-dom": "^19.1.5",
|
||||||
"eslint-plugin-react-hooks": "^5.0.0",
|
"@vitejs/plugin-react": "^4.5.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.16",
|
"eslint": "^9.27.0",
|
||||||
"globals": "^15.14.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"postcss": "^8.5.1",
|
"eslint-plugin-react-refresh": "^0.4.19",
|
||||||
"postcss-preset-mantine": "^1.17.0",
|
"globals": "^16.2.0",
|
||||||
"postcss-simple-vars": "^7.0.1",
|
"prettier": "3.5.3",
|
||||||
"prettier": "3.4.2",
|
"tw-animate-css": "^1.3.2",
|
||||||
"typescript": "~5.6.2",
|
"typescript": "~5.8.3",
|
||||||
"typescript-eslint": "^8.18.2",
|
"typescript-eslint": "^8.33.0",
|
||||||
"vite": "^6.0.5"
|
"vite": "^6.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
plugins: {
|
|
||||||
"postcss-preset-mantine": {},
|
|
||||||
"postcss-simple-vars": {
|
|
||||||
variables: {
|
|
||||||
"mantine-breakpoint-xs": "36em",
|
|
||||||
"mantine-breakpoint-sm": "48em",
|
|
||||||
"mantine-breakpoint-md": "62em",
|
|
||||||
"mantine-breakpoint-lg": "75em",
|
|
||||||
"mantine-breakpoint-xl": "88em",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.6 KiB |
BIN
frontend/public/background.jpg
Normal file
|
After Width: | Height: | Size: 530 KiB |
|
Before Width: | Height: | Size: 602 B |
|
Before Width: | Height: | Size: 1.4 KiB |
BIN
frontend/public/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
3
frontend/public/favicon.svg
Normal file
|
After Width: | Height: | Size: 48 KiB |
@@ -1 +1,21 @@
|
|||||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
{
|
||||||
|
"name": "Tinyauth",
|
||||||
|
"short_name": "Tinyauth",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/web-app-manifest-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/web-app-manifest-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#171717",
|
||||||
|
"background_color": "#171717",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
||||||
|
|||||||
BIN
frontend/public/web-app-manifest-192x192.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
frontend/public/web-app-manifest-512x512.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
@@ -1,17 +1,12 @@
|
|||||||
import { Navigate } from "react-router";
|
import { Navigate } from "react-router";
|
||||||
import { useUserContext } from "./context/user-context";
|
import { useUserContext } from "./context/user-context";
|
||||||
import { LogoutPage } from "./pages/logout-page";
|
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const queryString = window.location.search;
|
|
||||||
const params = new URLSearchParams(queryString);
|
|
||||||
const redirectUri = params.get("redirect_uri");
|
|
||||||
|
|
||||||
const { isLoggedIn } = useUserContext();
|
const { isLoggedIn } = useUserContext();
|
||||||
|
|
||||||
if (!isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
return <Navigate to={`/login?redirect_uri=${redirectUri}`} />;
|
return <Navigate to="/logout" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <LogoutPage />;
|
return <Navigate to="/login" />;
|
||||||
};
|
};
|
||||||
|
|||||||
81
frontend/src/components/auth/login-form.tsx
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Input } from "../ui/input";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "../ui/form";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
import { loginSchema, LoginSchema } from "@/schemas/login-schema";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
onSubmit: (data: LoginSchema) => void;
|
||||||
|
loading?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LoginForm = (props: Props) => {
|
||||||
|
const { onSubmit, loading } = props;
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const form = useForm<LoginSchema>({
|
||||||
|
resolver: zodResolver(loginSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Form {...form}>
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="username"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="mb-4">
|
||||||
|
<FormLabel>{t("loginUsername")}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder={t("loginUsername")}
|
||||||
|
disabled={loading}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="password"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="mb-4">
|
||||||
|
<div className="relative">
|
||||||
|
<FormLabel className="mb-2">{t("loginPassword")}</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input
|
||||||
|
placeholder={t("loginPassword")}
|
||||||
|
type="password"
|
||||||
|
disabled={loading}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
<a
|
||||||
|
href="/forgot-password"
|
||||||
|
className="text-muted-foreground text-sm absolute right-0 bottom-10"
|
||||||
|
>
|
||||||
|
{t("forgotPasswordTitle")}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button className="w-full" type="submit" loading={loading}>
|
||||||
|
{t("loginSubmit")}
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import { TextInput, PasswordInput, Button } from "@mantine/core";
|
|
||||||
import { useForm, zodResolver } from "@mantine/form";
|
|
||||||
import { LoginFormValues, loginSchema } from "../../schemas/login-schema";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
interface LoginFormProps {
|
|
||||||
isLoading: boolean;
|
|
||||||
onSubmit: (values: LoginFormValues) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LoginForm = (props: LoginFormProps) => {
|
|
||||||
const { isLoading, onSubmit } = props;
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const form = useForm({
|
|
||||||
mode: "uncontrolled",
|
|
||||||
initialValues: {
|
|
||||||
username: "",
|
|
||||||
password: "",
|
|
||||||
},
|
|
||||||
validate: zodResolver(loginSchema),
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
|
||||||
<TextInput
|
|
||||||
label={t("loginUsername")}
|
|
||||||
placeholder="user@example.com"
|
|
||||||
required
|
|
||||||
disabled={isLoading}
|
|
||||||
key={form.key("username")}
|
|
||||||
{...form.getInputProps("username")}
|
|
||||||
/>
|
|
||||||
<PasswordInput
|
|
||||||
label={t("loginPassword")}
|
|
||||||
placeholder="password"
|
|
||||||
required
|
|
||||||
mt="md"
|
|
||||||
disabled={isLoading}
|
|
||||||
key={form.key("password")}
|
|
||||||
{...form.getInputProps("password")}
|
|
||||||
/>
|
|
||||||
<Button fullWidth mt="xl" type="submit" loading={isLoading}>
|
|
||||||
{t("loginSubmit")}
|
|
||||||
</Button>
|
|
||||||
</form>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
import { Grid, Button } from "@mantine/core";
|
|
||||||
import { GithubIcon } from "../../icons/github";
|
|
||||||
import { GoogleIcon } from "../../icons/google";
|
|
||||||
import { OAuthIcon } from "../../icons/oauth";
|
|
||||||
import { TailscaleIcon } from "../../icons/tailscale";
|
|
||||||
|
|
||||||
interface OAuthButtonsProps {
|
|
||||||
oauthProviders: string[];
|
|
||||||
isLoading: boolean;
|
|
||||||
mutate: (provider: string) => void;
|
|
||||||
genericName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const OAuthButtons = (props: OAuthButtonsProps) => {
|
|
||||||
const { oauthProviders, isLoading, genericName, mutate } = props;
|
|
||||||
return (
|
|
||||||
<Grid mb="md" mt="md" align="center" justify="center">
|
|
||||||
{oauthProviders.includes("google") && (
|
|
||||||
<Grid.Col span="content">
|
|
||||||
<Button
|
|
||||||
radius="xl"
|
|
||||||
leftSection={<GoogleIcon style={{ width: 14, height: 14 }} />}
|
|
||||||
variant="default"
|
|
||||||
onClick={() => mutate("google")}
|
|
||||||
loading={isLoading}
|
|
||||||
>
|
|
||||||
Google
|
|
||||||
</Button>
|
|
||||||
</Grid.Col>
|
|
||||||
)}
|
|
||||||
{oauthProviders.includes("github") && (
|
|
||||||
<Grid.Col span="content">
|
|
||||||
<Button
|
|
||||||
radius="xl"
|
|
||||||
leftSection={<GithubIcon style={{ width: 14, height: 14 }} />}
|
|
||||||
variant="default"
|
|
||||||
onClick={() => mutate("github")}
|
|
||||||
loading={isLoading}
|
|
||||||
>
|
|
||||||
Github
|
|
||||||
</Button>
|
|
||||||
</Grid.Col>
|
|
||||||
)}
|
|
||||||
{oauthProviders.includes("tailscale") && (
|
|
||||||
<Grid.Col span="content">
|
|
||||||
<Button
|
|
||||||
radius="xl"
|
|
||||||
leftSection={<TailscaleIcon style={{ width: 14, height: 14 }} />}
|
|
||||||
variant="default"
|
|
||||||
onClick={() => mutate("tailscale")}
|
|
||||||
loading={isLoading}
|
|
||||||
>
|
|
||||||
Tailscale
|
|
||||||
</Button>
|
|
||||||
</Grid.Col>
|
|
||||||
)}
|
|
||||||
{oauthProviders.includes("generic") && (
|
|
||||||
<Grid.Col span="content">
|
|
||||||
<Button
|
|
||||||
radius="xl"
|
|
||||||
leftSection={<OAuthIcon style={{ width: 14, height: 14 }} />}
|
|
||||||
variant="default"
|
|
||||||
onClick={() => mutate("generic")}
|
|
||||||
loading={isLoading}
|
|
||||||
>
|
|
||||||
{genericName}
|
|
||||||
</Button>
|
|
||||||
</Grid.Col>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,40 +1,54 @@
|
|||||||
import { Button, PinInput } from "@mantine/core";
|
import { Form, FormControl, FormField, FormItem } from "../ui/form";
|
||||||
import { useForm, zodResolver } from "@mantine/form";
|
import {
|
||||||
import { z } from "zod";
|
InputOTP,
|
||||||
|
InputOTPGroup,
|
||||||
|
InputOTPSeparator,
|
||||||
|
InputOTPSlot,
|
||||||
|
} from "../ui/input-otp";
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import { totpSchema, TotpSchema } from "@/schemas/totp-schema";
|
||||||
|
|
||||||
const schema = z.object({
|
interface Props {
|
||||||
code: z.string(),
|
formId: string;
|
||||||
});
|
onSubmit: (code: TotpSchema) => void;
|
||||||
|
loading?: boolean;
|
||||||
type FormValues = z.infer<typeof schema>;
|
|
||||||
|
|
||||||
interface TotpFormProps {
|
|
||||||
onSubmit: (values: FormValues) => void;
|
|
||||||
isLoading: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TotpForm = (props: TotpFormProps) => {
|
export const TotpForm = (props: Props) => {
|
||||||
const { onSubmit, isLoading } = props;
|
const { formId, onSubmit, loading } = props;
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm<TotpSchema>({
|
||||||
mode: "uncontrolled",
|
resolver: zodResolver(totpSchema),
|
||||||
initialValues: {
|
|
||||||
code: "",
|
|
||||||
},
|
|
||||||
validate: zodResolver(schema),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
<Form {...form}>
|
||||||
<PinInput
|
<form id={formId} onSubmit={form.handleSubmit(onSubmit)}>
|
||||||
length={6}
|
<FormField
|
||||||
type={"number"}
|
control={form.control}
|
||||||
placeholder=""
|
name="code"
|
||||||
{...form.getInputProps("code")}
|
render={({ field }) => (
|
||||||
/>
|
<FormItem>
|
||||||
<Button type="submit" mt="xl" loading={isLoading} fullWidth>
|
<FormControl>
|
||||||
Verify
|
<InputOTP maxLength={6} disabled={loading} {...field}>
|
||||||
</Button>
|
<InputOTPGroup>
|
||||||
</form>
|
<InputOTPSlot index={0} />
|
||||||
|
<InputOTPSlot index={1} />
|
||||||
|
<InputOTPSlot index={2} />
|
||||||
|
</InputOTPGroup>
|
||||||
|
<InputOTPSeparator />
|
||||||
|
<InputOTPGroup>
|
||||||
|
<InputOTPSlot index={3} />
|
||||||
|
<InputOTPSlot index={4} />
|
||||||
|
<InputOTPSlot index={5} />
|
||||||
|
</InputOTPGroup>
|
||||||
|
</InputOTP>
|
||||||
|
</FormControl>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { SVGProps } from "react";
|
import type { SVGProps } from "react";
|
||||||
|
|
||||||
export function OAuthIcon(props: SVGProps<SVGSVGElement>) {
|
export function GenericIcon(props: SVGProps<SVGSVGElement>) {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
30
frontend/src/components/icons/google.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import type { SVGProps } from "react";
|
||||||
|
|
||||||
|
export function GoogleIcon(props: SVGProps<SVGSVGElement>) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width={256}
|
||||||
|
height={262}
|
||||||
|
viewBox="0 0 256 262"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="#4285f4"
|
||||||
|
d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622l38.755 30.023l2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill="#34a853"
|
||||||
|
d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055c-34.523 0-63.824-22.773-74.269-54.25l-1.531.13l-40.298 31.187l-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill="#fbbc05"
|
||||||
|
d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82c0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602z"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
fill="#eb4335"
|
||||||
|
d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0C79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import { ComboboxItem, Select } from "@mantine/core";
|
|
||||||
import { useState } from "react";
|
|
||||||
import i18n from "../../lib/i18n/i18n";
|
|
||||||
import {
|
|
||||||
SupportedLanguage,
|
|
||||||
getLanguageName,
|
|
||||||
languages,
|
|
||||||
} from "../../lib/i18n/locales";
|
|
||||||
|
|
||||||
export const LanguageSelector = () => {
|
|
||||||
const [language, setLanguage] = useState<ComboboxItem>({
|
|
||||||
value: i18n.language,
|
|
||||||
label: getLanguageName(i18n.language as SupportedLanguage),
|
|
||||||
});
|
|
||||||
|
|
||||||
const languageOptions = Object.entries(languages).map(([code, name]) => ({
|
|
||||||
value: code,
|
|
||||||
label: name,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const handleLanguageChange = (option: string) => {
|
|
||||||
i18n.changeLanguage(option as SupportedLanguage);
|
|
||||||
setLanguage({
|
|
||||||
value: option,
|
|
||||||
label: getLanguageName(option as SupportedLanguage),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
data={languageOptions}
|
|
||||||
value={language ? language.value : null}
|
|
||||||
onChange={(_value, option) => handleLanguageChange(option.value)}
|
|
||||||
allowDeselect={false}
|
|
||||||
pos="absolute"
|
|
||||||
right={10}
|
|
||||||
top={10}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
35
frontend/src/components/language/language.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { languages, SupportedLanguage } from "@/lib/i18n/locales";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectItem,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "../ui/select";
|
||||||
|
import { useState } from "react";
|
||||||
|
import i18n from "@/lib/i18n/i18n";
|
||||||
|
|
||||||
|
export const LanguageSelector = () => {
|
||||||
|
const [language, setLanguage] = useState<SupportedLanguage>(
|
||||||
|
i18n.language as SupportedLanguage,
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSelect = (option: string) => {
|
||||||
|
setLanguage(option as SupportedLanguage);
|
||||||
|
i18n.changeLanguage(option as SupportedLanguage);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Select onValueChange={handleSelect} value={language}>
|
||||||
|
<SelectTrigger className="absolute top-5 right-5">
|
||||||
|
<SelectValue placeholder="Select language" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{Object.entries(languages).map(([key, value]) => (
|
||||||
|
<SelectItem key={key} value={key}>
|
||||||
|
{value}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
};
|
||||||
21
frontend/src/components/layout/layout.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { useAppContext } from "@/context/app-context";
|
||||||
|
import { LanguageSelector } from "../language/language";
|
||||||
|
import { Outlet } from "react-router";
|
||||||
|
|
||||||
|
export const Layout = () => {
|
||||||
|
const { backgroundImage } = useAppContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="relative flex flex-col justify-center items-center min-h-svh"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${backgroundImage})`,
|
||||||
|
backgroundSize: "cover",
|
||||||
|
backgroundPosition: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<LanguageSelector />
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { Center, Flex } from "@mantine/core";
|
|
||||||
import { ReactNode } from "react";
|
|
||||||
import { LanguageSelector } from "../language-selector/language-selector";
|
|
||||||
|
|
||||||
export const Layout = ({ children }: { children: ReactNode }) => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<LanguageSelector />
|
|
||||||
<Center style={{ minHeight: "100vh" }}>
|
|
||||||
<Flex direction="column" flex="1" maw={340}>
|
|
||||||
{children}
|
|
||||||
</Flex>
|
|
||||||
</Center>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
77
frontend/src/components/ui/button.tsx
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { Slot } from "@radix-ui/react-slot";
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
|
||||||
|
const buttonVariants = cva(
|
||||||
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
|
{
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default:
|
||||||
|
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||||
|
destructive:
|
||||||
|
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
|
outline:
|
||||||
|
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||||
|
secondary:
|
||||||
|
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||||
|
ghost:
|
||||||
|
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||||
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
|
warning:
|
||||||
|
"bg-amber-500 text-white shadow-xs hover:bg-amber-400 focus-visible:ring-amber-200/20 dark:focus-visible:ring-amber-400/40 dark:bg-amber-600",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||||
|
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||||
|
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||||
|
icon: "size-9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: "default",
|
||||||
|
size: "default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
function Button({
|
||||||
|
className,
|
||||||
|
variant,
|
||||||
|
size,
|
||||||
|
asChild = false,
|
||||||
|
loading = false,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<"button"> &
|
||||||
|
VariantProps<typeof buttonVariants> & {
|
||||||
|
asChild?: boolean;
|
||||||
|
loading?: boolean;
|
||||||
|
}) {
|
||||||
|
const Comp = asChild ? Slot : "button";
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
|
data-slot="button"
|
||||||
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
|
disabled
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<Loader2 className="animate-spin" />
|
||||||
|
</Comp>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
|
data-slot="button"
|
||||||
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Button, buttonVariants };
|
||||||
92
frontend/src/components/ui/card.tsx
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
function Card({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card"
|
||||||
|
className={cn(
|
||||||
|
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card-header"
|
||||||
|
className={cn(
|
||||||
|
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card-title"
|
||||||
|
className={cn("leading-none font-semibold", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card-description"
|
||||||
|
className={cn("text-muted-foreground text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card-action"
|
||||||
|
className={cn(
|
||||||
|
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card-content"
|
||||||
|
className={cn("px-6", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="card-footer"
|
||||||
|
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
Card,
|
||||||
|
CardHeader,
|
||||||
|
CardFooter,
|
||||||
|
CardTitle,
|
||||||
|
CardAction,
|
||||||
|
CardDescription,
|
||||||
|
CardContent,
|
||||||
|
};
|
||||||
166
frontend/src/components/ui/form.tsx
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||||
|
import { Slot } from "@radix-ui/react-slot";
|
||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
FormProvider,
|
||||||
|
useFormContext,
|
||||||
|
useFormState,
|
||||||
|
type ControllerProps,
|
||||||
|
type FieldPath,
|
||||||
|
type FieldValues,
|
||||||
|
} from "react-hook-form";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
|
||||||
|
const Form = FormProvider;
|
||||||
|
|
||||||
|
type FormFieldContextValue<
|
||||||
|
TFieldValues extends FieldValues = FieldValues,
|
||||||
|
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
||||||
|
> = {
|
||||||
|
name: TName;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FormFieldContext = React.createContext<FormFieldContextValue>(
|
||||||
|
{} as FormFieldContextValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
const FormField = <
|
||||||
|
TFieldValues extends FieldValues = FieldValues,
|
||||||
|
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
||||||
|
>({
|
||||||
|
...props
|
||||||
|
}: ControllerProps<TFieldValues, TName>) => {
|
||||||
|
return (
|
||||||
|
<FormFieldContext.Provider value={{ name: props.name }}>
|
||||||
|
<Controller {...props} />
|
||||||
|
</FormFieldContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const useFormField = () => {
|
||||||
|
const fieldContext = React.useContext(FormFieldContext);
|
||||||
|
const itemContext = React.useContext(FormItemContext);
|
||||||
|
const { getFieldState } = useFormContext();
|
||||||
|
const formState = useFormState({ name: fieldContext.name });
|
||||||
|
const fieldState = getFieldState(fieldContext.name, formState);
|
||||||
|
|
||||||
|
if (!fieldContext) {
|
||||||
|
throw new Error("useFormField should be used within <FormField>");
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id } = itemContext;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name: fieldContext.name,
|
||||||
|
formItemId: `${id}-form-item`,
|
||||||
|
formDescriptionId: `${id}-form-item-description`,
|
||||||
|
formMessageId: `${id}-form-item-message`,
|
||||||
|
...fieldState,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type FormItemContextValue = {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FormItemContext = React.createContext<FormItemContextValue>(
|
||||||
|
{} as FormItemContextValue,
|
||||||
|
);
|
||||||
|
|
||||||
|
function FormItem({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
const id = React.useId();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormItemContext.Provider value={{ id }}>
|
||||||
|
<div
|
||||||
|
data-slot="form-item"
|
||||||
|
className={cn("grid gap-2", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</FormItemContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormLabel({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
||||||
|
const { error, formItemId } = useFormField();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Label
|
||||||
|
data-slot="form-label"
|
||||||
|
data-error={!!error}
|
||||||
|
className={cn("data-[error=true]:text-destructive", className)}
|
||||||
|
htmlFor={formItemId}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
|
||||||
|
const { error, formItemId, formDescriptionId, formMessageId } =
|
||||||
|
useFormField();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slot
|
||||||
|
data-slot="form-control"
|
||||||
|
id={formItemId}
|
||||||
|
aria-describedby={
|
||||||
|
!error
|
||||||
|
? `${formDescriptionId}`
|
||||||
|
: `${formDescriptionId} ${formMessageId}`
|
||||||
|
}
|
||||||
|
aria-invalid={!!error}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
|
||||||
|
const { formDescriptionId } = useFormField();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
data-slot="form-description"
|
||||||
|
id={formDescriptionId}
|
||||||
|
className={cn("text-muted-foreground text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
|
||||||
|
const { error, formMessageId } = useFormField();
|
||||||
|
const body = error ? String(error?.message ?? "") : props.children;
|
||||||
|
|
||||||
|
if (!body) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
data-slot="form-message"
|
||||||
|
id={formMessageId}
|
||||||
|
className={cn("text-destructive text-sm", className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{body}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
useFormField,
|
||||||
|
Form,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormMessage,
|
||||||
|
FormField,
|
||||||
|
};
|
||||||
75
frontend/src/components/ui/input-otp.tsx
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { OTPInput, OTPInputContext } from "input-otp";
|
||||||
|
import { MinusIcon } from "lucide-react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
function InputOTP({
|
||||||
|
className,
|
||||||
|
containerClassName,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof OTPInput> & {
|
||||||
|
containerClassName?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<OTPInput
|
||||||
|
data-slot="input-otp"
|
||||||
|
containerClassName={cn(
|
||||||
|
"flex items-center gap-2 has-disabled:opacity-50",
|
||||||
|
containerClassName,
|
||||||
|
)}
|
||||||
|
className={cn("disabled:cursor-not-allowed", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="input-otp-group"
|
||||||
|
className={cn("flex items-center", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputOTPSlot({
|
||||||
|
index,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<"div"> & {
|
||||||
|
index: number;
|
||||||
|
}) {
|
||||||
|
const inputOTPContext = React.useContext(OTPInputContext);
|
||||||
|
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="input-otp-slot"
|
||||||
|
data-active={isActive}
|
||||||
|
className={cn(
|
||||||
|
"data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{char}
|
||||||
|
{hasFakeCaret && (
|
||||||
|
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
||||||
|
<div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
|
||||||
|
return (
|
||||||
|
<div data-slot="input-otp-separator" role="separator" {...props}>
|
||||||
|
<MinusIcon />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
|
||||||
21
frontend/src/components/ui/input.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
data-slot="input"
|
||||||
|
className={cn(
|
||||||
|
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||||
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Input };
|
||||||
22
frontend/src/components/ui/label.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
function Label({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
||||||
|
return (
|
||||||
|
<LabelPrimitive.Root
|
||||||
|
data-slot="label"
|
||||||
|
className={cn(
|
||||||
|
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Label };
|
||||||
33
frontend/src/components/ui/oauth-button.tsx
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { Loader2 } from "lucide-react";
|
||||||
|
import { Button } from "./button";
|
||||||
|
import React from "react";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
interface Props extends React.ComponentProps<typeof Button> {
|
||||||
|
title: string;
|
||||||
|
icon: React.ReactNode;
|
||||||
|
onClick?: () => void;
|
||||||
|
loading?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const OAuthButton = (props: Props) => {
|
||||||
|
const { title, icon, onClick, loading, className, ...rest } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={onClick}
|
||||||
|
className={twMerge("rounded-md", className)}
|
||||||
|
variant="outline"
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{loading ? (
|
||||||
|
<Loader2 className="animate-spin" />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{icon}
|
||||||
|
{title}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
183
frontend/src/components/ui/select.tsx
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
||||||
|
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
function Select({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
||||||
|
return <SelectPrimitive.Root data-slot="select" {...props} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectGroup({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
||||||
|
return <SelectPrimitive.Group data-slot="select-group" {...props} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectValue({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
||||||
|
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectTrigger({
|
||||||
|
className,
|
||||||
|
size = "default",
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
||||||
|
size?: "sm" | "default";
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Trigger
|
||||||
|
data-slot="select-trigger"
|
||||||
|
data-size={size}
|
||||||
|
className={cn(
|
||||||
|
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-card dark:hover:bg-card/90 flex w-fit items-center justify-between gap-2 rounded-md border bg-card hover:bg-card/90 px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<SelectPrimitive.Icon asChild>
|
||||||
|
<ChevronDownIcon className="size-4" />
|
||||||
|
</SelectPrimitive.Icon>
|
||||||
|
</SelectPrimitive.Trigger>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectContent({
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
position = "popper",
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Portal>
|
||||||
|
<SelectPrimitive.Content
|
||||||
|
data-slot="select-content"
|
||||||
|
className={cn(
|
||||||
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
||||||
|
position === "popper" &&
|
||||||
|
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
position={position}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<SelectScrollUpButton />
|
||||||
|
<SelectPrimitive.Viewport
|
||||||
|
className={cn(
|
||||||
|
"p-1",
|
||||||
|
position === "popper" &&
|
||||||
|
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SelectPrimitive.Viewport>
|
||||||
|
<SelectScrollDownButton />
|
||||||
|
</SelectPrimitive.Content>
|
||||||
|
</SelectPrimitive.Portal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectLabel({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Label
|
||||||
|
data-slot="select-label"
|
||||||
|
className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectItem({
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Item
|
||||||
|
data-slot="select-item"
|
||||||
|
className={cn(
|
||||||
|
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
||||||
|
<SelectPrimitive.ItemIndicator>
|
||||||
|
<CheckIcon className="size-4" />
|
||||||
|
</SelectPrimitive.ItemIndicator>
|
||||||
|
</span>
|
||||||
|
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
||||||
|
</SelectPrimitive.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectSeparator({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.Separator
|
||||||
|
data-slot="select-separator"
|
||||||
|
className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectScrollUpButton({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.ScrollUpButton
|
||||||
|
data-slot="select-scroll-up-button"
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center justify-center py-1",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronUpIcon className="size-4" />
|
||||||
|
</SelectPrimitive.ScrollUpButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SelectScrollDownButton({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
||||||
|
return (
|
||||||
|
<SelectPrimitive.ScrollDownButton
|
||||||
|
data-slot="select-scroll-down-button"
|
||||||
|
className={cn(
|
||||||
|
"flex cursor-default items-center justify-center py-1",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<ChevronDownIcon className="size-4" />
|
||||||
|
</SelectPrimitive.ScrollDownButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectLabel,
|
||||||
|
SelectScrollDownButton,
|
||||||
|
SelectScrollUpButton,
|
||||||
|
SelectSeparator,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
};
|
||||||
38
frontend/src/components/ui/separator.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as React from "react";
|
||||||
|
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
function Separator({
|
||||||
|
className,
|
||||||
|
orientation = "horizontal",
|
||||||
|
decorative = true,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
|
||||||
|
return (
|
||||||
|
<SeparatorPrimitive.Root
|
||||||
|
data-slot="separator-root"
|
||||||
|
decorative={decorative}
|
||||||
|
orientation={orientation}
|
||||||
|
className={cn(
|
||||||
|
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SeperatorWithChildren({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-4">
|
||||||
|
<Separator className="flex-1" />
|
||||||
|
<span className="text-sm text-muted-foreground">{children}</span>
|
||||||
|
<Separator className="flex-1" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Separator, SeperatorWithChildren };
|
||||||
23
frontend/src/components/ui/sonner.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { Toaster as Sonner, ToasterProps } from "sonner";
|
||||||
|
|
||||||
|
const Toaster = ({ ...props }: ToasterProps) => {
|
||||||
|
const { theme = "system" } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Sonner
|
||||||
|
theme={theme as ToasterProps["theme"]}
|
||||||
|
className="toaster group"
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
"--normal-bg": "var(--popover)",
|
||||||
|
"--normal-text": "var(--popover-foreground)",
|
||||||
|
"--normal-border": "var(--border)",
|
||||||
|
} as React.CSSProperties
|
||||||
|
}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Toaster };
|
||||||
@@ -1,40 +1,42 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import {
|
||||||
import React, { createContext, useContext } from "react";
|
appContextSchema,
|
||||||
|
AppContextSchema,
|
||||||
|
} from "@/schemas/app-context-schema";
|
||||||
|
import { createContext, useContext } from "react";
|
||||||
|
import { useSuspenseQuery } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { AppContextSchemaType } from "../schemas/app-context-schema";
|
|
||||||
|
|
||||||
const AppContext = createContext<AppContextSchemaType | null>(null);
|
const AppContext = createContext<AppContextSchema | null>(null);
|
||||||
|
|
||||||
export const AppContextProvider = ({
|
export const AppContextProvider = ({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const { isFetching, data, error } = useSuspenseQuery({
|
||||||
data: userContext,
|
queryKey: ["app"],
|
||||||
isLoading,
|
queryFn: () => axios.get("/api/app").then((res) => res.data),
|
||||||
error,
|
|
||||||
} = useQuery({
|
|
||||||
queryKey: ["appContext"],
|
|
||||||
queryFn: async () => {
|
|
||||||
const res = await axios.get("/api/app");
|
|
||||||
return res.data;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error && !isLoading) {
|
if (error && !isFetching) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validated = appContextSchema.safeParse(data);
|
||||||
|
|
||||||
|
if (validated.success === false) {
|
||||||
|
throw validated.error;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppContext.Provider value={userContext}>{children}</AppContext.Provider>
|
<AppContext.Provider value={validated.data}>{children}</AppContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAppContext = () => {
|
export const useAppContext = () => {
|
||||||
const context = useContext(AppContext);
|
const context = useContext(AppContext);
|
||||||
|
|
||||||
if (context === null) {
|
if (!context) {
|
||||||
throw new Error("useAppContext must be used within an AppContextProvider");
|
throw new Error("useAppContext must be used within an AppContextProvider");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,47 @@
|
|||||||
import { useQuery } from "@tanstack/react-query";
|
import {
|
||||||
import React, { createContext, useContext } from "react";
|
userContextSchema,
|
||||||
|
UserContextSchema,
|
||||||
|
} from "@/schemas/user-context-schema";
|
||||||
|
import { createContext, useContext } from "react";
|
||||||
|
import { useSuspenseQuery } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { UserContextSchemaType } from "../schemas/user-context-schema";
|
|
||||||
|
|
||||||
const UserContext = createContext<UserContextSchemaType | null>(null);
|
const UserContext = createContext<UserContextSchema | null>(null);
|
||||||
|
|
||||||
export const UserContextProvider = ({
|
export const UserContextProvider = ({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const { isFetching, data, error } = useSuspenseQuery({
|
||||||
data: userContext,
|
queryKey: ["user"],
|
||||||
isLoading,
|
queryFn: () => axios.get("/api/user").then((res) => res.data),
|
||||||
error,
|
|
||||||
} = useQuery({
|
|
||||||
queryKey: ["userContext"],
|
|
||||||
queryFn: async () => {
|
|
||||||
const res = await axios.get("/api/user");
|
|
||||||
return res.data;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error && !isLoading) {
|
if (error && !isFetching) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validated = userContextSchema.safeParse(data);
|
||||||
|
|
||||||
|
if (validated.success === false) {
|
||||||
|
throw validated.error;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserContext.Provider value={userContext}>{children}</UserContext.Provider>
|
<UserContext.Provider value={validated.data}>
|
||||||
|
{children}
|
||||||
|
</UserContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUserContext = () => {
|
export const useUserContext = () => {
|
||||||
const context = useContext(UserContext);
|
const context = useContext(UserContext);
|
||||||
|
|
||||||
if (context === null) {
|
if (!context) {
|
||||||
throw new Error("useUserContext must be used within a UserContextProvider");
|
throw new Error(
|
||||||
|
"useUserContext must be used within an UserContextProvider",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
import type { SVGProps } from "react";
|
|
||||||
|
|
||||||
export function GoogleIcon(props: SVGProps<SVGSVGElement>) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width={48}
|
|
||||||
height={48}
|
|
||||||
viewBox="0 0 48 48"
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="#ffc107"
|
|
||||||
d="M43.611 20.083H42V20H24v8h11.303c-1.649 4.657-6.08 8-11.303 8c-6.627 0-12-5.373-12-12s5.373-12 12-12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4C12.955 4 4 12.955 4 24s8.955 20 20 20s20-8.955 20-20c0-1.341-.138-2.65-.389-3.917"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#ff3d00"
|
|
||||||
d="m6.306 14.691l6.571 4.819C14.655 15.108 18.961 12 24 12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4C16.318 4 9.656 8.337 6.306 14.691"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#4caf50"
|
|
||||||
d="M24 44c5.166 0 9.86-1.977 13.409-5.192l-6.19-5.238A11.9 11.9 0 0 1 24 36c-5.202 0-9.619-3.317-11.283-7.946l-6.522 5.025C9.505 39.556 16.227 44 24 44"
|
|
||||||
></path>
|
|
||||||
<path
|
|
||||||
fill="#1976d2"
|
|
||||||
d="M43.611 20.083H42V20H24v8h11.303a12.04 12.04 0 0 1-4.087 5.571l.003-.002l6.19 5.238C36.971 39.205 44 34 44 24c0-1.341-.138-2.65-.389-3.917"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import type { SVGProps } from "react";
|
|
||||||
|
|
||||||
export function TailscaleIcon(props: SVGProps<SVGSVGElement>) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
width={24}
|
|
||||||
height={24}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<style>{".st0{opacity:0.2;fill:#CCCAC9;}.st1{fill:#FFFFFF;}"}</style>
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path
|
|
||||||
className="st0"
|
|
||||||
d="M65.6,127.7c35.3,0,63.9-28.6,63.9-63.9S100.9,0,65.6,0S1.8,28.6,1.8,63.9S30.4,127.7,65.6,127.7z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st1"
|
|
||||||
d="M65.6,318.1c35.3,0,63.9-28.6,63.9-63.9s-28.6-63.9-63.9-63.9S1.8,219,1.8,254.2S30.4,318.1,65.6,318.1z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st0"
|
|
||||||
d="M65.6,512c35.3,0,63.9-28.6,63.9-63.9s-28.6-63.9-63.9-63.9S1.8,412.9,1.8,448.1S30.4,512,65.6,512z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st1"
|
|
||||||
d="M257.2,318.1c35.3,0,63.9-28.6,63.9-63.9s-28.6-63.9-63.9-63.9s-63.9,28.6-63.9,63.9S221.9,318.1,257.2,318.1z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st1"
|
|
||||||
d="M257.2,512c35.3,0,63.9-28.6,63.9-63.9s-28.6-63.9-63.9-63.9s-63.9,28.6-63.9,63.9S221.9,512,257.2,512z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st0"
|
|
||||||
d="M257.2,127.7c35.3,0,63.9-28.6,63.9-63.9S292.5,0,257.2,0s-63.9,28.6-63.9,63.9S221.9,127.7,257.2,127.7z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st0"
|
|
||||||
d="M446.4,127.7c35.3,0,63.9-28.6,63.9-63.9S481.6,0,446.4,0c-35.3,0-63.9,28.6-63.9,63.9S411.1,127.7,446.4,127.7z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st1"
|
|
||||||
d="M446.4,318.1c35.3,0,63.9-28.6,63.9-63.9s-28.6-63.9-63.9-63.9s-63.9,28.6-63.9,63.9S411.1,318.1,446.4,318.1z"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
className="st0"
|
|
||||||
d="M446.4,512c35.3,0,63.9-28.6,63.9-63.9s-28.6-63.9-63.9-63.9s-63.9,28.6-63.9,63.9S411.1,512,446.4,512z"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
176
frontend/src/index.css
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
@import "tw-animate-css";
|
||||||
|
|
||||||
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--radius-sm: calc(var(--radius) - 4px);
|
||||||
|
--radius-md: calc(var(--radius) - 2px);
|
||||||
|
--radius-lg: var(--radius);
|
||||||
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
|
--color-background: var(--background);
|
||||||
|
--color-foreground: var(--foreground);
|
||||||
|
--color-card: var(--card);
|
||||||
|
--color-card-foreground: var(--card-foreground);
|
||||||
|
--color-popover: var(--popover);
|
||||||
|
--color-popover-foreground: var(--popover-foreground);
|
||||||
|
--color-primary: var(--primary);
|
||||||
|
--color-primary-foreground: var(--primary-foreground);
|
||||||
|
--color-secondary: var(--secondary);
|
||||||
|
--color-secondary-foreground: var(--secondary-foreground);
|
||||||
|
--color-muted: var(--muted);
|
||||||
|
--color-muted-foreground: var(--muted-foreground);
|
||||||
|
--color-accent: var(--accent);
|
||||||
|
--color-accent-foreground: var(--accent-foreground);
|
||||||
|
--color-destructive: var(--destructive);
|
||||||
|
--color-border: var(--border);
|
||||||
|
--color-input: var(--input);
|
||||||
|
--color-ring: var(--ring);
|
||||||
|
--color-chart-1: var(--chart-1);
|
||||||
|
--color-chart-2: var(--chart-2);
|
||||||
|
--color-chart-3: var(--chart-3);
|
||||||
|
--color-chart-4: var(--chart-4);
|
||||||
|
--color-chart-5: var(--chart-5);
|
||||||
|
--color-sidebar: var(--sidebar);
|
||||||
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||||
|
--color-sidebar-primary: var(--sidebar-primary);
|
||||||
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||||
|
--color-sidebar-accent: var(--sidebar-accent);
|
||||||
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||||
|
--color-sidebar-border: var(--sidebar-border);
|
||||||
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--radius: 0.625rem;
|
||||||
|
--background: oklch(1 0 0);
|
||||||
|
--foreground: oklch(0.145 0 0);
|
||||||
|
--card: oklch(1 0 0);
|
||||||
|
--card-foreground: oklch(0.145 0 0);
|
||||||
|
--popover: oklch(1 0 0);
|
||||||
|
--popover-foreground: oklch(0.145 0 0);
|
||||||
|
--primary: oklch(0.205 0 0);
|
||||||
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
|
--secondary: oklch(0.97 0 0);
|
||||||
|
--secondary-foreground: oklch(0.205 0 0);
|
||||||
|
--muted: oklch(0.97 0 0);
|
||||||
|
--muted-foreground: oklch(0.556 0 0);
|
||||||
|
--accent: oklch(0.97 0 0);
|
||||||
|
--accent-foreground: oklch(0.205 0 0);
|
||||||
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
|
--border: oklch(0.922 0 0);
|
||||||
|
--input: oklch(0.922 0 0);
|
||||||
|
--ring: oklch(0.708 0 0);
|
||||||
|
--chart-1: oklch(0.646 0.222 41.116);
|
||||||
|
--chart-2: oklch(0.6 0.118 184.704);
|
||||||
|
--chart-3: oklch(0.398 0.07 227.392);
|
||||||
|
--chart-4: oklch(0.828 0.189 84.429);
|
||||||
|
--chart-5: oklch(0.769 0.188 70.08);
|
||||||
|
--sidebar: oklch(0.985 0 0);
|
||||||
|
--sidebar-foreground: oklch(0.145 0 0);
|
||||||
|
--sidebar-primary: oklch(0.205 0 0);
|
||||||
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-accent: oklch(0.97 0 0);
|
||||||
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||||
|
--sidebar-border: oklch(0.922 0 0);
|
||||||
|
--sidebar-ring: oklch(0.708 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: oklch(0.145 0 0);
|
||||||
|
--foreground: oklch(0.985 0 0);
|
||||||
|
--card: oklch(0.205 0 0);
|
||||||
|
--card-foreground: oklch(0.985 0 0);
|
||||||
|
--popover: oklch(0.205 0 0);
|
||||||
|
--popover-foreground: oklch(0.985 0 0);
|
||||||
|
--primary: oklch(0.922 0 0);
|
||||||
|
--primary-foreground: oklch(0.205 0 0);
|
||||||
|
--secondary: oklch(0.269 0 0);
|
||||||
|
--secondary-foreground: oklch(0.985 0 0);
|
||||||
|
--muted: oklch(0.269 0 0);
|
||||||
|
--muted-foreground: oklch(0.708 0 0);
|
||||||
|
--accent: oklch(0.269 0 0);
|
||||||
|
--accent-foreground: oklch(0.985 0 0);
|
||||||
|
--destructive: oklch(0.704 0.191 22.216);
|
||||||
|
--border: oklch(1 0 0 / 10%);
|
||||||
|
--input: oklch(1 0 0 / 15%);
|
||||||
|
--ring: oklch(0.556 0 0);
|
||||||
|
--chart-1: oklch(0.488 0.243 264.376);
|
||||||
|
--chart-2: oklch(0.696 0.17 162.48);
|
||||||
|
--chart-3: oklch(0.769 0.188 70.08);
|
||||||
|
--chart-4: oklch(0.627 0.265 303.9);
|
||||||
|
--chart-5: oklch(0.645 0.246 16.439);
|
||||||
|
--sidebar: oklch(0.205 0 0);
|
||||||
|
--sidebar-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||||
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-accent: oklch(0.269 0 0);
|
||||||
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-border: oklch(1 0 0 / 10%);
|
||||||
|
--sidebar-ring: oklch(0.556 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border outline-ring/50;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@apply scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@apply scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@apply scroll-m-20 text-2xl font-semibold tracking-tight;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@apply scroll-m-20 text-xl font-semibold tracking-tight;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
@apply leading-6 [&:not(:first-child)]:mt-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
@apply mt-6 border-l-2 pl-6 italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
@apply m-0 border-t p-0 even:bg-muted;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
@apply border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@apply my-6 ml-6 list-disc [&>li]:mt-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
@apply relative rounded bg-muted px-[0.2rem] py-[0.1rem] font-mono text-sm font-semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lead {
|
||||||
|
@apply text-xl text-muted-foreground;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
@apply text-lg font-semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
small {
|
||||||
|
@apply text-sm font-medium leading-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.muted {
|
||||||
|
@apply text-sm text-muted-foreground;
|
||||||
|
}
|
||||||
15
frontend/src/lib/hooks/use-is-mounted.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
export function useIsMounted(): () => boolean {
|
||||||
|
const isMounted = useRef(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
isMounted.current = true;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMounted.current = false;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return useCallback(() => isMounted.current, []);
|
||||||
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import i18n from "i18next";
|
import i18n from "i18next";
|
||||||
import { initReactI18next } from "react-i18next";
|
import { initReactI18next } from "react-i18next";
|
||||||
import LanguageDetector from "i18next-browser-languagedetector";
|
import LanguageDetector from "i18next-browser-languagedetector";
|
||||||
import ChainedBackend from "i18next-chained-backend";
|
|
||||||
import resourcesToBackend from "i18next-resources-to-backend";
|
import resourcesToBackend from "i18next-resources-to-backend";
|
||||||
import HttpBackend from "i18next-http-backend";
|
|
||||||
|
|
||||||
i18n
|
i18n
|
||||||
.use(ChainedBackend)
|
|
||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
|
.use(
|
||||||
|
resourcesToBackend(
|
||||||
|
(language: string) => import(`./locales/${language}.json`),
|
||||||
|
),
|
||||||
|
)
|
||||||
.init({
|
.init({
|
||||||
fallbackLng: "en",
|
fallbackLng: "en",
|
||||||
debug: import.meta.env.MODE === "development",
|
debug: import.meta.env.MODE === "development",
|
||||||
@@ -18,20 +20,6 @@ i18n
|
|||||||
},
|
},
|
||||||
|
|
||||||
load: "currentOnly",
|
load: "currentOnly",
|
||||||
|
|
||||||
backend: {
|
|
||||||
backends: [
|
|
||||||
HttpBackend,
|
|
||||||
resourcesToBackend(
|
|
||||||
(language: string) => import(`./locales/${language}.json`),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
backendOptions: [
|
|
||||||
{
|
|
||||||
loadPath: "https://cdn.tinyauth.app/i18n/v1/{{lng}}.json",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
|||||||
@@ -1,36 +1,37 @@
|
|||||||
export const languages = {
|
export const languages = {
|
||||||
"af-ZA": "Afrikaans",
|
"af-ZA": "Afrikaans",
|
||||||
"ar-SA": "العربية",
|
"ar-SA": "العربية",
|
||||||
"ca-ES": "Català",
|
"ca-ES": "Català",
|
||||||
"cs-CZ": "Čeština",
|
"cs-CZ": "Čeština",
|
||||||
"da-DK": "Dansk",
|
"da-DK": "Dansk",
|
||||||
"de-DE": "Deutsch",
|
"de-DE": "Deutsch",
|
||||||
"el-GR": "Ελληνικά",
|
"el-GR": "Ελληνικά",
|
||||||
"en-US": "English",
|
"en-US": "English",
|
||||||
"es-ES": "Español",
|
"es-ES": "Español",
|
||||||
"fi-FI": "Suomi",
|
"fi-FI": "Suomi",
|
||||||
"fr-FR": "Français",
|
"fr-FR": "Français",
|
||||||
"he-IL": "עברית",
|
"he-IL": "עברית",
|
||||||
"hu-HU": "Magyar",
|
"hu-HU": "Magyar",
|
||||||
"it-IT": "Italiano",
|
"it-IT": "Italiano",
|
||||||
"ja-JP": "日本語",
|
"ja-JP": "日本語",
|
||||||
"ko-KR": "한국어",
|
"ko-KR": "한국어",
|
||||||
"nl-NL": "Nederlands",
|
"nl-NL": "Nederlands",
|
||||||
"no-NO": "Norsk",
|
"no-NO": "Norsk",
|
||||||
"pl-PL": "Polski",
|
"pl-PL": "Polski",
|
||||||
"pt-BR": "Português",
|
"pt-BR": "Português",
|
||||||
"pt-PT": "Português",
|
"pt-PT": "Português",
|
||||||
"ro-RO": "Română",
|
"ro-RO": "Română",
|
||||||
"ru-RU": "Русский",
|
"ru-RU": "Русский",
|
||||||
"sr-SP": "Српски",
|
"sr-SP": "Српски",
|
||||||
"sv-SE": "Svenska",
|
"sv-SE": "Svenska",
|
||||||
"tr-TR": "Türkçe",
|
"tr-TR": "Türkçe",
|
||||||
"uk-UA": "Українська",
|
"uk-UA": "Українська",
|
||||||
"vi-VN": "Tiếng Việt",
|
"vi-VN": "Tiếng Việt",
|
||||||
"zh-CN": "中文",
|
"zh-CN": "中文",
|
||||||
"zh-TW": "中文"
|
"zh-TW": "中文",
|
||||||
}
|
};
|
||||||
|
|
||||||
export type SupportedLanguage = keyof typeof languages;
|
export type SupportedLanguage = keyof typeof languages;
|
||||||
|
|
||||||
export const getLanguageName = (language: SupportedLanguage): string => languages[language];
|
export const getLanguageName = (language: SupportedLanguage): string =>
|
||||||
|
languages[language];
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "مرحبا بعودتك، قم بتسجيل الدخول باستخدام",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Or",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "اسم المستخدم",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "كلمة المرور",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "تسجيل الدخول",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailTitle": "فشل تسجيل الدخول",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailSubtitle": "الرجاء التحقق من اسم المستخدم وكلمة المرور",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessTitle": "تم تسجيل الدخول",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginSuccessSubtitle": "مرحبا بعودتك!",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthFailSubtitle": "فشل في الحصول على رابط OAuth",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"loginOauthSuccessTitle": "إعادة توجيه",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"loginOauthSuccessSubtitle": "إعادة توجيه إلى مزود OAuth الخاص بك",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueRedirectingTitle": "إعادة توجيه...",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueRedirectingSubtitle": "يجب إعادة توجيهك إلى التطبيق قريبا",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInvalidRedirectTitle": "إعادة توجيه غير صالحة",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInvalidRedirectSubtitle": "رابط إعادة التوجيه غير صالح",
|
||||||
"continueTitle": "Continue",
|
"continueInsecureRedirectTitle": "إعادة توجيه غير آمنة",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
"continueTitle": "متابعة",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
"continueSubtitle": "انقر الزر للمتابعة إلى التطبيق الخاص بك.",
|
||||||
"internalErrorButton": "Try again",
|
"logoutFailTitle": "فشل تسجيل الخروج",
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailSubtitle": "يرجى إعادة المحاولة",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutSuccessTitle": "تم تسجيل الخروج",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessSubtitle": "تم تسجيل خروجك",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutTitle": "تسجيل الخروج",
|
||||||
"logoutTitle": "Logout",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"notFoundTitle": "الصفحة غير موجودة",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundSubtitle": "الصفحة التي تبحث عنها غير موجودة.",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundButton": "انتقل إلى الرئيسية",
|
||||||
"notFoundButton": "Go home",
|
"totpFailTitle": "فشل في التحقق من الرمز",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailSubtitle": "الرجاء التحقق من الرمز الخاص بك وحاول مرة أخرى",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpSuccessTitle": "تم التحقق",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessSubtitle": "إعادة توجيه إلى تطبيقك",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpTitle": "أدخل رمز TOTP الخاص بك",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "غير مرخص",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "حاول مجددا",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "إلغاء",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Velkommen tilbage, log ind med",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Velkommen tilbage, log venligst ind",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Eller",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "Brugernavn",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "Adgangskode",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "Log ind",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailTitle": "Login mislykkedes",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailSubtitle": "Tjek venligst dit brugernavn og adgangskode",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginFailRateLimit": "Du har forsøgt at logge ind for mange gange, prøv igen senere",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessTitle": "Logget ind",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginSuccessSubtitle": "Velkommen tilbage!",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthFailTitle": "Der opstod en fejl",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthFailSubtitle": "Kunne ikke hente OAuth-URL",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"loginOauthSuccessTitle": "Omdirigerer",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"loginOauthSuccessSubtitle": "Omdirigerer til din OAuth-udbyder",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueRedirectingTitle": "Omdirigerer...",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueRedirectingSubtitle": "Du bør blive omdirigeret til appen snart",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInvalidRedirectTitle": "Ugyldig omdirigering",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInvalidRedirectSubtitle": "Omdirigerings-URL'en er ugyldig",
|
||||||
"continueTitle": "Continue",
|
"continueInsecureRedirectTitle": "Usikker omdirigering",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueInsecureRedirectSubtitle": "Du forsøger at omdirigere fra <code>https</code> til <code>http</code>, som ikke er sikker. Er du sikker på, at du vil fortsætte?",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
"continueTitle": "Fortsæt",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
"continueSubtitle": "Klik på knappen for at fortsætte til din app.",
|
||||||
"internalErrorButton": "Try again",
|
"logoutFailTitle": "Log ud mislykkedes",
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailSubtitle": "Prøv venligst igen",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutSuccessTitle": "Logget ud",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessSubtitle": "Du er blevet logget ud",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutTitle": "Log ud",
|
||||||
"logoutTitle": "Logout",
|
"logoutUsernameSubtitle": "Du er i øjeblikket logget ind som <code>{{username}}</code>. Klik på knappen nedenfor for at logge ud.",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutOauthSubtitle": "Du er i øjeblikket logget ind som <code>{{username}}</code> via {{provider}} OAuth-udbyderen. Klik på knappen nedenfor for at logge ud.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"notFoundTitle": "Siden blev ikke fundet",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundSubtitle": "Siden du leder efter, findes ikke.",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundButton": "Gå til forsiden",
|
||||||
"notFoundButton": "Go home",
|
"totpFailTitle": "Verificering af kode mislykkedes",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailSubtitle": "Tjek venligst din kode og prøv igen",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpSuccessTitle": "Verificeret",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessSubtitle": "Omdirigerer til din app",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpTitle": "Indtast din TOTP-kode",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpSubtitle": "Indtast venligst koden fra din to-faktor-godkendelsesapp.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Uautoriseret",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "Brugeren med brugernavnet <code>{{username}}</code> har ikke tilladelse til at tilgå ressourcen <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "Brugeren med brugernavnet <code>{{username}}</code> har ikke tilladelse til at logge ind.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "Brugeren med brugernavnet <code>{{username}}</code> er ikke i de grupper, som ressourcen <code>{{resource}}</code> kræver.",
|
||||||
|
"unauthorizedButton": "Prøv igen",
|
||||||
|
"untrustedRedirectTitle": "Usikker omdirigering",
|
||||||
|
"untrustedRedirectSubtitle": "Du forsøger at omdirigere til et domæne, der ikke matcher dit konfigurerede domæne (<code>{{domain}}</code>). Er du sikker på, at du vil fortsætte?",
|
||||||
|
"cancelTitle": "Annuller",
|
||||||
|
"forgotPasswordTitle": "Glemt din adgangskode?",
|
||||||
|
"failedToFetchProvidersTitle": "Kunne ikke indlæse godkendelsesudbydere. Tjek venligst din konfiguration.",
|
||||||
|
"errorTitle": "Der opstod en fejl",
|
||||||
|
"errorSubtitle": "Der opstod en fejl under forsøget på at udføre denne handling. Tjek venligst konsollen for mere information."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Willkommen zurück, logge dich ein mit",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Or",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "Benutzername",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "Passwort",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "Anmelden",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailTitle": "Login fehlgeschlagen",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailSubtitle": "Bitte überprüfe deinen Benutzernamen und Passwort",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessTitle": "Angemeldet",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginSuccessSubtitle": "Willkommen zurück!",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthFailSubtitle": "Fehler beim Abrufen der OAuth-URL",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"loginOauthSuccessTitle": "Leite weiter",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"loginOauthSuccessSubtitle": "Weiterleitung zu Ihrem OAuth-Provider",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueRedirectingTitle": "Leite weiter...",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueRedirectingSubtitle": "Sie sollten in Kürze zur App weitergeleitet werden",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInvalidRedirectTitle": "Ungültige Weiterleitung",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInvalidRedirectSubtitle": "Die Weiterleitungs-URL ist ungültig",
|
||||||
"continueTitle": "Continue",
|
"continueInsecureRedirectTitle": "Unsichere Weiterleitung",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
"continueTitle": "Weiter",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
"continueSubtitle": "Klicken Sie auf den Button, um zur App zu gelangen.",
|
||||||
"internalErrorButton": "Try again",
|
"logoutFailTitle": "Abmelden fehlgeschlagen",
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailSubtitle": "Bitte versuchen Sie es erneut",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutSuccessTitle": "Abgemeldet",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessSubtitle": "Sie wurden abgemeldet",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutTitle": "Abmelden",
|
||||||
"logoutTitle": "Logout",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"notFoundTitle": "Seite nicht gefunden",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundSubtitle": "Die gesuchte Seite existiert nicht.",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundButton": "Nach Hause",
|
||||||
"notFoundButton": "Go home",
|
"totpFailTitle": "Fehler beim Verifizieren des Codes",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailSubtitle": "Bitte überprüfen Sie Ihren Code und versuchen Sie es erneut",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpSuccessTitle": "Verifiziert",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessSubtitle": "Leite zur App weiter",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpTitle": "Geben Sie Ihren TOTP Code ein",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unautorisiert",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Erneut versuchen",
|
||||||
|
"untrustedRedirectTitle": "Nicht vertrauenswürdige Weiterleitung",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Abbrechen",
|
||||||
|
"forgotPasswordTitle": "Passwort vergessen?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Καλώς ήρθατε, συνδεθείτε με",
|
"loginTitle": "Καλώς ήρθατε, συνδεθείτε με",
|
||||||
"loginDivider": "Ή συνεχίστε με κωδικό πρόσβασης",
|
"loginTitleSimple": "Καλώς ορίσατε, παρακαλώ συνδεθείτε",
|
||||||
|
"loginDivider": "Ή",
|
||||||
"loginUsername": "Όνομα Χρήστη",
|
"loginUsername": "Όνομα Χρήστη",
|
||||||
"loginPassword": "Κωδικός",
|
"loginPassword": "Κωδικός",
|
||||||
"loginSubmit": "Είσοδος",
|
"loginSubmit": "Είσοδος",
|
||||||
"loginFailTitle": "Αποτυχία σύνδεσης",
|
"loginFailTitle": "Αποτυχία σύνδεσης",
|
||||||
"loginFailSubtitle": "Παρακαλώ ελέγξτε το όνομα χρήστη και τον κωδικό πρόσβασης",
|
"loginFailSubtitle": "Παρακαλώ ελέγξτε το όνομα χρήστη και τον κωδικό πρόσβασης",
|
||||||
|
"loginFailRateLimit": "Αποτύχατε να συνδεθείτε πάρα πολλές φορές. Παρακαλώ προσπαθήστε ξανά αργότερα",
|
||||||
"loginSuccessTitle": "Συνδεδεμένος",
|
"loginSuccessTitle": "Συνδεδεμένος",
|
||||||
"loginSuccessSubtitle": "Καλώς ήρθατε!",
|
"loginSuccessSubtitle": "Καλώς ήρθατε!",
|
||||||
"loginOauthFailTitle": "Εσωτερικό σφάλμα",
|
"loginOauthFailTitle": "Παρουσιάστηκε ένα σφάλμα",
|
||||||
"loginOauthFailSubtitle": "Αποτυχία λήψης OAuth URL",
|
"loginOauthFailSubtitle": "Αποτυχία λήψης OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Ανακατεύθυνση",
|
"loginOauthSuccessTitle": "Ανακατεύθυνση",
|
||||||
"loginOauthSuccessSubtitle": "Ανακατεύθυνση στον πάροχο OAuth σας",
|
"loginOauthSuccessSubtitle": "Ανακατεύθυνση στον πάροχο OAuth σας",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Μη έγκυρη ανακατεύθυνση",
|
"continueInvalidRedirectTitle": "Μη έγκυρη ανακατεύθυνση",
|
||||||
"continueInvalidRedirectSubtitle": "Το URL ανακατεύθυνσης δεν είναι έγκυρο",
|
"continueInvalidRedirectSubtitle": "Το URL ανακατεύθυνσης δεν είναι έγκυρο",
|
||||||
"continueInsecureRedirectTitle": "Μη ασφαλής ανακατεύθυνση",
|
"continueInsecureRedirectTitle": "Μη ασφαλής ανακατεύθυνση",
|
||||||
"continueInsecureRedirectSubtitle": "Προσπαθείτε να ανακατευθύνετε από <Code>https</Code> σε <Code>http</Code>, είστε σίγουροι ότι θέλετε να συνεχίσετε;",
|
"continueInsecureRedirectSubtitle": "Προσπαθείτε να ανακατευθύνετε από <code>https</code> σε <code>http</code> το οποίο δεν είναι ασφαλές. Είστε σίγουροι ότι θέλετε να συνεχίσετε;",
|
||||||
"continueTitle": "Συνέχεια",
|
"continueTitle": "Συνέχεια",
|
||||||
"continueSubtitle": "Κάντε κλικ στο κουμπί για να συνεχίσετε στην εφαρμογή σας.",
|
"continueSubtitle": "Κάντε κλικ στο κουμπί για να συνεχίσετε στην εφαρμογή σας.",
|
||||||
"internalErrorTitle": "Εσωτερικό Σφάλμα Διακομιστή",
|
|
||||||
"internalErrorSubtitle": "Παρουσιάστηκε σφάλμα στο διακομιστή και δεν μπορεί να εξυπηρετήσει το αίτημά σας.",
|
|
||||||
"internalErrorButton": "Προσπαθήστε ξανά",
|
|
||||||
"logoutFailTitle": "Αποτυχία αποσύνδεσης",
|
"logoutFailTitle": "Αποτυχία αποσύνδεσης",
|
||||||
"logoutFailSubtitle": "Παρακαλώ δοκιμάστε ξανά",
|
"logoutFailSubtitle": "Παρακαλώ δοκιμάστε ξανά",
|
||||||
"logoutSuccessTitle": "Αποσυνδεδεμένος",
|
"logoutSuccessTitle": "Αποσυνδεδεμένος",
|
||||||
"logoutSuccessSubtitle": "Έχετε αποσυνδεθεί",
|
"logoutSuccessSubtitle": "Έχετε αποσυνδεθεί",
|
||||||
"logoutTitle": "Αποσύνδεση",
|
"logoutTitle": "Αποσύνδεση",
|
||||||
"logoutUsernameSubtitle": "Αυτή τη στιγμή είστε συνδεδεμένοι ως <Code>{{username}}</Code>, κάντε κλικ στο παρακάτω κουμπί για να αποσυνδεθείτε.",
|
"logoutUsernameSubtitle": "Αυτή τη στιγμή είστε συνδεδεμένοι ως <code>{{username}}</code>. Κάντε κλικ στο παρακάτω κουμπί για να αποσυνδεθείτε.",
|
||||||
"logoutOauthSubtitle": "Αυτή τη στιγμή είστε συνδεδεμένοι ως <Code>{{username}}</Code> χρησιμοποιώντας την υπηρεσία παροχής {{provider}} OAuth, κάντε κλικ στο παρακάτω κουμπί για να αποσυνδεθείτε.",
|
"logoutOauthSubtitle": "Αυτή τη στιγμή είστε συνδεδεμένοι ως <code>{{username}}</code> χρησιμοποιώντας την υπηρεσία παροχής {{provider}} OAuth. Κάντε κλικ στο παρακάτω κουμπί για να αποσυνδεθείτε.",
|
||||||
"notFoundTitle": "Η σελίδα δε βρέθηκε",
|
"notFoundTitle": "Η σελίδα δε βρέθηκε",
|
||||||
"notFoundSubtitle": "Η σελίδα που ψάχνετε δεν υπάρχει.",
|
"notFoundSubtitle": "Η σελίδα που ψάχνετε δεν υπάρχει.",
|
||||||
"notFoundButton": "Μετάβαση στην αρχική",
|
"notFoundButton": "Μετάβαση στην αρχική",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Επαληθεύθηκε",
|
"totpSuccessTitle": "Επαληθεύθηκε",
|
||||||
"totpSuccessSubtitle": "Ανακατεύθυνση στην εφαρμογή σας",
|
"totpSuccessSubtitle": "Ανακατεύθυνση στην εφαρμογή σας",
|
||||||
"totpTitle": "Εισάγετε τον κωδικό TOTP",
|
"totpTitle": "Εισάγετε τον κωδικό TOTP",
|
||||||
|
"totpSubtitle": "Παρακαλώ εισάγετε τον κωδικό από την εφαρμογή ελέγχου ταυτότητας.",
|
||||||
"unauthorizedTitle": "Μη εξουσιοδοτημένο",
|
"unauthorizedTitle": "Μη εξουσιοδοτημένο",
|
||||||
"unauthorizedResourceSubtitle": "Ο χρήστης με όνομα χρήστη {{username}} δεν είναι εξουσιοδοτημένος να έχει πρόσβαση στον πόρο <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "Ο χρήστης με όνομα χρήστη <code>{{username}}</code> δεν έχει άδεια πρόσβασης στον πόρο <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "Ο χρήστης με όνομα χρήστη {{username}} δεν είναι εξουσιοδοτημένος να συνδεθεί.",
|
"unauthorizedLoginSubtitle": "Ο χρήστης με όνομα χρήστη <code>{{username}}</code> δεν είναι εξουσιοδοτημένος να συνδεθεί.",
|
||||||
"unauthorizedButton": "Προσπαθήστε ξανά"
|
"unauthorizedGroupsSubtitle": "Ο χρήστης με όνομα χρήστη <code>{{username}}</code> δεν είναι στις ομάδες που απαιτούνται από τον πόρο <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Προσπαθήστε ξανά",
|
||||||
|
"untrustedRedirectTitle": "Μη έμπιστη ανακατεύθυνση",
|
||||||
|
"untrustedRedirectSubtitle": "Προσπαθείτε να ανακατευθύνετε σε ένα domain που δεν ταιριάζει με τον ρυθμισμένο domain σας (<code>{{domain}}</code>). Είστε βέβαιοι ότι θέλετε να συνεχίσετε;",
|
||||||
|
"cancelTitle": "Ακύρωση",
|
||||||
|
"forgotPasswordTitle": "Ξεχάσατε το συνθηματικό σας;",
|
||||||
|
"failedToFetchProvidersTitle": "Αποτυχία φόρτωσης παρόχων πιστοποίησης. Παρακαλώ ελέγξτε τις ρυθμίσεις σας.",
|
||||||
|
"errorTitle": "Παρουσιάστηκε ένα σφάλμα",
|
||||||
|
"errorSubtitle": "Παρουσιάστηκε σφάλμα κατά την προσπάθεια εκτέλεσης αυτής της ενέργειας. Ελέγξτε την κονσόλα για περισσότερες πληροφορίες."
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
"loginFailRateLimit": "You failed to login too many times, please try again later",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -18,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -39,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
"loginFailRateLimit": "You failed to login too many times, please try again later",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -18,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -39,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Error al obtener la URL de OAuth",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"continueRedirectingTitle": "Redirecting...",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Bienvenue, connectez-vous avec",
|
"loginTitle": "Bienvenue, connectez-vous avec",
|
||||||
"loginDivider": "Ou continuez avec le mot de passe",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Nom d'utilisateur",
|
"loginUsername": "Nom d'utilisateur",
|
||||||
"loginPassword": "Mot de passe",
|
"loginPassword": "Mot de passe",
|
||||||
"loginSubmit": "Se connecter",
|
"loginSubmit": "Se connecter",
|
||||||
"loginFailTitle": "Échec de la connexion",
|
"loginFailTitle": "Échec de la connexion",
|
||||||
"loginFailSubtitle": "Veuillez vérifier votre nom d'utilisateur et votre mot de passe",
|
"loginFailSubtitle": "Veuillez vérifier votre nom d'utilisateur et votre mot de passe",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Connecté",
|
"loginSuccessTitle": "Connecté",
|
||||||
"loginSuccessSubtitle": "Bienvenue!",
|
"loginSuccessSubtitle": "Bienvenue!",
|
||||||
"loginOauthFailTitle": "Erreur interne",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Impossible d'obtenir l'URL OAuth",
|
"loginOauthFailSubtitle": "Impossible d'obtenir l'URL OAuth",
|
||||||
"loginOauthSuccessTitle": "Redirection",
|
"loginOauthSuccessTitle": "Redirection",
|
||||||
"loginOauthSuccessSubtitle": "Redirection vers votre fournisseur OAuth",
|
"loginOauthSuccessSubtitle": "Redirection vers votre fournisseur OAuth",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Redirection invalide",
|
"continueInvalidRedirectTitle": "Redirection invalide",
|
||||||
"continueInvalidRedirectSubtitle": "L'URL de redirection est invalide",
|
"continueInvalidRedirectSubtitle": "L'URL de redirection est invalide",
|
||||||
"continueInsecureRedirectTitle": "Redirection non sécurisée",
|
"continueInsecureRedirectTitle": "Redirection non sécurisée",
|
||||||
"continueInsecureRedirectSubtitle": "Vous essayez de rediriger de <Code>https</Code> vers <Code>http</Code>, êtes-vous sûr de vouloir continuer ?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continuer",
|
"continueTitle": "Continuer",
|
||||||
"continueSubtitle": "Cliquez sur le bouton pour continuer vers votre application.",
|
"continueSubtitle": "Cliquez sur le bouton pour continuer vers votre application.",
|
||||||
"internalErrorTitle": "Erreur interne du serveur",
|
|
||||||
"internalErrorSubtitle": "Une erreur s'est produite sur le serveur et il ne peut actuellement pas répondre à votre demande.",
|
|
||||||
"internalErrorButton": "Réessayer",
|
|
||||||
"logoutFailTitle": "Échec de la déconnexion",
|
"logoutFailTitle": "Échec de la déconnexion",
|
||||||
"logoutFailSubtitle": "Veuillez réessayer",
|
"logoutFailSubtitle": "Veuillez réessayer",
|
||||||
"logoutSuccessTitle": "Déconnecté",
|
"logoutSuccessTitle": "Déconnecté",
|
||||||
"logoutSuccessSubtitle": "Vous avez été déconnecté",
|
"logoutSuccessSubtitle": "Vous avez été déconnecté",
|
||||||
"logoutTitle": "Déconnexion",
|
"logoutTitle": "Déconnexion",
|
||||||
"logoutUsernameSubtitle": "Vous êtes actuellement connecté en tant que <Code>{{username}}</Code>, cliquez sur le bouton ci-dessous pour vous déconnecter.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "Vous êtes actuellement connecté en tant que <Code>{{username}}</Code> en utilisant le fournisseur OAuth {{provider}} , cliquez sur le bouton ci-dessous pour vous déconnecter.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page introuvable",
|
"notFoundTitle": "Page introuvable",
|
||||||
"notFoundSubtitle": "La page recherchée n'existe pas.",
|
"notFoundSubtitle": "La page recherchée n'existe pas.",
|
||||||
"notFoundButton": "Retour à la page d'accueil",
|
"notFoundButton": "Retour à la page d'accueil",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Vérifié",
|
"totpSuccessTitle": "Vérifié",
|
||||||
"totpSuccessSubtitle": "Redirection vers votre application",
|
"totpSuccessSubtitle": "Redirection vers votre application",
|
||||||
"totpTitle": "Saisissez votre code TOTP",
|
"totpTitle": "Saisissez votre code TOTP",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Non autorisé",
|
"unauthorizedTitle": "Non autorisé",
|
||||||
"unauthorizedResourceSubtitle": "L'utilisateur avec le nom d'utilisateur {{username}} n'est pas autorisé à accéder à la ressource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "L'utilisateur avec le nom d'utilisateur {{username}} n'est pas autorisé à se connecter.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Réessayer"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Réessayer",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welkom terug, log in met",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Or",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "Gebruikersnaam",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "Wachtwoord",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "Log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailTitle": "Mislukt om in te loggen",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailSubtitle": "Controleer je gebruikersnaam en wachtwoord",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessTitle": "Ingelogd",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginSuccessSubtitle": "Welkom terug!",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthFailSubtitle": "Fout bij het ophalen van OAuth URL",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"loginOauthSuccessTitle": "Omleiden",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"loginOauthSuccessSubtitle": "Omleiden naar je OAuth provider",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueRedirectingTitle": "Omleiden...",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueRedirectingSubtitle": "Je wordt naar de app doorgestuurd",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInvalidRedirectTitle": "Ongeldige omleiding",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInvalidRedirectSubtitle": "De omleidings-URL is ongeldig",
|
||||||
"continueTitle": "Continue",
|
"continueInsecureRedirectTitle": "Onveilige doorverwijzing",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
"continueTitle": "Ga verder",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
"continueSubtitle": "Klik op de knop om door te gaan naar de app.",
|
||||||
"internalErrorButton": "Try again",
|
"logoutFailTitle": "Afmelden mislukt",
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailSubtitle": "Probeer het opnieuw",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutSuccessTitle": "Afgemeld",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessSubtitle": "Je bent afgemeld",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutTitle": "Afmelden",
|
||||||
"logoutTitle": "Logout",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"notFoundTitle": "Pagina niet gevonden",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundSubtitle": "De pagina die je zoekt bestaat niet.",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundButton": "Naar startpagina",
|
||||||
"notFoundButton": "Go home",
|
"totpFailTitle": "Verifiëren van code mislukt",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailSubtitle": "Controleer je code en probeer het opnieuw",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpSuccessTitle": "Geverifiëerd",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessSubtitle": "Omleiden naar je app",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpTitle": "Voer je TOTP-code in",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Ongeautoriseerd",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Opnieuw proberen",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Witaj ponownie, zaloguj się przez",
|
"loginTitle": "Witaj ponownie, zaloguj się przez",
|
||||||
"loginDivider": "Lub kontynuuj z hasłem",
|
"loginTitleSimple": "Witaj ponownie, zaloguj się",
|
||||||
|
"loginDivider": "lub",
|
||||||
"loginUsername": "Nazwa użytkownika",
|
"loginUsername": "Nazwa użytkownika",
|
||||||
"loginPassword": "Hasło",
|
"loginPassword": "Hasło",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Zaloguj się",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Nie udało się zalogować",
|
||||||
"loginFailSubtitle": "Sprawdź swoją nazwę użytkownika i hasło",
|
"loginFailSubtitle": "Sprawdź swoją nazwę użytkownika i hasło",
|
||||||
|
"loginFailRateLimit": "Zbyt wiele razy nie udało Ci się zalogować. Spróbuj ponownie później",
|
||||||
"loginSuccessTitle": "Zalogowano",
|
"loginSuccessTitle": "Zalogowano",
|
||||||
"loginSuccessSubtitle": "Witaj ponownie!",
|
"loginSuccessSubtitle": "Witaj ponownie!",
|
||||||
"loginOauthFailTitle": "Wewnętrzny błąd",
|
"loginOauthFailTitle": "Wystąpił błąd",
|
||||||
"loginOauthFailSubtitle": "Nie udało się uzyskać adresu URL OAuth",
|
"loginOauthFailSubtitle": "Nie udało się uzyskać adresu URL OAuth",
|
||||||
"loginOauthSuccessTitle": "Przekierowywanie",
|
"loginOauthSuccessTitle": "Przekierowywanie",
|
||||||
"loginOauthSuccessSubtitle": "Przekierowywanie do Twojego dostawcy OAuth",
|
"loginOauthSuccessSubtitle": "Przekierowywanie do Twojego dostawcy OAuth",
|
||||||
@@ -17,29 +19,35 @@
|
|||||||
"continueInvalidRedirectTitle": "Nieprawidłowe przekierowanie",
|
"continueInvalidRedirectTitle": "Nieprawidłowe przekierowanie",
|
||||||
"continueInvalidRedirectSubtitle": "Adres przekierowania jest nieprawidłowy",
|
"continueInvalidRedirectSubtitle": "Adres przekierowania jest nieprawidłowy",
|
||||||
"continueInsecureRedirectTitle": "Niezabezpieczone przekierowanie",
|
"continueInsecureRedirectTitle": "Niezabezpieczone przekierowanie",
|
||||||
"continueInsecureRedirectSubtitle": "Próbujesz przekierować z <Code>https</Code> do <Code>http</Code>, czy na pewno chcesz kontynuować?",
|
"continueInsecureRedirectSubtitle": "Próbujesz przekierować z <code>https</code> do <code>http</code>, co nie jest bezpieczne. Czy na pewno chcesz kontynuować?",
|
||||||
"continueTitle": "Kontynuuj",
|
"continueTitle": "Kontynuuj",
|
||||||
"continueSubtitle": "Kliknij przycisk, aby przejść do aplikacji.",
|
"continueSubtitle": "Kliknij przycisk, aby przejść do aplikacji.",
|
||||||
"internalErrorTitle": "Wewnętrzny błąd serwera",
|
"logoutFailTitle": "Nie udało się wylogować",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Spróbuj ponownie",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
|
||||||
"logoutFailSubtitle": "Spróbuj ponownie",
|
"logoutFailSubtitle": "Spróbuj ponownie",
|
||||||
"logoutSuccessTitle": "Wylogowano",
|
"logoutSuccessTitle": "Wylogowano",
|
||||||
"logoutSuccessSubtitle": "Zostałeś wylogowany",
|
"logoutSuccessSubtitle": "Zostałeś wylogowany",
|
||||||
"logoutTitle": "Wylogowanie",
|
"logoutTitle": "Wylogowanie",
|
||||||
"logoutUsernameSubtitle": "Jesteś aktualnie zalogowany jako <Code>{{username}}</Code>, kliknij przycisk poniżej, aby się wylogować.",
|
"logoutUsernameSubtitle": "Jesteś obecnie zalogowany jako <code>{{username}}</code>. Kliknij poniższy przycisk, aby się wylogować.",
|
||||||
"logoutOauthSubtitle": "Jesteś obecnie zalogowany jako <Code>{{username}}</Code> przy użyciu providera OAuth {{provider}}, kliknij przycisk poniżej, aby się wylogować.",
|
"logoutOauthSubtitle": "Obecnie jesteś zalogowany jako <code>{{username}}</code> przy użyciu dostawcy {{provider}} OAuth. Kliknij poniższy przycisk, aby się wylogować.",
|
||||||
"notFoundTitle": "Strona nie znaleziona",
|
"notFoundTitle": "Nie znaleziono strony",
|
||||||
"notFoundSubtitle": "Strona, której szukasz nie istnieje.",
|
"notFoundSubtitle": "Strona, której szukasz nie istnieje.",
|
||||||
"notFoundButton": "Wróć do strony głównej",
|
"notFoundButton": "Wróć do strony głównej",
|
||||||
"totpFailTitle": "Nie udało się zweryfikować kodu",
|
"totpFailTitle": "Nie udało się zweryfikować kodu",
|
||||||
"totpFailSubtitle": "Sprawdź swój kod i spróbuj ponownie",
|
"totpFailSubtitle": "Sprawdź swój kod i spróbuj ponownie",
|
||||||
"totpSuccessTitle": "Zweryfikowano",
|
"totpSuccessTitle": "Zweryfikowano",
|
||||||
"totpSuccessSubtitle": "Przekierowywanie do aplikacji",
|
"totpSuccessSubtitle": "Przekierowywanie do aplikacji",
|
||||||
"totpTitle": "Wprowadź kod TOTP",
|
"totpTitle": "Wprowadź kod TOTP",
|
||||||
|
"totpSubtitle": "Wpisz kod z aplikacji uwierzytelniającej.",
|
||||||
"unauthorizedTitle": "Nieautoryzowany",
|
"unauthorizedTitle": "Nieautoryzowany",
|
||||||
"unauthorizedResourceSubtitle": "Użytkownik o nazwie {{username}} nie jest upoważniony do uzyskania dostępu do zasobu <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "Użytkownik o nazwie użytkownika <code>{{username}}</code> nie ma uprawnień dostępu do zasobu <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "Użytkownik o nazwie {{username}} nie jest upoważniony do logowania.",
|
"unauthorizedLoginSubtitle": "Użytkownik o nazwie <code>{{username}}</code> nie jest upoważniony do zalogowania się.",
|
||||||
"unauthorizedButton": "Spróbuj ponownie"
|
"unauthorizedGroupsSubtitle": "Użytkownik o nazwie <code>{{username}}</code> nie należy do grup wymaganych przez zasób <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Spróbuj ponownie",
|
||||||
|
"untrustedRedirectTitle": "Niezaufane przekierowanie",
|
||||||
|
"untrustedRedirectSubtitle": "Próbujesz przekierować do domeny, która nie pasuje do Twojej skonfigurowanej domeny (<code>{{domain}}</code>). Czy na pewno chcesz kontynuować?",
|
||||||
|
"cancelTitle": "Anuluj",
|
||||||
|
"forgotPasswordTitle": "Nie pamiętasz hasła?",
|
||||||
|
"failedToFetchProvidersTitle": "Nie udało się załadować dostawców uwierzytelniania. Sprawdź swoją konfigurację.",
|
||||||
|
"errorTitle": "Wystąpił błąd",
|
||||||
|
"errorSubtitle": "Wystąpił błąd podczas próby wykonania tej czynności. Sprawdź konsolę, aby uzyskać więcej informacji."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Bem-vindo de volta, acesse com",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Or",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "Nome de usuário",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "Senha",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "Entrar",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailTitle": "Falha ao iniciar sessão",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailSubtitle": "Por favor, verifique seu usuário e senha",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessTitle": "Sessão Iniciada",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginSuccessSubtitle": "Bem-vindo de volta!",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthFailSubtitle": "Falha ao obter URL de OAuth",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"loginOauthSuccessTitle": "Redirecionando",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"loginOauthSuccessSubtitle": "Redirecionando para seu provedor OAuth",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueRedirectingTitle": "Redirecionando...",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueRedirectingSubtitle": "Você deve ser redirecionado para o aplicativo em breve",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInvalidRedirectTitle": "Redirecionamento inválido",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInvalidRedirectSubtitle": "O endereço de redirecionamento é inválido",
|
||||||
"continueTitle": "Continue",
|
"continueInsecureRedirectTitle": "Redirecionamento inseguro",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
"continueTitle": "Continuar",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
"continueSubtitle": "Clique no botão para continuar para o seu aplicativo.",
|
||||||
"internalErrorButton": "Try again",
|
"logoutFailTitle": "Falha ao encerrar sessão",
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailSubtitle": "Por favor, tente novamente",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutSuccessTitle": "Sessão encerrada",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessSubtitle": "Você foi desconectado",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutTitle": "Sair",
|
||||||
"logoutTitle": "Logout",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"notFoundTitle": "Página não encontrada",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundSubtitle": "A página que você está procurando não existe.",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundButton": "Voltar para a tela inicial",
|
||||||
"notFoundButton": "Go home",
|
"totpFailTitle": "Falha ao verificar código",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailSubtitle": "Por favor, verifique seu código e tente novamente",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpSuccessTitle": "Verificado",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessSubtitle": "Redirecionando para o seu aplicativo",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpTitle": "Insira o seu código TOTP",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Não autorizado",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Tentar novamente",
|
||||||
|
"untrustedRedirectTitle": "Redirecionamento não confiável",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancelar",
|
||||||
|
"forgotPasswordTitle": "Esqueceu sua senha?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "С возвращением, войти с",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Вход",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Или",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "Имя пользователя",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "Пароль",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "Войти",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailTitle": "Вход не удался",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailSubtitle": "Проверьте имя пользователя и пароль",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginFailRateLimit": "Слишком много ошибок входа. Попробуйте позже",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessTitle": "Вы вошли",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginSuccessSubtitle": "С возвращением!",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthFailTitle": "Произошла ошибка",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthFailSubtitle": "Не удалось получить OAuth URL",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"loginOauthSuccessTitle": "Перенаправление",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"loginOauthSuccessSubtitle": "Перенаправление к поставщику OAuth",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueRedirectingTitle": "Перенаправление...",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueRedirectingSubtitle": "Скоро вы будете перенаправлены в приложение",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInvalidRedirectTitle": "Неверное перенаправление",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInvalidRedirectSubtitle": "URL перенаправления недействителен",
|
||||||
"continueTitle": "Continue",
|
"continueInsecureRedirectTitle": "Небезопасное перенаправление",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueInsecureRedirectSubtitle": "Попытка перенаправления с <code>https</code> на <code>http</code>, уверены, что хотите продолжить?",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
"continueTitle": "Продолжить",
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
"continueSubtitle": "Нажмите на кнопку, чтобы перейти к приложению.",
|
||||||
"internalErrorButton": "Try again",
|
"logoutFailTitle": "Не удалось выйти",
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailSubtitle": "Попробуйте ещё раз",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutSuccessTitle": "Выход",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessSubtitle": "Вы вышли из системы",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutTitle": "Выйти",
|
||||||
"logoutTitle": "Logout",
|
"logoutUsernameSubtitle": "Вход выполнен как <code>{{username}}</code>, нажмите на кнопку ниже, чтобы выйти.",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutOauthSubtitle": "Вход выполнен как <code>{{username}}</code> с использованием {{provider}} OAuth, нажмите кнопку ниже, чтобы выйти.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"notFoundTitle": "Страница не найдена",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundSubtitle": "Эта страница не существует.",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundButton": "На главную",
|
||||||
"notFoundButton": "Go home",
|
"totpFailTitle": "Не удалось проверить код",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailSubtitle": "Пожалуйста, проверьте свой код и повторите попытку",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpSuccessTitle": "Подтверждён",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessSubtitle": "Перенаправление в приложение",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpTitle": "Введите код TOTP",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpSubtitle": "Пожалуйста, введите код из вашего приложения — аутентификатора.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Доступ запрещен",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "Пользователю <code>{{username}}</code> не разрешен доступ к <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "Пользователю <code>{{username}}</code> не разрешен вход.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "Пользователь <code>{{username}}</code> не состоит в группах, которым разрешен доступ к <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Повторить",
|
||||||
|
"untrustedRedirectTitle": "Ненадежное перенаправление",
|
||||||
|
"untrustedRedirectSubtitle": "Попытка перенаправить на домен, который не соответствует вашему заданному домену (<code>{{domain}}</code>). Уверены, что хотите продолжить?",
|
||||||
|
"cancelTitle": "Отмена",
|
||||||
|
"forgotPasswordTitle": "Забыли пароль?",
|
||||||
|
"failedToFetchProvidersTitle": "Не удалось загрузить провайдеров аутентификации. Пожалуйста, проверьте конфигурацию.",
|
||||||
|
"errorTitle": "Произошла ошибка",
|
||||||
|
"errorSubtitle": "Произошла ошибка при попытке выполнить это действие. Проверьте консоль для дополнительной информации."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,53 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
"loginUsername": "Username",
|
"loginDivider": "Or",
|
||||||
"loginPassword": "Password",
|
"loginUsername": "Kullanıcı Adı",
|
||||||
"loginSubmit": "Login",
|
"loginPassword": "Şifre",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginSubmit": "Giriş Yap",
|
||||||
|
"loginFailTitle": "Giriş yapılamadı",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessTitle": "Giriş yapıldı",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginSuccessSubtitle": "Tekrar hoş geldiniz!",
|
||||||
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Yönlendiriliyor",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
"continueRedirectingTitle": "Redirecting...",
|
"continueRedirectingTitle": "Yönlendiriliyor...",
|
||||||
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
"continueRedirectingSubtitle": "You should be redirected to the app soon",
|
||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Devam et",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Lütfen tekrar deneyin",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Çıkış yapıldı",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Sayfa bulunamadı",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "Aradığınız sayfa mevcut değil.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Ana sayfaya git",
|
||||||
"totpFailTitle": "Failed to verify code",
|
"totpFailTitle": "Kod doğrulanamadı",
|
||||||
"totpFailSubtitle": "Please check your code and try again",
|
"totpFailSubtitle": "Please check your code and try again",
|
||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Doğrulandı",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "İptal",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"loginTitle": "Welcome back, login with",
|
"loginTitle": "Welcome back, login with",
|
||||||
"loginDivider": "Or continue with password",
|
"loginTitleSimple": "Welcome back, please login",
|
||||||
|
"loginDivider": "Or",
|
||||||
"loginUsername": "Username",
|
"loginUsername": "Username",
|
||||||
"loginPassword": "Password",
|
"loginPassword": "Password",
|
||||||
"loginSubmit": "Login",
|
"loginSubmit": "Login",
|
||||||
"loginFailTitle": "Failed to log in",
|
"loginFailTitle": "Failed to log in",
|
||||||
"loginFailSubtitle": "Please check your username and password",
|
"loginFailSubtitle": "Please check your username and password",
|
||||||
|
"loginFailRateLimit": "You failed to login too many times. Please try again later",
|
||||||
"loginSuccessTitle": "Logged in",
|
"loginSuccessTitle": "Logged in",
|
||||||
"loginSuccessSubtitle": "Welcome back!",
|
"loginSuccessSubtitle": "Welcome back!",
|
||||||
"loginOauthFailTitle": "Internal error",
|
"loginOauthFailTitle": "An error occurred",
|
||||||
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
"loginOauthFailSubtitle": "Failed to get OAuth URL",
|
||||||
"loginOauthSuccessTitle": "Redirecting",
|
"loginOauthSuccessTitle": "Redirecting",
|
||||||
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
|
||||||
@@ -17,19 +19,16 @@
|
|||||||
"continueInvalidRedirectTitle": "Invalid redirect",
|
"continueInvalidRedirectTitle": "Invalid redirect",
|
||||||
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
|
||||||
"continueInsecureRedirectTitle": "Insecure redirect",
|
"continueInsecureRedirectTitle": "Insecure redirect",
|
||||||
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
|
"continueInsecureRedirectSubtitle": "You are trying to redirect from <code>https</code> to <code>http</code> which is not secure. Are you sure you want to continue?",
|
||||||
"continueTitle": "Continue",
|
"continueTitle": "Continue",
|
||||||
"continueSubtitle": "Click the button to continue to your app.",
|
"continueSubtitle": "Click the button to continue to your app.",
|
||||||
"internalErrorTitle": "Internal Server Error",
|
|
||||||
"internalErrorSubtitle": "An error occurred on the server and it currently cannot serve your request.",
|
|
||||||
"internalErrorButton": "Try again",
|
|
||||||
"logoutFailTitle": "Failed to log out",
|
"logoutFailTitle": "Failed to log out",
|
||||||
"logoutFailSubtitle": "Please try again",
|
"logoutFailSubtitle": "Please try again",
|
||||||
"logoutSuccessTitle": "Logged out",
|
"logoutSuccessTitle": "Logged out",
|
||||||
"logoutSuccessSubtitle": "You have been logged out",
|
"logoutSuccessSubtitle": "You have been logged out",
|
||||||
"logoutTitle": "Logout",
|
"logoutTitle": "Logout",
|
||||||
"logoutUsernameSubtitle": "You are currently logged in as <Code>{{username}}</Code>, click the button below to logout.",
|
"logoutUsernameSubtitle": "You are currently logged in as <code>{{username}}</code>. Click the button below to logout.",
|
||||||
"logoutOauthSubtitle": "You are currently logged in as <Code>{{username}}</Code> using the {{provider}} OAuth provider, click the button below to logout.",
|
"logoutOauthSubtitle": "You are currently logged in as <code>{{username}}</code> using the {{provider}} OAuth provider. Click the button below to logout.",
|
||||||
"notFoundTitle": "Page not found",
|
"notFoundTitle": "Page not found",
|
||||||
"notFoundSubtitle": "The page you are looking for does not exist.",
|
"notFoundSubtitle": "The page you are looking for does not exist.",
|
||||||
"notFoundButton": "Go home",
|
"notFoundButton": "Go home",
|
||||||
@@ -38,8 +37,17 @@
|
|||||||
"totpSuccessTitle": "Verified",
|
"totpSuccessTitle": "Verified",
|
||||||
"totpSuccessSubtitle": "Redirecting to your app",
|
"totpSuccessSubtitle": "Redirecting to your app",
|
||||||
"totpTitle": "Enter your TOTP code",
|
"totpTitle": "Enter your TOTP code",
|
||||||
|
"totpSubtitle": "Please enter the code from your authenticator app.",
|
||||||
"unauthorizedTitle": "Unauthorized",
|
"unauthorizedTitle": "Unauthorized",
|
||||||
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
|
"unauthorizedResourceSubtitle": "The user with username <code>{{username}}</code> is not authorized to access the resource <code>{{resource}}</code>.",
|
||||||
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
|
"unauthorizedLoginSubtitle": "The user with username <code>{{username}}</code> is not authorized to login.",
|
||||||
"unauthorizedButton": "Try again"
|
"unauthorizedGroupsSubtitle": "The user with username <code>{{username}}</code> is not in the groups required by the resource <code>{{resource}}</code>.",
|
||||||
|
"unauthorizedButton": "Try again",
|
||||||
|
"untrustedRedirectTitle": "Untrusted redirect",
|
||||||
|
"untrustedRedirectSubtitle": "You are trying to redirect to a domain that does not match your configured domain (<code>{{domain}}</code>). Are you sure you want to continue?",
|
||||||
|
"cancelTitle": "Cancel",
|
||||||
|
"forgotPasswordTitle": "Forgot your password?",
|
||||||
|
"failedToFetchProvidersTitle": "Failed to load authentication providers. Please check your configuration.",
|
||||||
|
"errorTitle": "An error occurred",
|
||||||
|
"errorSubtitle": "An error occurred while trying to perform this action. Please check the console for more information."
|
||||||
}
|
}
|
||||||