Compare commits

..

3 Commits

Author SHA1 Message Date
Stavros
156bba6141 tests: fix tests 2025-03-18 21:48:26 +02:00
Stavros
7d1252f3c7 refactor: use prefix instead of patern in docker meta 2025-03-15 23:58:42 +02:00
Stavros
0c91465c63 wip 2025-03-15 17:44:41 +02:00
112 changed files with 339 additions and 2021 deletions

View File

@@ -26,17 +26,17 @@ jobs:
- name: Install frontend dependencies - name: Install frontend dependencies
run: | run: |
cd frontend cd site
bun install bun install
- name: Build frontend - name: Build frontend
run: | run: |
cd frontend cd site
bun run build bun run build
- name: Copy frontend - name: Copy frontend
run: | run: |
cp -r frontend/dist internal/assets/dist cp -r site/dist internal/assets/dist
- name: Run tests - name: Run tests
run: go test -v ./... run: go test -v ./...

View File

@@ -1,48 +0,0 @@
name: Publish translations
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Move translations
run: |
mkdir -p dist
mv frontend/src/lib/i18n/locales 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

View File

@@ -20,22 +20,22 @@ 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 errors, to install the go requirements, run:
```sh ```sh
go mod tidy go mod tidy
``` ```
You also need to download the frontend dependencies, this can be done like so: You also need to download the frontend requirements, this can be done like so:
```sh ```sh
cd frontend/ cd site/
bun install 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 ocnfigure 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.
## Developing ## Developing

View File

@@ -1,22 +1,22 @@
# Site builder # Site builder
FROM oven/bun:1.1.45-alpine AS frontend-builder FROM oven/bun:1.1.45-alpine AS site-builder
WORKDIR /frontend WORKDIR /site
COPY ./frontend/package.json ./ COPY ./site/package.json ./
COPY ./frontend/bun.lockb ./ COPY ./site/bun.lockb ./
RUN bun install RUN bun install
COPY ./frontend/public ./public COPY ./site/public ./public
COPY ./frontend/src ./src COPY ./site/src ./src
COPY ./frontend/eslint.config.js ./ COPY ./site/eslint.config.js ./
COPY ./frontend/index.html ./ COPY ./site/index.html ./
COPY ./frontend/tsconfig.json ./ COPY ./site/tsconfig.json ./
COPY ./frontend/tsconfig.app.json ./ COPY ./site/tsconfig.app.json ./
COPY ./frontend/tsconfig.node.json ./ COPY ./site/tsconfig.node.json ./
COPY ./frontend/vite.config.ts ./ COPY ./site/vite.config.ts ./
COPY ./frontend/postcss.config.cjs ./ COPY ./site/postcss.config.cjs ./
RUN bun run build RUN bun run build
@@ -33,7 +33,7 @@ RUN go mod download
COPY ./main.go ./ COPY ./main.go ./
COPY ./cmd ./cmd COPY ./cmd ./cmd
COPY ./internal ./internal COPY ./internal ./internal
COPY --from=frontend-builder /frontend/dist ./internal/assets/dist COPY --from=site-builder /site/dist ./internal/assets/dist
RUN CGO_ENABLED=0 go build -ldflags "-s -w" RUN CGO_ENABLED=0 go build -ldflags "-s -w"
@@ -42,13 +42,8 @@ FROM alpine:3.21 AS runner
WORKDIR /tinyauth WORKDIR /tinyauth
RUN apk add --no-cache curl
COPY --from=builder /tinyauth/tinyauth ./ 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"]

View File

@@ -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="256" src="site/public/logo.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>
@@ -10,7 +10,6 @@
<img alt="Commit activity" src="https://img.shields.io/github/commit-activity/w/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>
</div> </div>
<br /> <br />
@@ -39,10 +38,6 @@ You can find documentation and guides on all available configuration of tinyauth
All contributions to the codebase are welcome! If you have any recommendations on how to improve security or find a security issue in tinyauth please open an issue or pull request so it can be fixed as soon as possible! All contributions to the codebase are welcome! If you have any recommendations on how to improve security or find a security issue in tinyauth please open an issue or pull request so it can be fixed as soon as possible!
## Localization
If you would like to help translating the project in more languages you can do so by visiting the [Crowdin](https://crowdin.com/project/tinyauth) page.
## License ## License
Tinyauth is licensed under the GNU General Public License v3.0. TL;DR — You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions. For more information about the license check the [license](./LICENSE) file. Tinyauth is licensed under the GNU General Public License v3.0. TL;DR — You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions. For more information about the license check the [license](./LICENSE) file.

View File

@@ -2,6 +2,7 @@ root = "/tinyauth"
tmp_dir = "tmp" tmp_dir = "tmp"
[build] [build]
pre_cmd = ["go mod tidy"]
cmd = "go build -o ./tmp/tinyauth ." cmd = "go build -o ./tmp/tinyauth ."
bin = "tmp/tinyauth" bin = "tmp/tinyauth"
include_ext = ["go"] include_ext = ["go"]

View File

@@ -14,7 +14,7 @@
}, },
"timestamp": "2025-03-10T19:00:00.000Z", "timestamp": "2025-03-10T19:00:00.000Z",
"thumbnail": { "thumbnail": {
"url": "https://github.com/steveiliop56/tinyauth/blob/main/frontend/public/logo.png?raw=true" "url": "https://github.com/steveiliop56/tinyauth/blob/main/site/public/logo.png?raw=true"
} }
} }
], ],

View File

@@ -117,8 +117,8 @@ var rootCmd = &cobra.Command{
docker := docker.NewDocker() docker := docker.NewDocker()
// Initialize docker // Initialize docker
err = docker.Init() dockerErr := docker.Init()
HandleError(err, "Failed to initialize docker") HandleError(dockerErr, "Failed to initialize docker")
// Create auth service // Create auth service
auth := auth.NewAuth(docker, users, oauthWhitelist, config.SessionExpiry) auth := auth.NewAuth(docker, users, oauthWhitelist, config.SessionExpiry)
@@ -133,7 +133,7 @@ var rootCmd = &cobra.Command{
hooks := hooks.NewHooks(auth, providers) hooks := hooks.NewHooks(auth, providers)
// Create handlers // Create handlers
handlers := handlers.NewHandlers(serverConfig, auth, hooks, providers, docker) handlers := handlers.NewHandlers(serverConfig, auth, hooks, providers)
// Create API // Create API
api := api.NewAPI(apiConfig, handlers) api := api.NewAPI(apiConfig, handlers)

View File

@@ -18,7 +18,7 @@ import (
// Interactive flag // Interactive flag
var interactive bool var interactive bool
// Input user // i stands for input
var iUser string var iUser string
var GenerateCmd = &cobra.Command{ var GenerateCmd = &cobra.Command{
@@ -46,18 +46,18 @@ var GenerateCmd = &cobra.Command{
) )
// Run form // Run form
err := form.WithTheme(baseTheme).Run() formErr := form.WithTheme(baseTheme).Run()
if err != nil { if formErr != nil {
log.Fatal().Err(err).Msg("Form failed") log.Fatal().Err(formErr).Msg("Form failed")
} }
} }
// Parse user // Parse user
user, err := utils.ParseUser(iUser) user, parseErr := utils.ParseUser(iUser)
if err != nil { if parseErr != nil {
log.Fatal().Err(err).Msg("Failed to parse user") log.Fatal().Err(parseErr).Msg("Failed to parse user")
} }
// Check if user was using docker escape // Check if user was using docker escape
@@ -73,13 +73,13 @@ var GenerateCmd = &cobra.Command{
} }
// Generate totp secret // Generate totp secret
key, err := totp.Generate(totp.GenerateOpts{ key, keyErr := totp.Generate(totp.GenerateOpts{
Issuer: "Tinyauth", Issuer: "Tinyauth",
AccountName: user.Username, AccountName: user.Username,
}) })
if err != nil { if keyErr != nil {
log.Fatal().Err(err).Msg("Failed to generate totp secret") log.Fatal().Err(keyErr).Msg("Failed to generate totp secret")
} }
// Create secret // Create secret

View File

@@ -12,10 +12,7 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
// Interactive flag
var interactive bool var interactive bool
// Docker flag
var docker bool var docker bool
// i stands for input // i stands for input
@@ -54,10 +51,10 @@ var CreateCmd = &cobra.Command{
// Use simple theme // Use simple theme
var baseTheme *huh.Theme = huh.ThemeBase() var baseTheme *huh.Theme = huh.ThemeBase()
err := form.WithTheme(baseTheme).Run() formErr := form.WithTheme(baseTheme).Run()
if err != nil { if formErr != nil {
log.Fatal().Err(err).Msg("Form failed") log.Fatal().Err(formErr).Msg("Form failed")
} }
} }
@@ -69,10 +66,10 @@ var CreateCmd = &cobra.Command{
log.Info().Str("username", iUsername).Str("password", iPassword).Bool("docker", docker).Msg("Creating user") log.Info().Str("username", iUsername).Str("password", iPassword).Bool("docker", docker).Msg("Creating user")
// Hash password // Hash password
password, err := bcrypt.GenerateFromPassword([]byte(iPassword), bcrypt.DefaultCost) password, passwordErr := bcrypt.GenerateFromPassword([]byte(iPassword), bcrypt.DefaultCost)
if err != nil { if passwordErr != nil {
log.Fatal().Err(err).Msg("Failed to hash password") log.Fatal().Err(passwordErr).Msg("Failed to hash password")
} }
// Convert password to string // Convert password to string

View File

@@ -12,10 +12,7 @@ import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
) )
// Interactive flag
var interactive bool var interactive bool
// Docker flag
var docker bool var docker bool
// i stands for input // i stands for input
@@ -63,18 +60,18 @@ var VerifyCmd = &cobra.Command{
) )
// Run form // Run form
err := form.WithTheme(baseTheme).Run() formErr := form.WithTheme(baseTheme).Run()
if err != nil { if formErr != nil {
log.Fatal().Err(err).Msg("Form failed") log.Fatal().Err(formErr).Msg("Form failed")
} }
} }
// Parse user // Parse user
user, err := utils.ParseUser(iUser) user, userErr := utils.ParseUser(iUser)
if err != nil { if userErr != nil {
log.Fatal().Err(err).Msg("Failed to parse user") log.Fatal().Err(userErr).Msg("Failed to parse user")
} }
// Compare username // Compare username
@@ -83,9 +80,9 @@ var VerifyCmd = &cobra.Command{
} }
// Compare password // Compare password
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(iPassword)) verifyErr := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(iPassword))
if err != nil { if verifyErr != nil {
log.Fatal().Msg("Ppassword is incorrect") log.Fatal().Msg("Ppassword is incorrect")
} }
@@ -99,9 +96,9 @@ var VerifyCmd = &cobra.Command{
} }
// Check totp code // Check totp code
ok := totp.Validate(iTotp, user.TotpSecret) totpOk := totp.Validate(iTotp, user.TotpSecret)
if !ok { if !totpOk {
log.Fatal().Msg("Totp code incorrect") log.Fatal().Msg("Totp code incorrect")
} }

