mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-04-18 03:36:09 +00:00
Compare commits
1 Commits
v5.0.7
...
bd05386e68
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd05386e68 |
4
.github/workflows/nightly.yml
vendored
4
.github/workflows/nightly.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
||||
REPO: ${{ github.event.repository.name }}
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v3
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
prerelease: true
|
||||
tag_name: nightly
|
||||
@@ -459,7 +459,7 @@ jobs:
|
||||
merge-multiple: true
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v3
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: binaries/*
|
||||
tag_name: nightly
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -426,6 +426,6 @@ jobs:
|
||||
merge-multiple: true
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v3
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: binaries/*
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="Tinyauth" />
|
||||
<meta name="robots" content="nofollow, noindex" />
|
||||
<meta
|
||||
name="description"
|
||||
content="The tiniest authentication and authorization server you have ever seen."
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<title>Tinyauth</title>
|
||||
</head>
|
||||
|
||||
@@ -21,7 +21,7 @@ export const LanguageSelector = () => {
|
||||
|
||||
return (
|
||||
<Select onValueChange={handleSelect} value={language}>
|
||||
<SelectTrigger aria-label="Select language">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select language" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "تجاهل",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Toto pole je povinné",
|
||||
"invalidInput": "Neplatný údaj",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Dieses Feld ist notwendig",
|
||||
"invalidInput": "Ungültige Eingabe",
|
||||
"domainWarningTitle": "Ungültige Domain",
|
||||
"domainWarningSubtitle": "Sie greifen von einer falschen Domäne aus auf diese Instanz zu. Wenn Sie fortfahren, können Probleme mit der Authentifizierung auftreten.",
|
||||
"domainWarningSubtitle": "Diese Instanz ist so konfiguriert, dass sie von <code>{{appUrl}}</code> aufgerufen werden kann, aber <code>{{currentUrl}}</code> wird verwendet. Wenn Sie fortfahren, können Probleme bei der Authentifizierung auftreten.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignorieren",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "Estás accediendo a esta instancia desde un dominio incorrecto. Si sigues, puedes encontrar problemas con la autenticación.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Tämä kenttä on pakollinen",
|
||||
"invalidInput": "Virheellinen syöte",
|
||||
"domainWarningTitle": "Virheellinen verkkotunnus",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "Tämä instanssi on määritelty käyttämään osoitetta <code>{{appUrl}}</code>, mutta nykyinen osoite on <code>{{currentUrl}}</code>. Jos jatkat, saatat törmätä ongelmiin autentikoinnissa.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Jätä huomiotta",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Questo campo è obbligatorio",
|
||||
"invalidInput": "Input non valido",
|
||||
"domainWarningTitle": "Dominio non valido",
|
||||
"domainWarningSubtitle": "Stai accedendo a questa istanza da un dominio errato. Scegliendo di procedere, potresti incontrare problemi con l'autenticazione.",
|
||||
"domainWarningSubtitle": "Questa istanza è configurata per essere accessibile da <code>{{appUrl}}</code>, ma la stai visitando da <code>{{currentUrl}}</code>. Se procedi, potresti incorrere in problemi di autenticazione.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignora",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "不正なドメインからこのインスタンスにアクセスしています。続行すると、認証に問題が発生する可能性があります。",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"logoutSuccessTitle": "로그아웃 완료",
|
||||
"logoutSuccessSubtitle": "로그아웃되었습니다",
|
||||
"logoutTitle": "로그아웃",
|
||||
"logoutUsernameSubtitle": "현재 <code>{{username}}</code>로 로그인되어 있습니다. 아래 버튼을 클릭하여 로그아웃하세요.",
|
||||
"logoutUsernameSubtitle": "현재 <code>{{username}}</code>(으)로 로그인되어 있습니다. 아래 버튼을 클릭하여 로그아웃하세요.",
|
||||
"logoutOauthSubtitle": "현재 {{provider}} OAuth 제공자를 통해 <code>{{username}}</code>(으)로 로그인되어 있습니다. 아래 버튼을 클릭하여 로그아웃하세요.",
|
||||
"notFoundTitle": "페이지를 찾을 수 없습니다",
|
||||
"notFoundSubtitle": "찾으시는 페이지가 존재하지 않습니다.",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Dit veld is verplicht",
|
||||
"invalidInput": "Ongeldige invoer",
|
||||
"domainWarningTitle": "Ongeldig domein",
|
||||
"domainWarningSubtitle": "U benadert deze instantie vanuit een onjuist domein. Als u doorgaat, kunt u problemen ondervinden met authenticatie.",
|
||||
"domainWarningSubtitle": "Deze instantie is geconfigureerd voor toegang tot <code>{{appUrl}}</code>, maar <code>{{currentUrl}}</code> wordt gebruikt. Als je doorgaat, kun je problemen ondervinden met authenticatie.",
|
||||
"domainWarningCurrent": "Huidig:",
|
||||
"domainWarningExpected": "Verwacht:",
|
||||
"ignoreTitle": "Negeren",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "Du bruker denne forekomsten fra et feil domene. Dersom du fortsetter kan du få problemer med autentiseringen.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "To pole jest wymagane",
|
||||
"invalidInput": "Nieprawidłowe dane wejściowe",
|
||||
"domainWarningTitle": "Nieprawidłowa domena",
|
||||
"domainWarningSubtitle": "Masz dostęp do tej instancji z nieprawidłowej domeny. Jeśli kontynuujesz, możesz napotkać problemy z uwierzytelnianiem.",
|
||||
"domainWarningSubtitle": "Ta instancja jest skonfigurowana do uzyskania dostępu z <code>{{appUrl}}</code>, ale <code>{{currentUrl}}</code> jest w użyciu. Jeśli będziesz kontynuować, mogą wystąpić problemy z uwierzytelnianiem.",
|
||||
"domainWarningCurrent": "Bieżąca:",
|
||||
"domainWarningExpected": "Oczekiwana:",
|
||||
"ignoreTitle": "Zignoruj",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Este campo é obrigatório",
|
||||
"invalidInput": "Entrada Inválida",
|
||||
"domainWarningTitle": "Domínio inválido",
|
||||
"domainWarningSubtitle": "Você está acessando essa instância de um domínio incorreto. Se você continuar, você pode encontrar problemas com a autenticação.",
|
||||
"domainWarningSubtitle": "Esta instância está configurada para ser acessada de <code>{{appUrl}}</code>, mas <code>{{currentUrl}}</code> está sendo usado. Se você continuar, você pode encontrar problemas com a autenticação.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignorar",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Este campo é obrigatório",
|
||||
"invalidInput": "Entrada inválida",
|
||||
"domainWarningTitle": "Domínio inválido",
|
||||
"domainWarningSubtitle": "Acessa essa instância de um domínio incorreto. Se você continuar, você pode encontrar problemas com a autenticação.",
|
||||
"domainWarningSubtitle": "Esta instância está configurada para ser acedida a partir de <code>{{appUrl}}</code>, mas está a ser usado <code>{{currentUrl}}</code>. Se continuares, poderás ter problemas de autenticação.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignorar",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -51,33 +51,33 @@
|
||||
"forgotPasswordTitle": "Забыли пароль?",
|
||||
"failedToFetchProvidersTitle": "Не удалось загрузить поставщика авторизации. Пожалуйста, проверьте конфигурацию.",
|
||||
"errorTitle": "Произошла ошибка",
|
||||
"errorSubtitleInfo": "При обработке вашего запроса произошла следующая ошибка:",
|
||||
"errorSubtitleInfo": "The following error occurred while processing your request:",
|
||||
"errorSubtitle": "Произошла ошибка при попытке выполнить это действие. Проверьте консоль для дополнительной информации.",
|
||||
"forgotPasswordMessage": "Вы можете сбросить свой пароль, изменив переменную окружения `USERS`.",
|
||||
"fieldRequired": "Это поле является обязательным",
|
||||
"invalidInput": "Недопустимый ввод",
|
||||
"domainWarningTitle": "Неверный домен",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Текущий:",
|
||||
"domainWarningExpected": "Ожидается:",
|
||||
"domainWarningSubtitle": "Этот экземпляр настроен на доступ к нему из <code>{{appUrl}}</code>, но <code>{{currentUrl}}</code> в настоящее время используется. Если вы продолжите, то могут возникнуть проблемы с авторизацией.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Игнорировать",
|
||||
"goToCorrectDomainTitle": "Перейти к правильному домену",
|
||||
"authorizeTitle": "Разрешить",
|
||||
"authorizeCardTitle": "Продолжить с {{app}}?",
|
||||
"authorizeSubtitle": "Вы хотите продолжить работу с этим приложением? Внимательно проверьте запрашиваемые приложением разрешения.",
|
||||
"authorizeSubtitleOAuth": "Вы хотите продолжить работу с этим приложением?",
|
||||
"authorizeLoadingTitle": "Загрузка...",
|
||||
"authorizeLoadingSubtitle": "Пожалуйста, подождите, пока мы загрузим информацию о клиенте.",
|
||||
"authorizeSuccessTitle": "Разрешено",
|
||||
"authorizeSuccessSubtitle": "Вы будете перенаправлены в приложение через несколько секунд.",
|
||||
"authorizeErrorClientInfo": "Произошла ошибка при загрузке информации о клиенте. Пожалуйста, повторите попытку позже.",
|
||||
"authorizeErrorMissingParams": "Отсутствуют следующие параметры: {{missingParams}}",
|
||||
"openidScopeName": "Подключение OpenID",
|
||||
"openidScopeDescription": "Приложение сможет получить доступ к информации подключённого OpenID.",
|
||||
"emailScopeName": "Эл. Почта",
|
||||
"emailScopeDescription": "Приложение сможет получить доступ к вашему электронному адресу.",
|
||||
"profileScopeName": "Профиль",
|
||||
"profileScopeDescription": "Приложение сможет получить доступ к информации вашего профиля.",
|
||||
"groupsScopeName": "Группы",
|
||||
"groupsScopeDescription": "Приложение сможет получать доступ к информации о вашей группе."
|
||||
"authorizeTitle": "Authorize",
|
||||
"authorizeCardTitle": "Continue to {{app}}?",
|
||||
"authorizeSubtitle": "Would you like to continue to this app? Please carefully review the permissions requested by the app.",
|
||||
"authorizeSubtitleOAuth": "Would you like to continue to this app?",
|
||||
"authorizeLoadingTitle": "Loading...",
|
||||
"authorizeLoadingSubtitle": "Please wait while we load the client information.",
|
||||
"authorizeSuccessTitle": "Authorized",
|
||||
"authorizeSuccessSubtitle": "You will be redirected to the app in a few seconds.",
|
||||
"authorizeErrorClientInfo": "An error occurred while loading the client information. Please try again later.",
|
||||
"authorizeErrorMissingParams": "The following parameters are missing: {{missingParams}}",
|
||||
"openidScopeName": "OpenID Connect",
|
||||
"openidScopeDescription": "Allows the app to access your OpenID Connect information.",
|
||||
"emailScopeName": "Email",
|
||||
"emailScopeDescription": "Allows the app to access your email address.",
|
||||
"profileScopeName": "Profile",
|
||||
"profileScopeDescription": "Allows the app to access your profile information.",
|
||||
"groupsScopeName": "Groups",
|
||||
"groupsScopeDescription": "Allows the app to access your group information."
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Ово поље је неопходно",
|
||||
"invalidInput": "Неисправан унос",
|
||||
"domainWarningTitle": "Неисправан домен",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "Ова инстанца је подешена да јој се приступа са <code>{{appUrl}}</code>, али се користи <code>{{currentUrl}}</code>. Ако наставите, можете искусити проблеме са аутентификацијом.",
|
||||
"domainWarningCurrent": "Тренутни:",
|
||||
"domainWarningExpected": "Очекивани:",
|
||||
"ignoreTitle": "Игнориши",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "Du kommer åt den här instansen från en felaktig domän. Om du fortsätter kan du stöta på problem med autentisering.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "Bu alan zorunludur",
|
||||
"invalidInput": "Geçersiz girdi",
|
||||
"domainWarningTitle": "Geçersiz alan adı",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "Bu örnek, <code>{{appUrl}}</code> adresinden erişilecek şekilde yapılandırılmıştır, ancak <code>{{currentUrl}}</code> kullanılmaktadır. Devam ederseniz, kimlik doğrulama ile ilgili sorunlarla karşılaşabilirsiniz.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Yoksay",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "This field is required",
|
||||
"invalidInput": "Invalid input",
|
||||
"domainWarningTitle": "Invalid Domain",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "This instance is configured to be accessed from <code>{{appUrl}}</code>, but <code>{{currentUrl}}</code> is being used. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "Ignore",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"fieldRequired": "此為必填欄位",
|
||||
"invalidInput": "無效的輸入",
|
||||
"domainWarningTitle": "無效的網域",
|
||||
"domainWarningSubtitle": "You are accessing this instance from an incorrect domain. If you proceed, you may encounter issues with authentication.",
|
||||
"domainWarningSubtitle": "此服務設定為透過 <code>{{appUrl}}</code> 存取,但目前使用的是 <code>{{currentUrl}}</code>。若繼續操作,可能會遇到驗證問題。",
|
||||
"domainWarningCurrent": "Current:",
|
||||
"domainWarningExpected": "Expected:",
|
||||
"ignoreTitle": "忽略",
|
||||
|
||||
@@ -23,41 +23,39 @@ import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<main>
|
||||
<StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppContextProvider>
|
||||
<UserContextProvider>
|
||||
<TooltipProvider>
|
||||
<ThemeProvider defaultTheme="system" storageKey="tinyauth-theme">
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route element={<Layout />} errorElement={<ErrorPage />}>
|
||||
<Route path="/" element={<App />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/authorize" element={<AuthorizePage />} />
|
||||
<Route path="/logout" element={<LogoutPage />} />
|
||||
<Route path="/continue" element={<ContinuePage />} />
|
||||
<Route path="/totp" element={<TotpPage />} />
|
||||
<Route
|
||||
path="/forgot-password"
|
||||
element={<ForgotPasswordPage />}
|
||||
/>
|
||||
<Route
|
||||
path="/unauthorized"
|
||||
element={<UnauthorizedPage />}
|
||||
/>
|
||||
<Route path="/error" element={<ErrorPage />} />
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<Toaster />
|
||||
</ThemeProvider>
|
||||
</TooltipProvider>
|
||||
</UserContextProvider>
|
||||
</AppContextProvider>
|
||||
</QueryClientProvider>
|
||||
</StrictMode>
|
||||
</main>,
|
||||
<StrictMode>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppContextProvider>
|
||||
<UserContextProvider>
|
||||
<TooltipProvider>
|
||||
<ThemeProvider defaultTheme="system" storageKey="tinyauth-theme">
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route element={<Layout />} errorElement={<ErrorPage />}>
|
||||
<Route path="/" element={<App />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/authorize" element={<AuthorizePage />} />
|
||||
<Route path="/logout" element={<LogoutPage />} />
|
||||
<Route path="/continue" element={<ContinuePage />} />
|
||||
<Route path="/totp" element={<TotpPage />} />
|
||||
<Route
|
||||
path="/forgot-password"
|
||||
element={<ForgotPasswordPage />}
|
||||
/>
|
||||
<Route
|
||||
path="/unauthorized"
|
||||
element={<UnauthorizedPage />}
|
||||
/>
|
||||
<Route path="/error" element={<ErrorPage />} />
|
||||
<Route path="*" element={<NotFoundPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<Toaster />
|
||||
</ThemeProvider>
|
||||
</TooltipProvider>
|
||||
</UserContextProvider>
|
||||
</AppContextProvider>
|
||||
</QueryClientProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
@@ -52,11 +52,6 @@ export default defineConfig({
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/\.well-known/, ""),
|
||||
},
|
||||
"/robots.txt": {
|
||||
target: "http://tinyauth-backend:3000/robots.txt",
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/robots.txt/, ""),
|
||||
},
|
||||
},
|
||||
allowedHosts: true,
|
||||
},
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE "oidc_tokens" DROP COLUMN "code_hash";
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE "oidc_tokens" ADD COLUMN "code_hash" TEXT NOT NULL DEFAULT "";
|
||||
@@ -44,13 +44,7 @@ func NewBootstrapApp(config config.Config) *BootstrapApp {
|
||||
}
|
||||
|
||||
func (app *BootstrapApp) Setup() error {
|
||||
fmt.Println("Tinyauth is moving to an organization! All versions after v5.0.7 will be released under ghcr.io/tinyauthapp/tinyauth. Existing images will continue to work but new features and updates (including security ones) will only be released under the new image path.")
|
||||
|
||||
// get app url
|
||||
if app.config.AppURL == "" {
|
||||
return fmt.Errorf("app URL cannot be empty, perhaps config loading failed")
|
||||
}
|
||||
|
||||
appUrl, err := url.Parse(app.config.AppURL)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -275,9 +275,6 @@ func (controller *OIDCController) Token(c *gin.Context) {
|
||||
case "authorization_code":
|
||||
entry, err := controller.oidc.GetCodeEntry(c, controller.oidc.Hash(req.Code), client.ClientID)
|
||||
if err != nil {
|
||||
if err := controller.oidc.DeleteTokenByCodeHash(c, controller.oidc.Hash(req.Code)); err != nil {
|
||||
tlog.App.Error().Err(err).Msg("Failed to delete access token by code hash")
|
||||
}
|
||||
if errors.Is(err, service.ErrCodeNotFound) {
|
||||
tlog.App.Warn().Msg("Code not found")
|
||||
c.JSON(400, gin.H{
|
||||
|
||||
@@ -387,7 +387,7 @@ func TestOIDCController(t *testing.T) {
|
||||
err = json.Unmarshal(secondRecorder.Body.Bytes(), &secondRes)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "invalid_grant", secondRes["error"])
|
||||
assert.Equal(t, secondRes["error"], "invalid_grant")
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -778,74 +778,6 @@ func TestOIDCController(t *testing.T) {
|
||||
assert.NotEmpty(t, error)
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Ensure access token gets invalidated on double code use",
|
||||
middlewares: []gin.HandlerFunc{
|
||||
simpleCtx,
|
||||
},
|
||||
run: func(t *testing.T, router *gin.Engine, recorder *httptest.ResponseRecorder) {
|
||||
authorizeCodeTest, found := getTestByDescription("Ensure authorize succeeds with valid params")
|
||||
assert.True(t, found, "Authorize test not found")
|
||||
authorizeCodeTest(t, router, recorder)
|
||||
|
||||
var res map[string]any
|
||||
err := json.Unmarshal(recorder.Body.Bytes(), &res)
|
||||
assert.NoError(t, err)
|
||||
|
||||
redirectURI := res["redirect_uri"].(string)
|
||||
url, err := url.Parse(redirectURI)
|
||||
assert.NoError(t, err)
|
||||
|
||||
queryParams := url.Query()
|
||||
code := queryParams.Get("code")
|
||||
assert.NotEmpty(t, code)
|
||||
|
||||
reqBody := controller.TokenRequest{
|
||||
GrantType: "authorization_code",
|
||||
Code: code,
|
||||
RedirectURI: "https://test.example.com/callback",
|
||||
}
|
||||
reqBodyEncoded, err := query.Values(reqBody)
|
||||
assert.NoError(t, err)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/oidc/token", strings.NewReader(reqBodyEncoded.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.SetBasicAuth("some-client-id", "some-client-secret")
|
||||
recorder = httptest.NewRecorder()
|
||||
router.ServeHTTP(recorder, req)
|
||||
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
|
||||
err = json.Unmarshal(recorder.Body.Bytes(), &res)
|
||||
assert.NoError(t, err)
|
||||
|
||||
accessToken := res["access_token"].(string)
|
||||
assert.NotEmpty(t, accessToken)
|
||||
|
||||
req = httptest.NewRequest("GET", "/api/oidc/userinfo", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+accessToken)
|
||||
recorder = httptest.NewRecorder()
|
||||
router.ServeHTTP(recorder, req)
|
||||
assert.Equal(t, 200, recorder.Code)
|
||||
|
||||
req = httptest.NewRequest("POST", "/api/oidc/token", strings.NewReader(reqBodyEncoded.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.SetBasicAuth("some-client-id", "some-client-secret")
|
||||
recorder = httptest.NewRecorder()
|
||||
router.ServeHTTP(recorder, req)
|
||||
assert.Equal(t, 400, recorder.Code)
|
||||
|
||||
req = httptest.NewRequest("GET", "/api/oidc/userinfo", nil)
|
||||
req.Header.Set("Authorization", "Bearer "+accessToken)
|
||||
recorder = httptest.NewRecorder()
|
||||
router.ServeHTTP(recorder, req)
|
||||
assert.Equal(t, 401, recorder.Code)
|
||||
|
||||
err = json.Unmarshal(recorder.Body.Bytes(), &res)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "invalid_grant", res["error"])
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app := bootstrap.NewBootstrapApp(config.Config{})
|
||||
|
||||
@@ -46,11 +46,6 @@ func (m *UIMiddleware) Middleware() gin.HandlerFunc {
|
||||
case "api", "resources", ".well-known":
|
||||
c.Next()
|
||||
return
|
||||
case "robots.txt":
|
||||
c.Writer.Header().Set("Content-Type", "text/plain")
|
||||
c.Writer.WriteHeader(http.StatusOK)
|
||||
c.Writer.Write([]byte("User-agent: *\nDisallow: /\n"))
|
||||
return
|
||||
default:
|
||||
_, err := fs.Stat(m.uiFs, path)
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ type OidcToken struct {
|
||||
Sub string
|
||||
AccessTokenHash string
|
||||
RefreshTokenHash string
|
||||
CodeHash string
|
||||
Scope string
|
||||
ClientID string
|
||||
TokenExpiresAt int64
|
||||
|
||||
@@ -70,12 +70,11 @@ INSERT INTO "oidc_tokens" (
|
||||
"client_id",
|
||||
"token_expires_at",
|
||||
"refresh_token_expires_at",
|
||||
"code_hash",
|
||||
"nonce"
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
?, ?, ?, ?, ?, ?, ?, ?
|
||||
)
|
||||
RETURNING sub, access_token_hash, refresh_token_hash, code_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce
|
||||
RETURNING sub, access_token_hash, refresh_token_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce
|
||||
`
|
||||
|
||||
type CreateOidcTokenParams struct {
|
||||
@@ -86,7 +85,6 @@ type CreateOidcTokenParams struct {
|
||||
ClientID string
|
||||
TokenExpiresAt int64
|
||||
RefreshTokenExpiresAt int64
|
||||
CodeHash string
|
||||
Nonce string
|
||||
}
|
||||
|
||||
@@ -99,7 +97,6 @@ func (q *Queries) CreateOidcToken(ctx context.Context, arg CreateOidcTokenParams
|
||||
arg.ClientID,
|
||||
arg.TokenExpiresAt,
|
||||
arg.RefreshTokenExpiresAt,
|
||||
arg.CodeHash,
|
||||
arg.Nonce,
|
||||
)
|
||||
var i OidcToken
|
||||
@@ -107,7 +104,6 @@ func (q *Queries) CreateOidcToken(ctx context.Context, arg CreateOidcTokenParams
|
||||
&i.Sub,
|
||||
&i.AccessTokenHash,
|
||||
&i.RefreshTokenHash,
|
||||
&i.CodeHash,
|
||||
&i.Scope,
|
||||
&i.ClientID,
|
||||
&i.TokenExpiresAt,
|
||||
@@ -202,7 +198,7 @@ func (q *Queries) DeleteExpiredOidcCodes(ctx context.Context, expiresAt int64) (
|
||||
const deleteExpiredOidcTokens = `-- name: DeleteExpiredOidcTokens :many
|
||||
DELETE FROM "oidc_tokens"
|
||||
WHERE "token_expires_at" < ? AND "refresh_token_expires_at" < ?
|
||||
RETURNING sub, access_token_hash, refresh_token_hash, code_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce
|
||||
RETURNING sub, access_token_hash, refresh_token_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce
|
||||
`
|
||||
|
||||
type DeleteExpiredOidcTokensParams struct {
|
||||
@@ -223,7 +219,6 @@ func (q *Queries) DeleteExpiredOidcTokens(ctx context.Context, arg DeleteExpired
|
||||
&i.Sub,
|
||||
&i.AccessTokenHash,
|
||||
&i.RefreshTokenHash,
|
||||
&i.CodeHash,
|
||||
&i.Scope,
|
||||
&i.ClientID,
|
||||
&i.TokenExpiresAt,
|
||||
@@ -273,16 +268,6 @@ func (q *Queries) DeleteOidcToken(ctx context.Context, accessTokenHash string) e
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteOidcTokenByCodeHash = `-- name: DeleteOidcTokenByCodeHash :exec
|
||||
DELETE FROM "oidc_tokens"
|
||||
WHERE "code_hash" = ?
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteOidcTokenByCodeHash(ctx context.Context, codeHash string) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteOidcTokenByCodeHash, codeHash)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteOidcTokenBySub = `-- name: DeleteOidcTokenBySub :exec
|
||||
DELETE FROM "oidc_tokens"
|
||||
WHERE "sub" = ?
|
||||
@@ -390,7 +375,7 @@ func (q *Queries) GetOidcCodeUnsafe(ctx context.Context, codeHash string) (OidcC
|
||||
}
|
||||
|
||||
const getOidcToken = `-- name: GetOidcToken :one
|
||||
SELECT sub, access_token_hash, refresh_token_hash, code_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce FROM "oidc_tokens"
|
||||
SELECT sub, access_token_hash, refresh_token_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce FROM "oidc_tokens"
|
||||
WHERE "access_token_hash" = ?
|
||||
`
|
||||
|
||||
@@ -401,7 +386,6 @@ func (q *Queries) GetOidcToken(ctx context.Context, accessTokenHash string) (Oid
|
||||
&i.Sub,
|
||||
&i.AccessTokenHash,
|
||||
&i.RefreshTokenHash,
|
||||
&i.CodeHash,
|
||||
&i.Scope,
|
||||
&i.ClientID,
|
||||
&i.TokenExpiresAt,
|
||||
@@ -412,7 +396,7 @@ func (q *Queries) GetOidcToken(ctx context.Context, accessTokenHash string) (Oid
|
||||
}
|
||||
|
||||
const getOidcTokenByRefreshToken = `-- name: GetOidcTokenByRefreshToken :one
|
||||
SELECT sub, access_token_hash, refresh_token_hash, code_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce FROM "oidc_tokens"
|
||||
SELECT sub, access_token_hash, refresh_token_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce FROM "oidc_tokens"
|
||||
WHERE "refresh_token_hash" = ?
|
||||
`
|
||||
|
||||
@@ -423,7 +407,6 @@ func (q *Queries) GetOidcTokenByRefreshToken(ctx context.Context, refreshTokenHa
|
||||
&i.Sub,
|
||||
&i.AccessTokenHash,
|
||||
&i.RefreshTokenHash,
|
||||
&i.CodeHash,
|
||||
&i.Scope,
|
||||
&i.ClientID,
|
||||
&i.TokenExpiresAt,
|
||||
@@ -434,7 +417,7 @@ func (q *Queries) GetOidcTokenByRefreshToken(ctx context.Context, refreshTokenHa
|
||||
}
|
||||
|
||||
const getOidcTokenBySub = `-- name: GetOidcTokenBySub :one
|
||||
SELECT sub, access_token_hash, refresh_token_hash, code_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce FROM "oidc_tokens"
|
||||
SELECT sub, access_token_hash, refresh_token_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce FROM "oidc_tokens"
|
||||
WHERE "sub" = ?
|
||||
`
|
||||
|
||||
@@ -445,7 +428,6 @@ func (q *Queries) GetOidcTokenBySub(ctx context.Context, sub string) (OidcToken,
|
||||
&i.Sub,
|
||||
&i.AccessTokenHash,
|
||||
&i.RefreshTokenHash,
|
||||
&i.CodeHash,
|
||||
&i.Scope,
|
||||
&i.ClientID,
|
||||
&i.TokenExpiresAt,
|
||||
@@ -481,7 +463,7 @@ UPDATE "oidc_tokens" SET
|
||||
"token_expires_at" = ?,
|
||||
"refresh_token_expires_at" = ?
|
||||
WHERE "refresh_token_hash" = ?
|
||||
RETURNING sub, access_token_hash, refresh_token_hash, code_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce
|
||||
RETURNING sub, access_token_hash, refresh_token_hash, scope, client_id, token_expires_at, refresh_token_expires_at, nonce
|
||||
`
|
||||
|
||||
type UpdateOidcTokenByRefreshTokenParams struct {
|
||||
@@ -505,7 +487,6 @@ func (q *Queries) UpdateOidcTokenByRefreshToken(ctx context.Context, arg UpdateO
|
||||
&i.Sub,
|
||||
&i.AccessTokenHash,
|
||||
&i.RefreshTokenHash,
|
||||
&i.CodeHash,
|
||||
&i.Scope,
|
||||
&i.ClientID,
|
||||
&i.TokenExpiresAt,
|
||||
|
||||
@@ -506,7 +506,6 @@ func (service *OIDCService) GenerateAccessToken(c *gin.Context, client config.OI
|
||||
TokenExpiresAt: tokenExpiresAt,
|
||||
RefreshTokenExpiresAt: refrshTokenExpiresAt,
|
||||
Nonce: codeEntry.Nonce,
|
||||
CodeHash: codeEntry.CodeHash,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -591,10 +590,6 @@ func (service *OIDCService) DeleteToken(c *gin.Context, tokenHash string) error
|
||||
return service.queries.DeleteOidcToken(c, tokenHash)
|
||||
}
|
||||
|
||||
func (service *OIDCService) DeleteTokenByCodeHash(c *gin.Context, codeHash string) error {
|
||||
return service.queries.DeleteOidcTokenByCodeHash(c, codeHash)
|
||||
}
|
||||
|
||||
func (service *OIDCService) GetAccessToken(c *gin.Context, tokenHash string) (repository.OidcToken, error) {
|
||||
entry, err := service.queries.GetOidcToken(c, tokenHash)
|
||||
|
||||
|
||||
@@ -48,10 +48,9 @@ INSERT INTO "oidc_tokens" (
|
||||
"client_id",
|
||||
"token_expires_at",
|
||||
"refresh_token_expires_at",
|
||||
"code_hash",
|
||||
"nonce"
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
?, ?, ?, ?, ?, ?, ?, ?
|
||||
)
|
||||
RETURNING *;
|
||||
|
||||
@@ -76,10 +75,6 @@ WHERE "refresh_token_hash" = ?;
|
||||
SELECT * FROM "oidc_tokens"
|
||||
WHERE "sub" = ?;
|
||||
|
||||
-- name: DeleteOidcTokenByCodeHash :exec
|
||||
DELETE FROM "oidc_tokens"
|
||||
WHERE "code_hash" = ?;
|
||||
|
||||
-- name: DeleteOidcToken :exec
|
||||
DELETE FROM "oidc_tokens"
|
||||
WHERE "access_token_hash" = ?;
|
||||
|
||||
@@ -13,7 +13,6 @@ CREATE TABLE IF NOT EXISTS "oidc_tokens" (
|
||||
"sub" TEXT NOT NULL UNIQUE,
|
||||
"access_token_hash" TEXT NOT NULL PRIMARY KEY UNIQUE,
|
||||
"refresh_token_hash" TEXT NOT NULL,
|
||||
"code_hash" TEXT NOT NULL,
|
||||
"scope" TEXT NOT NULL,
|
||||
"client_id" TEXT NOT NULL,
|
||||
"token_expires_at" INTEGER NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user