View File

@@ -1,12 +0,0 @@
"base_path": "."
"base_url": "https://api.crowdin.com"
"preserve_hierarchy": true
files:
[
{
"source": "/frontend/src/lib/i18n/locales/en.json",
"translation": "/frontend/src/lib/i18n/locales/%locale%.json",
},
]

View File

@@ -14,20 +14,22 @@ services:
labels: labels:
traefik.enable: true traefik.enable: true
traefik.http.routers.nginx.rule: Host(`whoami.example.com`) traefik.http.routers.nginx.rule: Host(`whoami.example.com`)
traefik.http.services.nginx.loadbalancer.server.port: 80
traefik.http.routers.nginx.middlewares: tinyauth traefik.http.routers.nginx.middlewares: tinyauth
tinyauth-frontend: tinyauth-frontend:
container_name: tinyauth-frontend container_name: tinyauth-frontend
build: build:
context: . context: .
dockerfile: frontend/Dockerfile.dev dockerfile: site/Dockerfile.dev
volumes: volumes:
- ./frontend/src:/frontend/src - ./site/src:/site/src
ports: ports:
- 5173:5173 - 5173:5173
labels: labels:
traefik.enable: true traefik.enable: true
traefik.http.routers.tinyauth.rule: Host(`tinyauth.example.com`) traefik.http.routers.tinyauth.rule: Host(`tinyauth.example.com`)
traefik.http.services.tinyauth.loadbalancer.server.port: 5173
tinyauth-backend: tinyauth-backend:
container_name: tinyauth-backend container_name: tinyauth-backend
@@ -39,7 +41,6 @@ services:
- ./internal:/tinyauth/internal - ./internal:/tinyauth/internal
- ./cmd:/tinyauth/cmd - ./cmd:/tinyauth/cmd
- ./main.go:/tinyauth/main.go - ./main.go:/tinyauth/main.go
- /var/run/docker.sock:/var/run/docker.sock
ports: ports:
- 3000:3000 - 3000:3000
labels: labels:

View File

@@ -14,6 +14,7 @@ services:
labels: labels:
traefik.enable: true traefik.enable: true
traefik.http.routers.nginx.rule: Host(`whoami.example.com`) traefik.http.routers.nginx.rule: Host(`whoami.example.com`)
traefik.http.services.nginx.loadbalancer.server.port: 80
traefik.http.routers.nginx.middlewares: tinyauth traefik.http.routers.nginx.middlewares: tinyauth
tinyauth: tinyauth:
@@ -26,4 +27,5 @@ services:
labels: labels:
traefik.enable: true traefik.enable: true
traefik.http.routers.tinyauth.rule: Host(`tinyauth.example.com`) traefik.http.routers.tinyauth.rule: Host(`tinyauth.example.com`)
traefik.http.services.tinyauth.loadbalancer.server.port: 3000
traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik

View File

@@ -1,23 +0,0 @@
FROM oven/bun:1.1.45-alpine
WORKDIR /frontend
COPY ./frontend/package.json ./
COPY ./frontend/bun.lockb ./
RUN bun install
COPY ./frontend/public ./public
COPY ./frontend/src ./src
COPY ./frontend/eslint.config.js ./
COPY ./frontend/index.html ./
COPY ./frontend/tsconfig.json ./
COPY ./frontend/tsconfig.app.json ./
COPY ./frontend/tsconfig.node.json ./
COPY ./frontend/vite.config.ts ./
COPY ./frontend/postcss.config.cjs ./
EXPOSE 5173
ENTRYPOINT ["bun", "run", "dev"]

Binary file not shown.

View File

@@ -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}
/>
);
};

View File

@@ -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>
</>
);
};

View File

@@ -1,37 +0,0 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import ChainedBackend from "i18next-chained-backend";
import resourcesToBackend from "i18next-resources-to-backend";
import HttpBackend from "i18next-http-backend";
i18n
.use(ChainedBackend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: "en",
debug: import.meta.env.MODE === "development",
interpolation: {
escapeValue: false,
},
load: "currentOnly",
backend: {
backends: [
HttpBackend,
resourcesToBackend(
(language: string) => import(`./locales/${language}.json`),
),
],
backendOptions: [
{
loadPath: "https://cdn.tinyauth.app/i18n/{{lng}}.json",
},
],
},
});
export default i18n;

View File

@@ -1,36 +0,0 @@
export const languages = {
"af-ZA": "Afrikaans",
"ar-SA": "العربية",
"ca-ES": "Català",
"cs-CZ": "Čeština",
"da-DK": "Dansk",
"de-DE": "Deutsch",
"el-GR": "Ελληνικά",
"en-US": "English",
"es-ES": "Español",
"fi-FI": "Suomi",
"fr-FR": "Français",
"he-IL": "עברית",
"hu-HU": "Magyar",
"it-IT": "Italiano",
"ja-JP": "日本語",
"ko-KR": "한국어",
"nl-NL": "Nederlands",
"no-NO": "Norsk",
"pl-PL": "Polski",
"pt-BR": "Português",
"pt-PT": "Português",
"ro-RO": "Română",
"ru-RU": "Русский",
"sr-SP": "Српски",
"sv-SE": "Svenska",
"tr-TR": "Türkçe",
"uk-UA": "Українська",
"vi-VN": "Tiếng Việt",
"zh-CN": "中文",
"zh-TW": "中文"
}
export type SupportedLanguage = keyof typeof languages;
export const getLanguageName = (language: SupportedLanguage): string => languages[language];

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Καλώς ήρθατε, συνδεθείτε με",
"loginDivider": "Ή συνεχίστε με κωδικό πρόσβασης",
"loginUsername": "Όνομα Χρήστη",
"loginPassword": "Κωδικός",
"loginSubmit": "Είσοδος",
"loginFailTitle": "Αποτυχία σύνδεσης",
"loginFailSubtitle": "Παρακαλώ ελέγξτε το όνομα χρήστη και τον κωδικό πρόσβασης",
"loginSuccessTitle": "Συνδεδεμένος",
"loginSuccessSubtitle": "Καλώς ήρθατε!",
"loginOauthFailTitle": "Εσωτερικό σφάλμα",
"loginOauthFailSubtitle": "Αποτυχία λήψης OAuth URL",
"loginOauthSuccessTitle": "Ανακατεύθυνση",
"loginOauthSuccessSubtitle": "Ανακατεύθυνση στον πάροχο OAuth σας",
"continueRedirectingTitle": "Ανακατεύθυνση...",
"continueRedirectingSubtitle": "Θα πρέπει να μεταφερθείτε σύντομα στην εφαρμογή σας",
"continueInvalidRedirectTitle": "Μη έγκυρη ανακατεύθυνση",
"continueInvalidRedirectSubtitle": "Το URL ανακατεύθυνσης δεν είναι έγκυρο",
"continueInsecureRedirectTitle": "Μη ασφαλής ανακατεύθυνση",
"continueInsecureRedirectSubtitle": "Προσπαθείτε να ανακατευθύνετε από <Code>https</Code> σε <Code>http</Code>, είστε σίγουροι ότι θέλετε να συνεχίσετε;",
"continueTitle": "Συνέχεια",
"continueSubtitle": "Κάντε κλικ στο κουμπί για να συνεχίσετε στην εφαρμογή σας.",
"internalErrorTitle": "Εσωτερικό Σφάλμα Διακομιστή",
"internalErrorSubtitle": "Παρουσιάστηκε σφάλμα στο διακομιστή και δεν μπορεί να εξυπηρετήσει το αίτημά σας.",
"internalErrorButton": "Προσπαθήστε ξανά",
"logoutFailTitle": "Αποτυχία αποσύνδεσης",
"logoutFailSubtitle": "Παρακαλώ δοκιμάστε ξανά",
"logoutSuccessTitle": "Αποσυνδεδεμένος",
"logoutSuccessSubtitle": "Έχετε αποσυνδεθεί",
"logoutTitle": "Αποσύνδεση",
"logoutUsernameSubtitle": "Αυτή τη στιγμή είστε συνδεδεμένοι ως <Code>{{username}}</Code>, κάντε κλικ στο παρακάτω κουμπί για να αποσυνδεθείτε.",
"logoutOauthSubtitle": "Αυτή τη στιγμή είστε συνδεδεμένοι ως <Code>{{username}}</Code> χρησιμοποιώντας την υπηρεσία παροχής {{provider}} OAuth, κάντε κλικ στο παρακάτω κουμπί για να αποσυνδεθείτε.",
"notFoundTitle": "Η σελίδα δε βρέθηκε",
"notFoundSubtitle": "Η σελίδα που ψάχνετε δεν υπάρχει.",
"notFoundButton": "Μετάβαση στην αρχική",
"totpFailTitle": "Αποτυχία επαλήθευσης κωδικού",
"totpFailSubtitle": "Παρακαλώ ελέγξτε τον κώδικά σας και προσπαθήστε ξανά",
"totpSuccessTitle": "Επαληθεύθηκε",
"totpSuccessSubtitle": "Ανακατεύθυνση στην εφαρμογή σας",
"totpTitle": "Εισάγετε τον κωδικό TOTP",
"unauthorizedTitle": "Μη εξουσιοδοτημένο",
"unauthorizedResourceSubtitle": "Ο χρήστης με όνομα χρήστη {{username}} δεν είναι εξουσιοδοτημένος να έχει πρόσβαση στον πόρο <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "Ο χρήστης με όνομα χρήστη {{username}} δεν είναι εξουσιοδοτημένος να συνδεθεί.",
"unauthorizedButton": "Προσπαθήστε ξανά"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Bienvenue, connectez-vous avec",
"loginDivider": "Ou continuez avec le mot de passe",
"loginUsername": "Nom d'utilisateur",
"loginPassword": "Mot de passe",
"loginSubmit": "Se connecter",
"loginFailTitle": "Échec de la connexion",
"loginFailSubtitle": "Veuillez vérifier votre nom d'utilisateur et votre mot de passe",
"loginSuccessTitle": "Connecté",
"loginSuccessSubtitle": "Bienvenue!",
"loginOauthFailTitle": "Erreur interne",
"loginOauthFailSubtitle": "Impossible d'obtenir l'URL OAuth",
"loginOauthSuccessTitle": "Redirection",
"loginOauthSuccessSubtitle": "Redirection vers votre fournisseur OAuth",
"continueRedirectingTitle": "Redirection...",
"continueRedirectingSubtitle": "Vous devriez être redirigé vers l'application bientôt",
"continueInvalidRedirectTitle": "Redirection invalide",
"continueInvalidRedirectSubtitle": "L'URL de redirection est invalide",
"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 ?",
"continueTitle": "Continuer",
"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",
"logoutFailSubtitle": "Veuillez réessayer",
"logoutSuccessTitle": "Déconnecté",
"logoutSuccessSubtitle": "Vous avez été déconnecté",
"logoutTitle": "Déconnexion",
"logoutUsernameSubtitle": "Vous êtes actuellement connecté en tant que <Code>{{username}}</Code>, cliquez sur le bouton ci-dessous pour vous déconnecter.",
"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.",
"notFoundTitle": "Page introuvable",
"notFoundSubtitle": "La page recherchée n'existe pas.",
"notFoundButton": "Retour à la page d'accueil",
"totpFailTitle": "Échec de la vérification du code",
"totpFailSubtitle": "Veuillez vérifier votre code et réessayer",
"totpSuccessTitle": "Vérifié",
"totpSuccessSubtitle": "Redirection vers votre application",
"totpTitle": "Saisissez votre code TOTP",
"unauthorizedTitle": "Non autorisé",
"unauthorizedResourceSubtitle": "L'utilisateur avec le nom d'utilisateur {{username}} n'est pas autorisé à accéder à la ressource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "L'utilisateur avec le nom d'utilisateur {{username}} n'est pas autorisé à se connecter.",
"unauthorizedButton": "Réessayer"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Witaj ponownie, zaloguj się przez",
"loginDivider": "Lub kontynuuj z hasłem",
"loginUsername": "Nazwa użytkownika",
"loginPassword": "Hasło",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Sprawdź swoją nazwę użytkownika i hasło",
"loginSuccessTitle": "Zalogowano",
"loginSuccessSubtitle": "Witaj ponownie!",
"loginOauthFailTitle": "Wewnętrzny błąd",
"loginOauthFailSubtitle": "Nie udało się uzyskać adresu URL OAuth",
"loginOauthSuccessTitle": "Przekierowywanie",
"loginOauthSuccessSubtitle": "Przekierowywanie do Twojego dostawcy OAuth",
"continueRedirectingTitle": "Przekierowywanie...",
"continueRedirectingSubtitle": "Wkrótce powinieneś zostać przekierowany do aplikacji",
"continueInvalidRedirectTitle": "Nieprawidłowe przekierowanie",
"continueInvalidRedirectSubtitle": "Adres przekierowania jest nieprawidłowy",
"continueInsecureRedirectTitle": "Niezabezpieczone przekierowanie",
"continueInsecureRedirectSubtitle": "Próbujesz przekierować z <Code>https</Code> do <Code>http</Code>, czy na pewno chcesz kontynuować?",
"continueTitle": "Kontynuuj",
"continueSubtitle": "Kliknij przycisk, aby przejść do aplikacji.",
"internalErrorTitle": "Wewnętrzny błąd serwera",
"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",
"logoutSuccessTitle": "Wylogowano",
"logoutSuccessSubtitle": "Zostałeś wylogowany",
"logoutTitle": "Wylogowanie",
"logoutUsernameSubtitle": "Jesteś aktualnie zalogowany jako <Code>{{username}}</Code>, kliknij przycisk poniżej, aby się wylogować.",
"logoutOauthSubtitle": "Jesteś obecnie zalogowany jako <Code>{{username}}</Code> przy użyciu providera OAuth {{provider}}, kliknij przycisk poniżej, aby się wylogować.",
"notFoundTitle": "Strona nie znaleziona",
"notFoundSubtitle": "Strona, której szukasz nie istnieje.",
"notFoundButton": "Wróć do strony głównej",
"totpFailTitle": "Nie udało się zweryfikować kodu",
"totpFailSubtitle": "Sprawdź swój kod i spróbuj ponownie",
"totpSuccessTitle": "Zweryfikowano",
"totpSuccessSubtitle": "Przekierowywanie do aplikacji",
"totpTitle": "Wprowadź kod TOTP",
"unauthorizedTitle": "Nieautoryzowany",
"unauthorizedResourceSubtitle": "Użytkownik o nazwie {{username}} nie jest upoważniony do uzyskania dostępu do zasobu <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "Użytkownik o nazwie {{username}} nie jest upoważniony do logowania.",
"unauthorizedButton": "Spróbuj ponownie"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -1,45 +0,0 @@
{
"loginTitle": "Welcome back, login with",
"loginDivider": "Or continue with password",
"loginUsername": "Username",
"loginPassword": "Password",
"loginSubmit": "Login",
"loginFailTitle": "Failed to log in",
"loginFailSubtitle": "Please check your username and password",
"loginSuccessTitle": "Logged in",
"loginSuccessSubtitle": "Welcome back!",
"loginOauthFailTitle": "Internal error",
"loginOauthFailSubtitle": "Failed to get OAuth URL",
"loginOauthSuccessTitle": "Redirecting",
"loginOauthSuccessSubtitle": "Redirecting to your OAuth provider",
"continueRedirectingTitle": "Redirecting...",
"continueRedirectingSubtitle": "You should be redirected to the app soon",
"continueInvalidRedirectTitle": "Invalid redirect",
"continueInvalidRedirectSubtitle": "The redirect URL is invalid",
"continueInsecureRedirectTitle": "Insecure redirect",
"continueInsecureRedirectSubtitle": "You are trying to redirect from <Code>https</Code> to <Code>http</Code>, are you sure you want to continue?",
"continueTitle": "Continue",
"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",
"logoutFailSubtitle": "Please try again",
"logoutSuccessTitle": "Logged out",
"logoutSuccessSubtitle": "You have been logged out",
"logoutTitle": "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.",
"notFoundTitle": "Page not found",
"notFoundSubtitle": "The page you are looking for does not exist.",
"notFoundButton": "Go home",
"totpFailTitle": "Failed to verify code",
"totpFailSubtitle": "Please check your code and try again",
"totpSuccessTitle": "Verified",
"totpSuccessSubtitle": "Redirecting to your app",
"totpTitle": "Enter your TOTP code",
"unauthorizedTitle": "Unauthorized",
"unauthorizedResourceSubtitle": "The user with username {{username}} is not authorized to access the resource <Code>{{resource}}</Code>.",
"unaothorizedLoginSubtitle": "The user with username {{username}} is not authorized to login.",
"unauthorizedButton": "Try again"
}

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"io/fs" "io/fs"
"net/http" "net/http"
"os"
"strings" "strings"
"time" "time"
"tinyauth/internal/assets" "tinyauth/internal/assets"
@@ -70,18 +69,7 @@ func (api *API) Init() {
router.Use(func(c *gin.Context) { router.Use(func(c *gin.Context) {
// If not an API request, serve the UI // If not an API request, serve the UI
if !strings.HasPrefix(c.Request.URL.Path, "/api") { if !strings.HasPrefix(c.Request.URL.Path, "/api") {
// Check if the file exists
_, err := fs.Stat(dist, strings.TrimPrefix(c.Request.URL.Path, "/"))
// If the file doesn't exist, serve the index.html
if os.IsNotExist(err) {
c.Request.URL.Path = "/"
}
// Serve the file
fileServer.ServeHTTP(c.Writer, c.Request) fileServer.ServeHTTP(c.Writer, c.Request)
// Stop further processing
c.Abort() c.Abort()
} }
}) })

View File

@@ -53,11 +53,11 @@ func getAPI(t *testing.T) *api.API {
docker := docker.NewDocker() docker := docker.NewDocker()
// Initialize docker // Initialize docker
err := docker.Init() dockerErr := docker.Init()
// Check if there was an error // Check if there was an error
if err != nil { if dockerErr != nil {
t.Fatalf("Failed to initialize docker: %v", err) t.Fatalf("Failed to initialize docker: %v", dockerErr)
} }
// Create auth service // Create auth service
@@ -78,7 +78,7 @@ func getAPI(t *testing.T) *api.API {
hooks := hooks.NewHooks(auth, providers) hooks := hooks.NewHooks(auth, providers)
// Create handlers service // Create handlers service
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker) handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers)
// Create API // Create API
api := api.NewAPI(apiConfig, handlers) api := api.NewAPI(apiConfig, handlers)
@@ -167,21 +167,21 @@ func TestAppContext(t *testing.T) {
assert.Equal(t, recorder.Code, http.StatusOK) assert.Equal(t, recorder.Code, http.StatusOK)
// Read the body of the response // Read the body of the response
body, err := io.ReadAll(recorder.Body) body, bodyErr := io.ReadAll(recorder.Body)
// Check if there was an error // Check if there was an error
if err != nil { if bodyErr != nil {
t.Fatalf("Error getting body: %v", err) t.Fatalf("Error getting body: %v", bodyErr)
} }
// Unmarshal the body into the user struct // Unmarshal the body into the user struct
var app types.AppContext var app types.AppContext
err = json.Unmarshal(body, &app) jsonErr := json.Unmarshal(body, &app)
// Check if there was an error // Check if there was an error
if err != nil { if jsonErr != nil {
t.Fatalf("Error unmarshalling body: %v", err) t.Fatalf("Error unmarshalling body: %v", jsonErr)
} }
// Create tests values // Create tests values
@@ -231,11 +231,11 @@ func TestUserContext(t *testing.T) {
assert.Equal(t, recorder.Code, http.StatusOK) assert.Equal(t, recorder.Code, http.StatusOK)
// Read the body of the response // Read the body of the response
body, err := io.ReadAll(recorder.Body) body, bodyErr := io.ReadAll(recorder.Body)
// Check if there was an error // Check if there was an error
if err != nil { if bodyErr != nil {
t.Fatalf("Error getting body: %v", err) t.Fatalf("Error getting body: %v", bodyErr)
} }
// Unmarshal the body into the user struct // Unmarshal the body into the user struct
@@ -245,11 +245,11 @@ func TestUserContext(t *testing.T) {
var user User var user User
err = json.Unmarshal(body, &user) jsonErr := json.Unmarshal(body, &user)
// Check if there was an error // Check if there was an error
if err != nil { if jsonErr != nil {
t.Fatalf("Error unmarshalling body: %v", err) t.Fatalf("Error unmarshalling body: %v", jsonErr)
} }
// We should get the username back // We should get the username back

View File

@@ -1 +1 @@
v3.2.0 v3.1.0

View File

@@ -159,15 +159,9 @@ func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext) (bo
// Get app id // Get app id
appId := strings.Split(host, ".")[0] appId := strings.Split(host, ".")[0]
// Get the container labels // Check if resource is allowed
labels, err := auth.Docker.GetLabels(appId) allowed, allowedErr := auth.Docker.ContainerAction(appId, func(labels types.TinyauthLabels) (bool, error) {
// If the container has an oauth whitelist, check if the user is in it
// If there is an error, return false
if err != nil {
return false, err
}
// Check if oauth is allowed
if context.OAuth { if context.OAuth {
if len(labels.OAuthWhitelist) == 0 { if len(labels.OAuthWhitelist) == 0 {
return true, nil return true, nil
@@ -176,18 +170,30 @@ func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext) (bo
if slices.Contains(labels.OAuthWhitelist, context.Username) { if slices.Contains(labels.OAuthWhitelist, context.Username) {
return true, nil return true, nil
} }
return false, nil
} }
// Check if user is allowed // If the container has users, check if the user is in it
if len(labels.Users) != 0 { if len(labels.Users) != 0 {
log.Debug().Msg("Checking users") log.Debug().Msg("Checking users")
if slices.Contains(labels.Users, context.Username) { if slices.Contains(labels.Users, context.Username) {
return true, nil return true, nil
} }
return false, nil
} }
// Not allowed // Allowed
return false, nil return true, nil
})
// If there is an error, return false
if allowedErr != nil {
log.Error().Err(allowedErr).Msg("Error checking if resource is allowed")
return false, allowedErr
}
// Return if the resource is allowed
return allowed, nil
} }
func (auth *Auth) AuthEnabled(c *gin.Context) (bool, error) { func (auth *Auth) AuthEnabled(c *gin.Context) (bool, error) {
@@ -198,14 +204,8 @@ func (auth *Auth) AuthEnabled(c *gin.Context) (bool, error) {
// Get app id // Get app id
appId := strings.Split(host, ".")[0] appId := strings.Split(host, ".")[0]
// Get the container labels // Check if auth is enabled
labels, err := auth.Docker.GetLabels(appId) enabled, enabledErr := auth.Docker.ContainerAction(appId, func(labels types.TinyauthLabels) (bool, error) {
// If there is an error, auth enabled
if err != nil {
return true, err
}
// Check if the allowed label is empty // Check if the allowed label is empty
if labels.Allowed == "" { if labels.Allowed == "" {
// Auth enabled // Auth enabled
@@ -213,12 +213,12 @@ func (auth *Auth) AuthEnabled(c *gin.Context) (bool, error) {
} }
// Compile regex // Compile regex
regex, err := regexp.Compile(labels.Allowed) regex, regexErr := regexp.Compile(labels.Allowed)
// If there is an error, invalid regex, auth enabled // If there is an error, invalid regex, auth enabled
if err != nil { if regexErr != nil {
log.Warn().Err(err).Msg("Invalid regex") log.Warn().Err(regexErr).Msg("Invalid regex")
return true, err return true, regexErr
} }
// Check if the uri matches the regex // Check if the uri matches the regex
@@ -229,6 +229,15 @@ func (auth *Auth) AuthEnabled(c *gin.Context) (bool, error) {
// Auth enabled // Auth enabled
return true, nil return true, nil
})
// If there is an error, auth enabled
if enabledErr != nil {
log.Error().Err(enabledErr).Msg("Error checking if auth is enabled")
return true, enabledErr
}
return enabled, nil
} }
func (auth *Auth) GetBasicAuth(c *gin.Context) *types.User { func (auth *Auth) GetBasicAuth(c *gin.Context) *types.User {

View File

@@ -5,5 +5,4 @@ var TinyauthLabels = []string{
"tinyauth.oauth.whitelist", "tinyauth.oauth.whitelist",
"tinyauth.users", "tinyauth.users",
"tinyauth.allowed", "tinyauth.allowed",
"tinyauth.headers",
} }

View File

@@ -3,7 +3,7 @@ package docker
import ( import (
"context" "context"
"strings" "strings"
"tinyauth/internal/types" appTypes "tinyauth/internal/types"
"tinyauth/internal/utils" "tinyauth/internal/utils"
apiTypes "github.com/docker/docker/api/types" apiTypes "github.com/docker/docker/api/types"
@@ -23,7 +23,7 @@ type Docker struct {
func (docker *Docker) Init() error { func (docker *Docker) Init() error {
// Create a new docker client // Create a new docker client
client, err := client.NewClientWithOpts(client.FromEnv) apiClient, err := client.NewClientWithOpts(client.FromEnv)
// Check if there was an error // Check if there was an error
if err != nil { if err != nil {
@@ -32,7 +32,7 @@ func (docker *Docker) Init() error {
// Set the context and api client // Set the context and api client
docker.Context = context.Background() docker.Context = context.Background()
docker.Client = client docker.Client = apiClient
// Done // Done
return nil return nil
@@ -70,22 +70,22 @@ func (docker *Docker) DockerConnected() bool {
return err == nil return err == nil
} }
func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) { func (docker *Docker) ContainerAction(appId string, runCheck func(labels appTypes.TinyauthLabels) (bool, error)) (bool, error) {
// Check if we have access to the Docker API // Check if we have access to the Docker API
isConnected := docker.DockerConnected() isConnected := docker.DockerConnected()
// If we don't have access, return an empty struct // If we don't have access, it is assumed that the check passed
if !isConnected { if !isConnected {
log.Debug().Msg("Docker not connected, returning empty labels") log.Debug().Msg("Docker not connected, passing check")
return types.TinyauthLabels{}, nil return true, nil
} }
// Get the containers // Get the containers
containers, err := docker.GetContainers() containers, containersErr := docker.GetContainers()
// If there is an error, return false // If there is an error, return false
if err != nil { if containersErr != nil {
return types.TinyauthLabels{}, err return false, containersErr
} }
log.Debug().Msg("Got containers") log.Debug().Msg("Got containers")
@@ -93,15 +93,15 @@ func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) {
// Loop through the containers // Loop through the containers
for _, container := range containers { for _, container := range containers {
// Inspect the container // Inspect the container
inspect, err := docker.InspectContainer(container.ID) inspect, inspectErr := docker.InspectContainer(container.ID)
// If there is an error, return false // If there is an error, return false
if err != nil { if inspectErr != nil {
return types.TinyauthLabels{}, err return false, inspectErr
} }
// Get the container name (for some reason it is /name) // Get the container name (for some reason it is /name)
containerName := strings.TrimPrefix(inspect.Name, "/") containerName := strings.Split(inspect.Name, "/")[1]
// There is a container with the same name as the app ID // There is a container with the same name as the app ID
if containerName == appId { if containerName == appId {
@@ -112,14 +112,14 @@ func (docker *Docker) GetLabels(appId string) (types.TinyauthLabels, error) {
log.Debug().Msg("Got labels") log.Debug().Msg("Got labels")
// Return labels // Run the check
return labels, nil return runCheck(labels)
} }
} }
log.Debug().Msg("No matching container found, returning empty labels") log.Debug().Msg("No matching container found, passing check")
// If no matching container is found, return empty labels // If no matching container is found, pass check
return types.TinyauthLabels{}, nil return true, nil
} }

View File

@@ -6,7 +6,6 @@ import (
"net/http" "net/http"
"strings" "strings"
"tinyauth/internal/auth" "tinyauth/internal/auth"
"tinyauth/internal/docker"
"tinyauth/internal/hooks" "tinyauth/internal/hooks"
"tinyauth/internal/providers" "tinyauth/internal/providers"
"tinyauth/internal/types" "tinyauth/internal/types"
@@ -17,13 +16,12 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
func NewHandlers(config types.HandlersConfig, auth *auth.Auth, hooks *hooks.Hooks, providers *providers.Providers, docker *docker.Docker) *Handlers { func NewHandlers(config types.HandlersConfig, auth *auth.Auth, hooks *hooks.Hooks, providers *providers.Providers) *Handlers {
return &Handlers{ return &Handlers{
Config: config, Config: config,
Auth: auth, Auth: auth,
Hooks: hooks, Hooks: hooks,
Providers: providers, Providers: providers,
Docker: docker,
} }
} }
@@ -32,7 +30,6 @@ type Handlers struct {
Auth *auth.Auth Auth *auth.Auth
Hooks *hooks.Hooks Hooks *hooks.Hooks
Providers *providers.Providers Providers *providers.Providers
Docker *docker.Docker
} }
func (h *Handlers) AuthHandler(c *gin.Context) { func (h *Handlers) AuthHandler(c *gin.Context) {
@@ -63,39 +60,12 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
log.Debug().Interface("proxy", proxy.Proxy).Msg("Got proxy") log.Debug().Interface("proxy", proxy.Proxy).Msg("Got proxy")
// Get headers
uri := c.Request.Header.Get("X-Forwarded-Uri")
proto := c.Request.Header.Get("X-Forwarded-Proto")
host := c.Request.Header.Get("X-Forwarded-Host")
// Check if auth is enabled // Check if auth is enabled
authEnabled, err := h.Auth.AuthEnabled(c) authEnabled, err := h.Auth.AuthEnabled(c)
// Check if there was an error // Handle error
if err != nil { if err != nil {
log.Error().Err(err).Msg("Failed to check if app is allowed") log.Error().Err(err).Msg("Failed to check if auth is enabled")
if proxy.Proxy == "nginx" || !isBrowser {
c.JSON(500, gin.H{
"status": 500,
"message": "Internal Server Error",
})
return
}
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL))
return
}
// Get the app id
appId := strings.Split(host, ".")[0]
// Get the container labels
labels, err := h.Docker.GetLabels(appId)
// Check if there was an error
if err != nil {
log.Error().Err(err).Msg("Failed to check if app is allowed")
if proxy.Proxy == "nginx" || !isBrowser { if proxy.Proxy == "nginx" || !isBrowser {
c.JSON(500, gin.H{ c.JSON(500, gin.H{
@@ -111,10 +81,6 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
// If auth is not enabled, return 200 // If auth is not enabled, return 200
if !authEnabled { if !authEnabled {
for key, value := range labels.Headers {
log.Debug().Str("key", key).Str("value", value).Msg("Setting header")
c.Header(key, value)
}
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"status": 200, "status": 200,
"message": "Authenticated", "message": "Authenticated",
@@ -125,6 +91,11 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
// Get user context // Get user context
userContext := h.Hooks.UseUserContext(c) userContext := h.Hooks.UseUserContext(c)
// Get headers
uri := c.Request.Header.Get("X-Forwarded-Uri")
proto := c.Request.Header.Get("X-Forwarded-Proto")
host := c.Request.Header.Get("X-Forwarded-Host")
// Check if user is logged in // Check if user is logged in
if userContext.IsLoggedIn { if userContext.IsLoggedIn {
log.Debug().Msg("Authenticated") log.Debug().Msg("Authenticated")
@@ -173,7 +144,7 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
// Handle error (no need to check for nginx/headers since we are sure we are using caddy/traefik) // Handle error (no need to check for nginx/headers since we are sure we are using caddy/traefik)
if err != nil { if err != nil {
log.Error().Err(err).Msg("Failed to build queries") log.Error().Err(err).Msg("Failed to build query")
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL)) c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL))
return return
} }
@@ -186,12 +157,6 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
// Set the user header // Set the user header
c.Header("Remote-User", userContext.Username) c.Header("Remote-User", userContext.Username)
// Set the rest of the headers
for key, value := range labels.Headers {
log.Debug().Str("key", key).Str("value", value).Msg("Setting header")
c.Header(key, value)
}
// The user is allowed to access the app // The user is allowed to access the app
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"status": 200, "status": 200,
@@ -219,7 +184,7 @@ func (h *Handlers) AuthHandler(c *gin.Context) {
}) })
if err != nil { if err != nil {
log.Error().Err(err).Msg("Failed to build queries") log.Error().Err(err).Msg("Failed to build query")
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL)) c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL))
return return
} }
@@ -358,10 +323,10 @@ func (h *Handlers) TotpHandler(c *gin.Context) {
} }
// Check if totp is correct // Check if totp is correct
ok := totp.Validate(totpReq.Code, user.TotpSecret) totpOk := totp.Validate(totpReq.Code, user.TotpSecret)
// TOTP is incorrect // TOTP is incorrect
if !ok { if !totpOk {
log.Debug().Msg("Totp incorrect") log.Debug().Msg("Totp incorrect")
c.JSON(401, gin.H{ c.JSON(401, gin.H{
"status": 401, "status": 401,
@@ -508,13 +473,13 @@ func (h *Handlers) OauthUrlHandler(c *gin.Context) {
// Tailscale does not have an auth url so we create a random code (does not need to be secure) to avoid caching and send it // Tailscale does not have an auth url so we create a random code (does not need to be secure) to avoid caching and send it
if request.Provider == "tailscale" { if request.Provider == "tailscale" {
// Build tailscale query // Build tailscale query
queries, err := query.Values(types.TailscaleQuery{ tailscaleQuery, err := query.Values(types.TailscaleQuery{
Code: (1000 + rand.IntN(9000)), Code: (1000 + rand.IntN(9000)),
}) })
// Handle error // Handle error
if err != nil { if err != nil {
log.Error().Err(err).Msg("Failed to build queries") log.Error().Err(err).Msg("Failed to build query")
c.JSON(500, gin.H{ c.JSON(500, gin.H{
"status": 500, "status": 500,
"message": "Internal Server Error", "message": "Internal Server Error",
@@ -526,7 +491,7 @@ func (h *Handlers) OauthUrlHandler(c *gin.Context) {
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"status": 200, "status": 200,
"message": "OK", "message": "OK",
"url": fmt.Sprintf("%s/api/oauth/callback/tailscale?%s", h.Config.AppURL, queries.Encode()), "url": fmt.Sprintf("%s/api/oauth/callback/tailscale?%s", h.Config.AppURL, tailscaleQuery.Encode()),
}) })
return return
} }
@@ -607,19 +572,19 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
log.Warn().Str("email", email).Msg("Email not whitelisted") log.Warn().Str("email", email).Msg("Email not whitelisted")
// Build query // Build query
queries, err := query.Values(types.UnauthorizedQuery{ unauthorizedQuery, err := query.Values(types.UnauthorizedQuery{
Username: email, Username: email,
}) })
// Handle error // Handle error
if err != nil { if err != nil {
log.Error().Msg("Failed to build queries") log.Error().Msg("Failed to build query")
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL)) c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL))
return return
} }
// Redirect to unauthorized // Redirect to unauthorized
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/unauthorized?%s", h.Config.AppURL, queries.Encode())) c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/unauthorized?%s", h.Config.AppURL, unauthorizedQuery.Encode()))
} }
log.Debug().Msg("Email whitelisted") log.Debug().Msg("Email whitelisted")
@@ -631,10 +596,10 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
}) })
// Get redirect URI // Get redirect URI
redirectURI, err := c.Cookie("tinyauth_redirect_uri") redirectURI, redirectURIErr := c.Cookie("tinyauth_redirect_uri")
// If it is empty it means that no redirect_uri was provided to the login screen so we just log in // If it is empty it means that no redirect_uri was provided to the login screen so we just log in
if err != nil { if redirectURIErr != nil {
c.Redirect(http.StatusPermanentRedirect, h.Config.AppURL) c.Redirect(http.StatusPermanentRedirect, h.Config.AppURL)
} }
@@ -644,7 +609,7 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
c.SetCookie("tinyauth_redirect_uri", "", -1, "/", h.Config.Domain, h.Config.CookieSecure, true) c.SetCookie("tinyauth_redirect_uri", "", -1, "/", h.Config.Domain, h.Config.CookieSecure, true)
// Build query // Build query
queries, err := query.Values(types.LoginQuery{ redirectQuery, err := query.Values(types.LoginQuery{
RedirectURI: redirectURI, RedirectURI: redirectURI,
}) })
@@ -652,13 +617,13 @@ func (h *Handlers) OauthCallbackHandler(c *gin.Context) {
// Handle error // Handle error
if err != nil { if err != nil {
log.Error().Msg("Failed to build queries") log.Error().Msg("Failed to build query")
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL)) c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/error", h.Config.AppURL))
return return
} }
// Redirect to continue with the redirect URI // Redirect to continue with the redirect URI
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/continue?%s", h.Config.AppURL, queries.Encode())) c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("%s/continue?%s", h.Config.AppURL, redirectQuery.Encode()))
} }
func (h *Handlers) HealthcheckHandler(c *gin.Context) { func (h *Handlers) HealthcheckHandler(c *gin.Context) {

View File

@@ -15,21 +15,21 @@ type GenericUserInfoResponse struct {
func GetGenericEmail(client *http.Client, url string) (string, error) { func GetGenericEmail(client *http.Client, url string) (string, error) {
// Using the oauth client get the user info url // Using the oauth client get the user info url
res, err := client.Get(url) res, resErr := client.Get(url)
// Check if there was an error // Check if there was an error
if err != nil { if resErr != nil {
return "", err return "", resErr
} }
log.Debug().Msg("Got response from generic provider") log.Debug().Msg("Got response from generic provider")
// Read the body of the response // Read the body of the response
body, err := io.ReadAll(res.Body) body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error // Check if there was an error
if err != nil { if bodyErr != nil {
return "", err return "", bodyErr
} }
log.Debug().Msg("Read body from generic provider") log.Debug().Msg("Read body from generic provider")
@@ -38,11 +38,11 @@ func GetGenericEmail(client *http.Client, url string) (string, error) {
var user GenericUserInfoResponse var user GenericUserInfoResponse
// Unmarshal the body into the user struct // Unmarshal the body into the user struct
err = json.Unmarshal(body, &user) jsonErr := json.Unmarshal(body, &user)
// Check if there was an error // Check if there was an error
if err != nil { if jsonErr != nil {
return "", err return "", jsonErr
} }
log.Debug().Msg("Parsed user from generic provider") log.Debug().Msg("Parsed user from generic provider")

View File

@@ -22,21 +22,21 @@ func GithubScopes() []string {
func GetGithubEmail(client *http.Client) (string, error) { func GetGithubEmail(client *http.Client) (string, error) {
// Get the user emails from github using the oauth http client // Get the user emails from github using the oauth http client
res, err := client.Get("https://api.github.com/user/emails") res, resErr := client.Get("https://api.github.com/user/emails")
// Check if there was an error // Check if there was an error
if err != nil { if resErr != nil {
return "", err return "", resErr
} }
log.Debug().Msg("Got response from github") log.Debug().Msg("Got response from github")
// Read the body of the response // Read the body of the response
body, err := io.ReadAll(res.Body) body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error // Check if there was an error
if err != nil { if bodyErr != nil {
return "", err return "", bodyErr
} }
log.Debug().Msg("Read body from github") log.Debug().Msg("Read body from github")
@@ -45,11 +45,11 @@ func GetGithubEmail(client *http.Client) (string, error) {
var emails GithubUserInfoResponse var emails GithubUserInfoResponse
// Unmarshal the body into the user struct // Unmarshal the body into the user struct
err = json.Unmarshal(body, &emails) jsonErr := json.Unmarshal(body, &emails)
// Check if there was an error // Check if there was an error
if err != nil { if jsonErr != nil {
return "", err return "", jsonErr
} }
log.Debug().Msg("Parsed emails from github") log.Debug().Msg("Parsed emails from github")

View File

@@ -20,21 +20,21 @@ func GoogleScopes() []string {
func GetGoogleEmail(client *http.Client) (string, error) { func GetGoogleEmail(client *http.Client) (string, error) {
// Get the user info from google using the oauth http client // Get the user info from google using the oauth http client
res, err := client.Get("https://www.googleapis.com/userinfo/v2/me") res, resErr := client.Get("https://www.googleapis.com/userinfo/v2/me")
// Check if there was an error // Check if there was an error
if err != nil { if resErr != nil {
return "", err return "", resErr
} }
log.Debug().Msg("Got response from google") log.Debug().Msg("Got response from google")
// Read the body of the response // Read the body of the response
body, err := io.ReadAll(res.Body) body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error // Check if there was an error
if err != nil { if bodyErr != nil {
return "", err return "", bodyErr
} }
log.Debug().Msg("Read body from google") log.Debug().Msg("Read body from google")
@@ -43,11 +43,11 @@ func GetGoogleEmail(client *http.Client) (string, error) {
var user GoogleUserInfoResponse var user GoogleUserInfoResponse
// Unmarshal the body into the user struct // Unmarshal the body into the user struct
err = json.Unmarshal(body, &user) jsonErr := json.Unmarshal(body, &user)
// Check if there was an error // Check if there was an error
if err != nil { if jsonErr != nil {
return "", err return "", jsonErr
} }
log.Debug().Msg("Parsed user from google") log.Debug().Msg("Parsed user from google")

View File

@@ -128,11 +128,11 @@ func (providers *Providers) GetUser(provider string) (string, error) {
log.Debug().Msg("Got client from github") log.Debug().Msg("Got client from github")
// Get the email from the github provider // Get the email from the github provider
email, err := GetGithubEmail(client) email, emailErr := GetGithubEmail(client)
// Check if there was an error // Check if there was an error
if err != nil { if emailErr != nil {
return "", err return "", emailErr
} }
log.Debug().Msg("Got email from github") log.Debug().Msg("Got email from github")
@@ -152,11 +152,11 @@ func (providers *Providers) GetUser(provider string) (string, error) {
log.Debug().Msg("Got client from google") log.Debug().Msg("Got client from google")
// Get the email from the google provider // Get the email from the google provider
email, err := GetGoogleEmail(client) email, emailErr := GetGoogleEmail(client)
// Check if there was an error // Check if there was an error
if err != nil { if emailErr != nil {
return "", err return "", emailErr
} }
log.Debug().Msg("Got email from google") log.Debug().Msg("Got email from google")
@@ -176,11 +176,11 @@ func (providers *Providers) GetUser(provider string) (string, error) {
log.Debug().Msg("Got client from tailscale") log.Debug().Msg("Got client from tailscale")
// Get the email from the tailscale provider // Get the email from the tailscale provider
email, err := GetTailscaleEmail(client) email, emailErr := GetTailscaleEmail(client)
// Check if there was an error // Check if there was an error
if err != nil { if emailErr != nil {
return "", err return "", emailErr
} }
log.Debug().Msg("Got email from tailscale") log.Debug().Msg("Got email from tailscale")
@@ -200,11 +200,11 @@ func (providers *Providers) GetUser(provider string) (string, error) {
log.Debug().Msg("Got client from generic") log.Debug().Msg("Got client from generic")
// Get the email from the generic provider // Get the email from the generic provider
email, err := GetGenericEmail(client, providers.Config.GenericUserURL) email, emailErr := GetGenericEmail(client, providers.Config.GenericUserURL)
// Check if there was an error // Check if there was an error
if err != nil { if emailErr != nil {
return "", err return "", emailErr
} }
log.Debug().Msg("Got email from generic") log.Debug().Msg("Got email from generic")

View File

@@ -31,21 +31,21 @@ var TailscaleEndpoint = oauth2.Endpoint{
func GetTailscaleEmail(client *http.Client) (string, error) { func GetTailscaleEmail(client *http.Client) (string, error) {
// Get the user info from tailscale using the oauth http client // Get the user info from tailscale using the oauth http client
res, err := client.Get("https://api.tailscale.com/api/v2/tailnet/-/users") res, resErr := client.Get("https://api.tailscale.com/api/v2/tailnet/-/users")
// Check if there was an error // Check if there was an error
if err != nil { if resErr != nil {
return "", err return "", resErr
} }
log.Debug().Msg("Got response from tailscale") log.Debug().Msg("Got response from tailscale")
// Read the body of the response // Read the body of the response
body, err := io.ReadAll(res.Body) body, bodyErr := io.ReadAll(res.Body)
// Check if there was an error // Check if there was an error
if err != nil { if bodyErr != nil {
return "", err return "", bodyErr
} }
log.Debug().Msg("Read body from tailscale") log.Debug().Msg("Read body from tailscale")
@@ -54,11 +54,11 @@ func GetTailscaleEmail(client *http.Client) (string, error) {
var users TailscaleUserInfoResponse var users TailscaleUserInfoResponse
// Unmarshal the body into the user struct // Unmarshal the body into the user struct
err = json.Unmarshal(body, &users) jsonErr := json.Unmarshal(body, &users)
// Check if there was an error // Check if there was an error
if err != nil { if jsonErr != nil {
return "", err return "", jsonErr
} }
log.Debug().Msg("Parsed users from tailscale") log.Debug().Msg("Parsed users from tailscale")

View File

@@ -124,7 +124,6 @@ type TinyauthLabels struct {
OAuthWhitelist []string OAuthWhitelist []string
Users []string Users []string
Allowed string Allowed string
Headers map[string]string
} }
// TailscaleQuery is the query parameters for the tailscale endpoint // TailscaleQuery is the query parameters for the tailscale endpoint

View File

@@ -29,11 +29,11 @@ func ParseUsers(users string) (types.Users, error) {
// Loop through the users and split them by colon // Loop through the users and split them by colon
for _, user := range userList { for _, user := range userList {
parsed, err := ParseUser(user) parsed, parseErr := ParseUser(user)
// Check if there was an error // Check if there was an error
if err != nil { if parseErr != nil {
return types.Users{}, err return types.Users{}, parseErr
} }
// Append the user to the users struct // Append the user to the users struct
@@ -69,19 +69,19 @@ func GetUpperDomain(urlSrc string) (string, error) {
// Reads a file and returns the contents // Reads a file and returns the contents
func ReadFile(file string) (string, error) { func ReadFile(file string) (string, error) {
// Check if the file exists // Check if the file exists
_, err := os.Stat(file) _, statErr := os.Stat(file)
// Check if there was an error // Check if there was an error
if err != nil { if statErr != nil {
return "", err return "", statErr
} }
// Read the file // Read the file
data, err := os.ReadFile(file) data, readErr := os.ReadFile(file)
// Check if there was an error // Check if there was an error
if err != nil { if readErr != nil {
return "", err return "", readErr
} }
// Return the file contents // Return the file contents
@@ -152,10 +152,10 @@ func GetUsers(conf string, file string) (types.Users, error) {
// If the file is set, read the file and append the users to the users string // If the file is set, read the file and append the users to the users string
if file != "" { if file != "" {
// Read the file // Read the file
contents, err := ReadFile(file) fileContents, fileErr := ReadFile(file)
// If there isn't an error we can append the users to the users string // If there isn't an error we can append the users to the users string
if err == nil { if fileErr == nil {
log.Debug().Msg("Using users from file") log.Debug().Msg("Using users from file")
// Append the users to the users string // Append the users to the users string
@@ -164,7 +164,7 @@ func GetUsers(conf string, file string) (types.Users, error) {
} }
// Parse the file contents into a comma separated list of users // Parse the file contents into a comma separated list of users
users += ParseFileToLine(contents) users += ParseFileToLine(fileContents)
} }
} }
@@ -193,16 +193,6 @@ func GetTinyauthLabels(labels map[string]string) types.TinyauthLabels {
tinyauthLabels.Users = strings.Split(value, ",") tinyauthLabels.Users = strings.Split(value, ",")
case "tinyauth.allowed": case "tinyauth.allowed":
tinyauthLabels.Allowed = value tinyauthLabels.Allowed = value
case "tinyauth.headers":
tinyauthLabels.Headers = make(map[string]string)
headers := strings.Split(value, ",")
for _, header := range headers {
headerSplit := strings.Split(header, "=")
if len(headerSplit) != 2 {
continue
}
tinyauthLabels.Headers[headerSplit[0]] = headerSplit[1]
}
} }
} }
} }

View File

@@ -102,7 +102,7 @@ func TestParseFileToLine(t *testing.T) {
t.Log("Testing parse file to line with a valid string") t.Log("Testing parse file to line with a valid string")
// Test the parse file to line function with a valid string // Test the parse file to line function with a valid string
content := "\nuser1:pass1\nuser2:pass2\n" content := "user1:pass1\nuser2:pass2"
expected := "user1:pass1,user2:pass2" expected := "user1:pass1,user2:pass2"
result := utils.ParseFileToLine(content) result := utils.ParseFileToLine(content)

23
site/Dockerfile.dev Normal file
View File

@@ -0,0 +1,23 @@
FROM oven/bun:1.1.45-alpine
WORKDIR /site
COPY ./site/package.json ./
COPY ./site/bun.lockb ./
RUN bun install
COPY ./site/public ./public
COPY ./site/src ./src
COPY ./site/eslint.config.js ./
COPY ./site/index.html ./
COPY ./site/tsconfig.json ./
COPY ./site/tsconfig.app.json ./
COPY ./site/tsconfig.node.json ./
COPY ./site/vite.config.ts ./
COPY ./site/postcss.config.cjs ./
EXPOSE 5173
ENTRYPOINT ["bun", "run", "dev"]

BIN
site/bun.lockb Executable file

Binary file not shown.

View File

@@ -6,7 +6,7 @@
<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" /> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" /> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/frontend.webmanifest" /> <link rel="manifest" href="/site.webmanifest" />
<title>Tinyauth</title> <title>Tinyauth</title>
</head> </head>
<body> <body>

View File

@@ -1,11 +1,11 @@
{ {
"name": "frontend", "name": "site",
"version": "0.0.0", "version": "0.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "frontend", "name": "site",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@mantine/core": "^7.16.0", "@mantine/core": "^7.16.0",

View File

@@ -1,5 +1,5 @@
{ {
"name": "frontend", "name": "site",
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
@@ -16,14 +16,8 @@
"@mantine/notifications": "^7.16.0", "@mantine/notifications": "^7.16.0",
"@tanstack/react-query": "4", "@tanstack/react-query": "4",
"axios": "^1.7.9", "axios": "^1.7.9",
"i18next": "^24.2.3",
"i18next-browser-languagedetector": "^8.0.4",
"i18next-chained-backend": "^4.6.2",
"i18next-http-backend": "^3.0.2",
"i18next-resources-to-backend": "^1.2.1",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-i18next": "^15.4.1",
"react-router": "^7.1.3", "react-router": "^7.1.3",
"zod": "^3.24.1" "zod": "^3.24.1"
}, },

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 602 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -1,7 +1,6 @@
import { TextInput, PasswordInput, Button } from "@mantine/core"; import { TextInput, PasswordInput, Button } from "@mantine/core";
import { useForm, zodResolver } from "@mantine/form"; import { useForm, zodResolver } from "@mantine/form";
import { LoginFormValues, loginSchema } from "../../schemas/login-schema"; import { LoginFormValues, loginSchema } from "../../schemas/login-schema";
import { useTranslation } from "react-i18next";
interface LoginFormProps { interface LoginFormProps {
isLoading: boolean; isLoading: boolean;
@@ -10,7 +9,6 @@ interface LoginFormProps {
export const LoginForm = (props: LoginFormProps) => { export const LoginForm = (props: LoginFormProps) => {
const { isLoading, onSubmit } = props; const { isLoading, onSubmit } = props;
const { t } = useTranslation();
const form = useForm({ const form = useForm({
mode: "uncontrolled", mode: "uncontrolled",
@@ -24,7 +22,7 @@ export const LoginForm = (props: LoginFormProps) => {
return ( return (
<form onSubmit={form.onSubmit(onSubmit)}> <form onSubmit={form.onSubmit(onSubmit)}>
<TextInput <TextInput
label={t("loginUsername")} label="Username"
placeholder="user@example.com" placeholder="user@example.com"
required required
disabled={isLoading} disabled={isLoading}
@@ -32,7 +30,7 @@ export const LoginForm = (props: LoginFormProps) => {
{...form.getInputProps("username")} {...form.getInputProps("username")}
/> />
<PasswordInput <PasswordInput
label={t("loginPassword")} label="Password"
placeholder="password" placeholder="password"
required required
mt="md" mt="md"
@@ -41,7 +39,7 @@ export const LoginForm = (props: LoginFormProps) => {
{...form.getInputProps("password")} {...form.getInputProps("password")}
/> />
<Button fullWidth mt="xl" type="submit" loading={isLoading}> <Button fullWidth mt="xl" type="submit" loading={isLoading}>
{t("loginSubmit")} Login
</Button> </Button>
</form> </form>
); );

View File

@@ -0,0 +1,12 @@
import { Center, Flex } from "@mantine/core";
import { ReactNode } from "react";
export const Layout = ({ children }: { children: ReactNode }) => {
return (
<Center style={{ minHeight: "100vh" }}>
<Flex direction="column" flex="1" maw={350}>
{children}
</Flex>
</Center>
);
};

View File

@@ -17,7 +17,6 @@ import { UnauthorizedPage } from "./pages/unauthorized-page.tsx";
import { InternalServerError } from "./pages/internal-server-error.tsx"; import { InternalServerError } from "./pages/internal-server-error.tsx";
import { TotpPage } from "./pages/totp-page.tsx"; import { TotpPage } from "./pages/totp-page.tsx";
import { AppContextProvider } from "./context/app-context.tsx"; import { AppContextProvider } from "./context/app-context.tsx";
import "./lib/i18n/i18n.ts";
const queryClient = new QueryClient({ const queryClient = new QueryClient({
defaultOptions: { defaultOptions: {

View File

@@ -6,7 +6,6 @@ import { Layout } from "../components/layouts/layout";
import { ReactNode } from "react"; import { ReactNode } from "react";
import { isQueryValid } from "../utils/utils"; import { isQueryValid } from "../utils/utils";
import { useAppContext } from "../context/app-context"; import { useAppContext } from "../context/app-context";
import { Trans, useTranslation } from "react-i18next";
export const ContinuePage = () => { export const ContinuePage = () => {
const queryString = window.location.search; const queryString = window.location.search;
@@ -15,7 +14,6 @@ export const ContinuePage = () => {
const { isLoggedIn } = useUserContext(); const { isLoggedIn } = useUserContext();
const { disableContinue } = useAppContext(); const { disableContinue } = useAppContext();
const { t } = useTranslation();
if (!isLoggedIn) { if (!isLoggedIn) {
return <Navigate to={`/login?redirect_uri=${redirectUri}`} />; return <Navigate to={`/login?redirect_uri=${redirectUri}`} />;
@@ -27,8 +25,8 @@ export const ContinuePage = () => {
const redirect = () => { const redirect = () => {
notifications.show({ notifications.show({
title: t("continueRedirectingTitle"), title: "Redirecting",
message: t("continueRedirectingSubtitle"), message: "You should be redirected to the app soon",
color: "blue", color: "blue",
}); });
setTimeout(() => { setTimeout(() => {
@@ -44,9 +42,12 @@ export const ContinuePage = () => {
return ( return (
<ContinuePageLayout> <ContinuePageLayout>
<Text size="xl" fw={700}> <Text size="xl" fw={700}>
{t("Invalid redirect")} Invalid Redirect
</Text>
<Text>
The redirect URL is invalid, please contact the app owner to fix the
issue.
</Text> </Text>
<Text>{t("The redirect URL is invalid")}</Text>
</ContinuePageLayout> </ContinuePageLayout>
); );
} }
@@ -56,9 +57,9 @@ export const ContinuePage = () => {
return ( return (
<ContinuePageLayout> <ContinuePageLayout>
<Text size="xl" fw={700}> <Text size="xl" fw={700}>
{t("continueRedirectingTitle")} Redirecting
</Text> </Text>
<Text>{t("continueRedirectingSubtitle")}</Text> <Text>You should be redirected to your app soon.</Text>
</ContinuePageLayout> </ContinuePageLayout>
); );
} }
@@ -67,17 +68,14 @@ export const ContinuePage = () => {
return ( return (
<ContinuePageLayout> <ContinuePageLayout>
<Text size="xl" fw={700}> <Text size="xl" fw={700}>
{t("continueInsecureRedirectTitle")} Insecure Redirect
</Text> </Text>
<Text> <Text>
<Trans Your are trying to redirect from <Code>https</Code> to{" "}
i18nKey="continueInsecureRedirectSubtitle" <Code>http</Code>, are you sure you want to continue?
t={t}
components={{ Code: <Code /> }}
/>
</Text> </Text>
<Button fullWidth mt="xl" color="yellow" onClick={redirect}> <Button fullWidth mt="xl" color="yellow" onClick={redirect}>
{t("continueTitle")} Continue
</Button> </Button>
</ContinuePageLayout> </ContinuePageLayout>
); );
@@ -86,11 +84,11 @@ export const ContinuePage = () => {
return ( return (
<ContinuePageLayout> <ContinuePageLayout>
<Text size="xl" fw={700}> <Text size="xl" fw={700}>
{t("continueTitle")} Continue
</Text> </Text>
<Text>{t("continueSubtitle")}</Text> <Text>Click the button to continue to your app.</Text>
<Button fullWidth mt="xl" onClick={redirect}> <Button fullWidth mt="xl" onClick={redirect}>
{t("continueTitle")} Continue
</Button> </Button>
</ContinuePageLayout> </ContinuePageLayout>
); );

View File

@@ -1,18 +1,19 @@
import { Button, Paper, Text } from "@mantine/core"; import { Button, Paper, Text } from "@mantine/core";
import { Layout } from "../components/layouts/layout"; import { Layout } from "../components/layouts/layout";
import { useTranslation } from "react-i18next";
export const InternalServerError = () => { export const InternalServerError = () => {
const { t } = useTranslation();
return ( return (
<Layout> <Layout>
<Paper shadow="md" p={30} mt={30} radius="md" withBorder> <Paper shadow="md" p={30} mt={30} radius="md" withBorder>
<Text size="xl" fw={700}> <Text size="xl" fw={700}>
{t("internalErrorTitle")} Internal Server Error
</Text>
<Text>
An error occured on the server and it currently cannot serve your
request.
</Text> </Text>
<Text>{t("internalErrorSubtitle")}</Text>
<Button fullWidth mt="xl" onClick={() => window.location.replace("/")}> <Button fullWidth mt="xl" onClick={() => window.location.replace("/")}>
{t("internalErrorButton")} Try again
</Button> </Button>
</Paper> </Paper>
</Layout> </Layout>

View File

@@ -10,7 +10,6 @@ import { LoginFormValues } from "../schemas/login-schema";
import { LoginForm } from "../components/auth/login-forn"; import { LoginForm } from "../components/auth/login-forn";
import { isQueryValid } from "../utils/utils"; import { isQueryValid } from "../utils/utils";
import { useAppContext } from "../context/app-context"; import { useAppContext } from "../context/app-context";
import { useTranslation } from "react-i18next";
export const LoginPage = () => { export const LoginPage = () => {
const queryString = window.location.search; const queryString = window.location.search;
@@ -19,7 +18,6 @@ export const LoginPage = () => {
const { isLoggedIn } = useUserContext(); const { isLoggedIn } = useUserContext();
const { configuredProviders, title, genericName } = useAppContext(); const { configuredProviders, title, genericName } = useAppContext();
const { t } = useTranslation();
const oauthProviders = configuredProviders.filter( const oauthProviders = configuredProviders.filter(
(value) => value !== "username", (value) => value !== "username",
@@ -35,8 +33,8 @@ export const LoginPage = () => {
}, },
onError: () => { onError: () => {
notifications.show({ notifications.show({
title: t("loginFailTitle"), title: "Failed to login",
message: t("loginFailSubtitle"), message: "Check your username and password",
color: "red", color: "red",
}); });
}, },
@@ -47,8 +45,8 @@ export const LoginPage = () => {
} }
notifications.show({ notifications.show({
title: t("loginSuccessTitle"), title: "Logged in",
message: t("loginSuccessSubtitle"), message: "Welcome back!",
color: "green", color: "green",
}); });
@@ -71,15 +69,15 @@ export const LoginPage = () => {
}, },
onError: () => { onError: () => {
notifications.show({ notifications.show({
title: t("loginOauthFailTitle"), title: "Internal error",
message: t("loginOauthFailSubtitle"), message: "Failed to get OAuth URL",
color: "red", color: "red",
}); });
}, },
onSuccess: (data) => { onSuccess: (data) => {
notifications.show({ notifications.show({
title: t("loginOauthSuccessTitle"), title: "Redirecting",
message: t("loginOauthSuccessSubtitle"), message: "Redirecting to your OAuth provider",
color: "blue", color: "blue",
}); });
setTimeout(() => { setTimeout(() => {
@@ -99,7 +97,7 @@ export const LoginPage = () => {
{oauthProviders.length > 0 && ( {oauthProviders.length > 0 && (
<> <>
<Text size="lg" fw={500} ta="center"> <Text size="lg" fw={500} ta="center">
{t("loginTitle")} Welcome back, login with
</Text> </Text>
<OAuthButtons <OAuthButtons
oauthProviders={oauthProviders} oauthProviders={oauthProviders}
@@ -109,7 +107,7 @@ export const LoginPage = () => {
/> />
{configuredProviders.includes("username") && ( {configuredProviders.includes("username") && (
<Divider <Divider
label={t("loginDivider")} label="Or continue with password"
labelPosition="center" labelPosition="center"
my="lg" my="lg"
/> />

View File

@@ -7,12 +7,10 @@ import { Navigate } from "react-router";
import { Layout } from "../components/layouts/layout"; import { Layout } from "../components/layouts/layout";
import { capitalize } from "../utils/utils"; import { capitalize } from "../utils/utils";
import { useAppContext } from "../context/app-context"; import { useAppContext } from "../context/app-context";
import { Trans, useTranslation } from "react-i18next";
export const LogoutPage = () => { export const LogoutPage = () => {
const { isLoggedIn, username, oauth, provider } = useUserContext(); const { isLoggedIn, username, oauth, provider } = useUserContext();
const { genericName } = useAppContext(); const { genericName } = useAppContext();
const { t } = useTranslation();
if (!isLoggedIn) { if (!isLoggedIn) {
return <Navigate to="/login" />; return <Navigate to="/login" />;
@@ -24,15 +22,15 @@ export const LogoutPage = () => {
}, },
onError: () => { onError: () => {
notifications.show({ notifications.show({
title: t("logoutFailTitle"), title: "Failed to logout",
message: t("logoutFailSubtitle"), message: "Please try again",
color: "red", color: "red",
}); });
}, },
onSuccess: () => { onSuccess: () => {
notifications.show({ notifications.show({
title: t("logoutSuccessTitle"), title: "Logged out",
message: t("logoutSuccessSubtitle"), message: "Goodbye!",
color: "green", color: "green",
}); });
setTimeout(() => { setTimeout(() => {
@@ -45,30 +43,13 @@ export const LogoutPage = () => {
<Layout> <Layout>
<Paper shadow="md" p={30} mt={30} radius="md" withBorder> <Paper shadow="md" p={30} mt={30} radius="md" withBorder>
<Text size="xl" fw={700}> <Text size="xl" fw={700}>
{t("logoutTitle")} Logout
</Text> </Text>
<Text> <Text>
{oauth ? ( You are currently logged in as <Code>{username}</Code>
<Trans {oauth &&
i18nKey="logoutOauthSubtitle" ` using ${capitalize(provider === "generic" ? genericName : provider)} OAuth`}
t={t} . Click the button below to log out.
components={{ Code: <Code /> }}
values={{
provider:
provider === "generic" ? genericName : capitalize(provider),
username: username,
}}
/>
) : (
<Trans
i18nKey="logoutUsernameSubtitle"
t={t}
components={{ Code: <Code /> }}
values={{
username: username,
}}
/>
)}
</Text> </Text>
<Button <Button
fullWidth fullWidth
@@ -76,7 +57,7 @@ export const LogoutPage = () => {
onClick={() => logoutMutation.mutate()} onClick={() => logoutMutation.mutate()}
loading={logoutMutation.isLoading} loading={logoutMutation.isLoading}
> >
{t("logoutTitle")} Logout
</Button> </Button>
</Paper> </Paper>
</Layout> </Layout>

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