@owlmeans/web-oauth 0.1.18-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/agent-meta/manifest.json +16 -0
- package/agent-meta/skills/web-oauth/SKILL.md +131 -0
- package/build/@/components/ui/button.d.ts +11 -0
- package/build/@/components/ui/button.d.ts.map +1 -0
- package/build/@/components/ui/button.js +32 -0
- package/build/@/components/ui/button.js.map +1 -0
- package/build/@/components/ui/card.d.ts +10 -0
- package/build/@/components/ui/card.d.ts.map +1 -0
- package/build/@/components/ui/card.js +25 -0
- package/build/@/components/ui/card.js.map +1 -0
- package/build/@/components/ui/input.d.ts +4 -0
- package/build/@/components/ui/input.d.ts.map +1 -0
- package/build/@/components/ui/input.js +7 -0
- package/build/@/components/ui/input.js.map +1 -0
- package/build/@/components/ui/label.d.ts +5 -0
- package/build/@/components/ui/label.d.ts.map +1 -0
- package/build/@/components/ui/label.js +8 -0
- package/build/@/components/ui/label.js.map +1 -0
- package/build/@/lib/utils.d.ts +3 -0
- package/build/@/lib/utils.d.ts.map +1 -0
- package/build/@/lib/utils.js +6 -0
- package/build/@/lib/utils.js.map +1 -0
- package/build/append.d.ts +14 -0
- package/build/append.d.ts.map +1 -0
- package/build/append.js +19 -0
- package/build/append.js.map +1 -0
- package/build/components/consent-screen.d.ts +12 -0
- package/build/components/consent-screen.d.ts.map +1 -0
- package/build/components/consent-screen.js +30 -0
- package/build/components/consent-screen.js.map +1 -0
- package/build/components/device-screen.d.ts +10 -0
- package/build/components/device-screen.d.ts.map +1 -0
- package/build/components/device-screen.js +48 -0
- package/build/components/device-screen.js.map +1 -0
- package/build/components/done-screen.d.ts +8 -0
- package/build/components/done-screen.d.ts.map +1 -0
- package/build/components/done-screen.js +18 -0
- package/build/components/done-screen.js.map +1 -0
- package/build/components/index.d.ts +4 -0
- package/build/components/index.d.ts.map +1 -0
- package/build/components/index.js +4 -0
- package/build/components/index.js.map +1 -0
- package/build/consts.d.ts +6 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +6 -0
- package/build/consts.js.map +1 -0
- package/build/entrypoints.d.ts +8 -0
- package/build/entrypoints.d.ts.map +1 -0
- package/build/entrypoints.js +20 -0
- package/build/entrypoints.js.map +1 -0
- package/build/hooks/use-oauth-consent.d.ts +27 -0
- package/build/hooks/use-oauth-consent.d.ts.map +1 -0
- package/build/hooks/use-oauth-consent.js +128 -0
- package/build/hooks/use-oauth-consent.js.map +1 -0
- package/build/i18n/be.json +35 -0
- package/build/i18n/de.json +35 -0
- package/build/i18n/en.json +35 -0
- package/build/i18n/es.json +35 -0
- package/build/i18n/pl.json +35 -0
- package/build/i18n/ru.json +35 -0
- package/build/i18n/uk.json +35 -0
- package/build/i18n.d.ts +2 -0
- package/build/i18n.d.ts.map +1 -0
- package/build/i18n.js +17 -0
- package/build/i18n.js.map +1 -0
- package/build/index.d.ts +7 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +7 -0
- package/build/index.js.map +1 -0
- package/components.json +21 -0
- package/package.json +77 -0
- package/src/@/components/ui/button.tsx +60 -0
- package/src/@/components/ui/card.tsx +93 -0
- package/src/@/components/ui/input.tsx +22 -0
- package/src/@/components/ui/label.tsx +23 -0
- package/src/@/globals.css +57 -0
- package/src/@/lib/utils.ts +6 -0
- package/src/append.ts +24 -0
- package/src/components/consent-screen.tsx +95 -0
- package/src/components/device-screen.tsx +81 -0
- package/src/components/done-screen.tsx +30 -0
- package/src/components/index.ts +3 -0
- package/src/consts.ts +6 -0
- package/src/entrypoints.ts +22 -0
- package/src/hooks/use-oauth-consent.ts +163 -0
- package/src/i18n/be.json +35 -0
- package/src/i18n/de.json +35 -0
- package/src/i18n/en.json +35 -0
- package/src/i18n/es.json +35 -0
- package/src/i18n/pl.json +35 -0
- package/src/i18n/ru.json +35 -0
- package/src/i18n/uk.json +35 -0
- package/src/i18n.ts +18 -0
- package/src/index.ts +6 -0
- package/tests/consent.spec.ts +260 -0
- package/tests/context.ts +48 -0
- package/tests/device.spec.ts +64 -0
- package/tests/done.spec.ts +41 -0
- package/tests/harness/css.d.ts +1 -0
- package/tests/harness/frame.html +15 -0
- package/tests/harness/index.html +11 -0
- package/tests/harness/mount.tsx +89 -0
- package/tests/helpers.ts +97 -0
- package/tests/i18n.spec.ts +41 -0
- package/tests/languages.spec.ts +38 -0
- package/tests/package-boundary.spec.ts +19 -0
- package/tests/tsconfig.json +12 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
2
|
+
import { useContext, useNavigate } from '@owlmeans/client'
|
|
3
|
+
import { DEFAULT_ALIAS as AUTH_SERVICE } from '@owlmeans/client-auth'
|
|
4
|
+
import type { AuthService } from '@owlmeans/auth-common'
|
|
5
|
+
import { DISPATCHER } from '@owlmeans/auth'
|
|
6
|
+
import { suspendFlow } from '@owlmeans/client-flow'
|
|
7
|
+
import { makeFlowModel } from '@owlmeans/flow'
|
|
8
|
+
import { ResilientError } from '@owlmeans/error'
|
|
9
|
+
import {
|
|
10
|
+
makeOAuthProtocols, oauthFlow, OAuthFlowStep, OAUTH_PAYLOAD_KIND, OAUTH_PAYLOAD_REF
|
|
11
|
+
} from '@owlmeans/oauth'
|
|
12
|
+
import type { ConsentView, OAuthEntrypointOptions } from '@owlmeans/oauth'
|
|
13
|
+
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
14
|
+
import { OAUTH_SUSPEND_TTL_MS } from '../consts.js'
|
|
15
|
+
|
|
16
|
+
export type ConsentStage = 'checking' | 'signing-in' | 'loading' | 'ready' | 'deciding' | 'done' | 'error'
|
|
17
|
+
|
|
18
|
+
/** Why the screen cannot go on — the screen phrases each kind as ONE sentence, never the wire text. */
|
|
19
|
+
export type ConsentErrorKind = 'missing' | 'not-found' | 'expired' | 'forbidden' | 'failed'
|
|
20
|
+
|
|
21
|
+
export interface UseOAuthConsent {
|
|
22
|
+
stage: ConsentStage
|
|
23
|
+
view: ConsentView | null
|
|
24
|
+
/** The raw failure, for a log; what a person reads is `errorKind`. */
|
|
25
|
+
error: string | null
|
|
26
|
+
errorKind: ConsentErrorKind | null
|
|
27
|
+
approve: () => Promise<void>
|
|
28
|
+
deny: () => Promise<void>
|
|
29
|
+
/** Sign the current session out and go through the sign-in again, returning to this request. */
|
|
30
|
+
switchAccount: () => Promise<void>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const errorKindOf = (message: string): ConsentErrorKind =>
|
|
34
|
+
message.includes('request-expired') ? 'expired'
|
|
35
|
+
: message.includes('request-not-found') ? 'not-found'
|
|
36
|
+
: message.includes('forbidden') ? 'forbidden'
|
|
37
|
+
: 'failed'
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The whole consent screen's logic, headless — so the rendered component stays a thin shell over
|
|
41
|
+
* whatever a consuming app's own primitives look like, the same split `@owlmeans/web-auth-token`
|
|
42
|
+
* draws between its panel and its hook.
|
|
43
|
+
*
|
|
44
|
+
* `ref` is whatever the URL query named: a code grant's request id, or a device grant's user
|
|
45
|
+
* code — `resolveRequestRef` on the server sorts out which. `aliases` lets an app that mounted
|
|
46
|
+
* these entrypoints under a different parent still reach them; the defaults are what
|
|
47
|
+
* `oauthEntrypoints` binds.
|
|
48
|
+
*/
|
|
49
|
+
export const useOAuthConsent = (ref: string | null, aliases?: OAuthEntrypointOptions): UseOAuthConsent => {
|
|
50
|
+
const context = useContext()
|
|
51
|
+
const nav = useNavigate()
|
|
52
|
+
const protocols = makeOAuthProtocols(aliases)
|
|
53
|
+
|
|
54
|
+
const [stage, setStage] = useState<ConsentStage>('checking')
|
|
55
|
+
const [view, setView] = useState<ConsentView | null>(null)
|
|
56
|
+
const [error, setError] = useState<string | null>(null)
|
|
57
|
+
const [errorKind, setErrorKind] = useState<ConsentErrorKind | null>(null)
|
|
58
|
+
const suspending = useRef(false)
|
|
59
|
+
|
|
60
|
+
const fail = (e: unknown): void => {
|
|
61
|
+
const message = ResilientError.ensure(e instanceof Error ? e : String(e)).message
|
|
62
|
+
setError(message)
|
|
63
|
+
setErrorKind(errorKindOf(message))
|
|
64
|
+
setStage('error')
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Suspend the consent flow at its `sign-in` step and leave for the dispatcher. Suspending AT
|
|
69
|
+
* that step is what makes resuming land back on `consent` with the same ref.
|
|
70
|
+
*/
|
|
71
|
+
const leaveForSignIn = async (target: string): Promise<void> => {
|
|
72
|
+
const model = await makeFlowModel(oauthFlow)
|
|
73
|
+
model.updatePayload({ [OAUTH_PAYLOAD_REF]: target })
|
|
74
|
+
model.transit(OAuthFlowStep.SignIn, true)
|
|
75
|
+
await suspendFlow(context, model, { expiresAt: Date.now() + OAUTH_SUSPEND_TTL_MS })
|
|
76
|
+
|
|
77
|
+
const dispatcher = await context.entrypoint<ClientEntrypoint<string>>(DISPATCHER).url()
|
|
78
|
+
window.location.href = dispatcher
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (ref == null || ref === '') {
|
|
83
|
+
setError('Nothing to approve.')
|
|
84
|
+
setErrorKind('missing')
|
|
85
|
+
setStage('error')
|
|
86
|
+
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let cancelled = false
|
|
91
|
+
void (async () => {
|
|
92
|
+
const auth = context.service<AuthService>(AUTH_SERVICE)
|
|
93
|
+
const token = await auth.authenticated()
|
|
94
|
+
|
|
95
|
+
if (token == null || token === '') {
|
|
96
|
+
if (suspending.current) return
|
|
97
|
+
suspending.current = true
|
|
98
|
+
setStage('signing-in')
|
|
99
|
+
|
|
100
|
+
await leaveForSignIn(ref)
|
|
101
|
+
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
setStage('loading')
|
|
106
|
+
try {
|
|
107
|
+
const loaded = await context.entrypoint(protocols.load).call({ params: { ref } })
|
|
108
|
+
if (!cancelled) {
|
|
109
|
+
setView(loaded)
|
|
110
|
+
setStage('ready')
|
|
111
|
+
}
|
|
112
|
+
} catch (e) {
|
|
113
|
+
if (!cancelled) fail(e)
|
|
114
|
+
}
|
|
115
|
+
})()
|
|
116
|
+
|
|
117
|
+
return () => { cancelled = true }
|
|
118
|
+
}, [ref])
|
|
119
|
+
|
|
120
|
+
const decide = useCallback(async (action: 'approve' | 'deny') => {
|
|
121
|
+
if (ref == null) return
|
|
122
|
+
setStage('deciding')
|
|
123
|
+
try {
|
|
124
|
+
const protocol = action === 'approve' ? protocols.approve : protocols.deny
|
|
125
|
+
const result = await context.entrypoint(protocol).call({ params: { ref } })
|
|
126
|
+
if (result.redirect != null) {
|
|
127
|
+
window.location.href = result.redirect
|
|
128
|
+
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
// Device grant: nothing to redirect to — the poller catches up on its own. `approve` and
|
|
132
|
+
// `deny` both lead to `done` from `consent`; asking the flow for that step's module is what
|
|
133
|
+
// keeps this in step with the shared definition instead of hardcoding the destination.
|
|
134
|
+
const model = await makeFlowModel(oauthFlow)
|
|
135
|
+
model.updatePayload({ [OAUTH_PAYLOAD_KIND]: view?.kind ?? '', [OAUTH_PAYLOAD_REF]: ref })
|
|
136
|
+
model.transit(action, true)
|
|
137
|
+
const destination = model.step()
|
|
138
|
+
setStage('done')
|
|
139
|
+
await nav.navigate(
|
|
140
|
+
context.entrypoint<ClientEntrypoint<string>>(destination.module!), { query: model.payload() }
|
|
141
|
+
)
|
|
142
|
+
} catch (e) {
|
|
143
|
+
fail(e)
|
|
144
|
+
}
|
|
145
|
+
}, [ref, view])
|
|
146
|
+
|
|
147
|
+
const switchAccount = useCallback(async () => {
|
|
148
|
+
if (ref == null || ref === '') return
|
|
149
|
+
try {
|
|
150
|
+
await context.service<AuthService>(AUTH_SERVICE).update(undefined)
|
|
151
|
+
await leaveForSignIn(ref)
|
|
152
|
+
} catch (e) {
|
|
153
|
+
fail(e)
|
|
154
|
+
}
|
|
155
|
+
}, [ref])
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
stage, view, error, errorKind,
|
|
159
|
+
approve: () => decide('approve'),
|
|
160
|
+
deny: () => decide('deny'),
|
|
161
|
+
switchAccount,
|
|
162
|
+
}
|
|
163
|
+
}
|
package/src/i18n/be.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Праверка сеанса…",
|
|
4
|
+
"loading": "Загрузка запыту…",
|
|
5
|
+
"framed": "Гэты экран нельга паказаць унутры іншай старонкі. Адкрыйце яго напрамую.",
|
|
6
|
+
"error": "Нешта пайшло не так. Паспрабуйце яшчэ раз з праграмы, якая накіравала вас сюды.",
|
|
7
|
+
"title": "{{client}} хоча атрымаць доступ да вашага акаўнта",
|
|
8
|
+
"known": "Вы ўжо карысталіся гэтай праграмай раней.",
|
|
9
|
+
"known-by-host": "Запыт ад {{host}}.",
|
|
10
|
+
"unverified": "Гэтая праграма зарэгістравалася самастойна і не была правераная.",
|
|
11
|
+
"device-code": "Код: {{code}}",
|
|
12
|
+
"device-name": "Прылада: {{name}}",
|
|
13
|
+
"redirect-host": "Вы вернецеся на {{host}}.",
|
|
14
|
+
"localhost-warning": "Гэтая праграма зарэгістравала толькі адрасы на вашым уласным камп'ютары. Пацвярджайце гэта, толькі калі вы самі толькі што пачалі ўваход.",
|
|
15
|
+
"scope": "Запытаны доступ: {{scopes}}",
|
|
16
|
+
"approve": "Дазволіць",
|
|
17
|
+
"deny": "Адхіліць",
|
|
18
|
+
"error-missing": "Тут няма чаго пацвярджаць. Пачніце ўваход нанова з праграмы.",
|
|
19
|
+
"error-not-found": "Гэты запыт невядомы або ўжо выкарыстаны. Пачніце ўваход нанова з праграмы.",
|
|
20
|
+
"error-expired": "Тэрмін дзеяння гэтага запыту скончыўся. Пачніце ўваход нанова з праграмы.",
|
|
21
|
+
"error-forbidden": "Акаўнт гэтага тыпу не можа пацвярджаць доступ. Увайдзіце ў акаўнт, які вы выкарыстоўваеце ў OwlMeans, і паспрабуйце яшчэ раз.",
|
|
22
|
+
"switch-account": "Выкарыстаць іншы акаўнт"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Падключыць прыладу",
|
|
26
|
+
"description": "Увядзіце код, паказаны праграмай, да якой вы падключаецеся.",
|
|
27
|
+
"code-label": "Код",
|
|
28
|
+
"continue": "Працягнуць"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "Вы ўвайшлі ў сістэму",
|
|
32
|
+
"message": "Можаце закрыць гэтае акно і працягнуць працу ў праграме, якая накіравала вас сюды.",
|
|
33
|
+
"device-message": "Можаце закрыць гэтае акно. Праграма падхопіць гэта аўтаматычна."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n/de.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Sitzung wird überprüft…",
|
|
4
|
+
"loading": "Anfrage wird geladen…",
|
|
5
|
+
"framed": "Dieser Bildschirm kann nicht innerhalb einer anderen Seite angezeigt werden. Öffne ihn direkt.",
|
|
6
|
+
"error": "Etwas ist schiefgelaufen. Versuche es erneut über die Anwendung, die dich hierher geschickt hat.",
|
|
7
|
+
"title": "{{client}} möchte auf dein Konto zugreifen",
|
|
8
|
+
"known": "Du hast diese Anwendung bereits verwendet.",
|
|
9
|
+
"known-by-host": "Anfrage von {{host}}.",
|
|
10
|
+
"unverified": "Diese Anwendung hat sich selbst registriert und wurde nicht verifiziert.",
|
|
11
|
+
"device-code": "Code: {{code}}",
|
|
12
|
+
"device-name": "Gerät: {{name}}",
|
|
13
|
+
"redirect-host": "Du kehrst zu {{host}} zurück.",
|
|
14
|
+
"localhost-warning": "Diese Anwendung hat nur Adressen auf deinem eigenen Computer registriert. Bestätige dies nur, wenn du die Anmeldung gerade selbst gestartet hast.",
|
|
15
|
+
"scope": "Angeforderter Zugriff: {{scopes}}",
|
|
16
|
+
"approve": "Genehmigen",
|
|
17
|
+
"deny": "Ablehnen",
|
|
18
|
+
"error-missing": "Hier gibt es nichts zu bestätigen. Starte die Anmeldung erneut in der Anwendung.",
|
|
19
|
+
"error-not-found": "Diese Anfrage ist unbekannt oder wurde bereits verwendet. Starte die Anmeldung erneut in der Anwendung.",
|
|
20
|
+
"error-expired": "Diese Anfrage ist abgelaufen. Starte die Anmeldung erneut in der Anwendung.",
|
|
21
|
+
"error-forbidden": "Diese Art von Konto kann keinen Zugriff bestätigen. Melde dich mit dem Konto an, das du für OwlMeans verwendest, und versuche es erneut.",
|
|
22
|
+
"switch-account": "Anderes Konto verwenden"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Gerät verbinden",
|
|
26
|
+
"description": "Gib den Code ein, den die Anwendung anzeigt, mit der du dich verbindest.",
|
|
27
|
+
"code-label": "Code",
|
|
28
|
+
"continue": "Weiter"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "Du bist angemeldet",
|
|
32
|
+
"message": "Du kannst dieses Fenster schließen und in der Anwendung fortfahren, die dich hierher geschickt hat.",
|
|
33
|
+
"device-message": "Du kannst dieses Fenster schließen. Die Anwendung übernimmt dies automatisch."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n/en.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Checking your session…",
|
|
4
|
+
"loading": "Loading the request…",
|
|
5
|
+
"framed": "This screen cannot be shown inside another page. Open it directly.",
|
|
6
|
+
"error": "Something went wrong. Try again from the application that sent you here.",
|
|
7
|
+
"title": "{{client}} wants to access your account",
|
|
8
|
+
"known": "You've used this application before.",
|
|
9
|
+
"known-by-host": "Requesting from {{host}}.",
|
|
10
|
+
"unverified": "This application registered itself and has not been verified.",
|
|
11
|
+
"device-code": "Code: {{code}}",
|
|
12
|
+
"device-name": "Device: {{name}}",
|
|
13
|
+
"redirect-host": "You will return to {{host}}.",
|
|
14
|
+
"localhost-warning": "This application only registered addresses on your own computer. Only approve this if you started the sign-in yourself, just now.",
|
|
15
|
+
"scope": "Access requested: {{scopes}}",
|
|
16
|
+
"approve": "Approve",
|
|
17
|
+
"deny": "Deny",
|
|
18
|
+
"error-missing": "There is nothing to approve here. Start the sign-in again from the application.",
|
|
19
|
+
"error-not-found": "This request is unknown or has already been used. Start the sign-in again from the application.",
|
|
20
|
+
"error-expired": "This request has expired. Start the sign-in again from the application.",
|
|
21
|
+
"error-forbidden": "This kind of account cannot approve access. Sign in with the account you use for OwlMeans and try again.",
|
|
22
|
+
"switch-account": "Use another account"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Connect a device",
|
|
26
|
+
"description": "Enter the code shown by the application you're connecting.",
|
|
27
|
+
"code-label": "Code",
|
|
28
|
+
"continue": "Continue"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "You're signed in",
|
|
32
|
+
"message": "You may close this window and continue in the application that sent you here.",
|
|
33
|
+
"device-message": "You may close this window. The application will pick this up automatically."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n/es.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Comprobando tu sesión…",
|
|
4
|
+
"loading": "Cargando la solicitud…",
|
|
5
|
+
"framed": "Esta pantalla no puede mostrarse dentro de otra página. Ábrela directamente.",
|
|
6
|
+
"error": "Algo salió mal. Vuelve a intentarlo desde la aplicación que te envió aquí.",
|
|
7
|
+
"title": "{{client}} quiere acceder a tu cuenta",
|
|
8
|
+
"known": "Ya has usado esta aplicación antes.",
|
|
9
|
+
"known-by-host": "Solicitud desde {{host}}.",
|
|
10
|
+
"unverified": "Esta aplicación se registró por sí misma y no ha sido verificada.",
|
|
11
|
+
"device-code": "Código: {{code}}",
|
|
12
|
+
"device-name": "Dispositivo: {{name}}",
|
|
13
|
+
"redirect-host": "Volverás a {{host}}.",
|
|
14
|
+
"localhost-warning": "Esta aplicación solo registró direcciones en tu propio equipo. Aprueba esto únicamente si tú mismo iniciaste el inicio de sesión, justo ahora.",
|
|
15
|
+
"scope": "Acceso solicitado: {{scopes}}",
|
|
16
|
+
"approve": "Aprobar",
|
|
17
|
+
"deny": "Rechazar",
|
|
18
|
+
"error-missing": "Aquí no hay nada que aprobar. Inicia sesión de nuevo desde la aplicación.",
|
|
19
|
+
"error-not-found": "Esta solicitud es desconocida o ya se ha usado. Inicia sesión de nuevo desde la aplicación.",
|
|
20
|
+
"error-expired": "Esta solicitud ha caducado. Inicia sesión de nuevo desde la aplicación.",
|
|
21
|
+
"error-forbidden": "Este tipo de cuenta no puede aprobar el acceso. Inicia sesión con la cuenta que usas en OwlMeans e inténtalo de nuevo.",
|
|
22
|
+
"switch-account": "Usar otra cuenta"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Conectar un dispositivo",
|
|
26
|
+
"description": "Introduce el código que muestra la aplicación a la que te estás conectando.",
|
|
27
|
+
"code-label": "Código",
|
|
28
|
+
"continue": "Continuar"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "Has iniciado sesión",
|
|
32
|
+
"message": "Puedes cerrar esta ventana y continuar en la aplicación que te envió aquí.",
|
|
33
|
+
"device-message": "Puedes cerrar esta ventana. La aplicación lo detectará automáticamente."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n/pl.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Sprawdzanie sesji…",
|
|
4
|
+
"loading": "Wczytywanie żądania…",
|
|
5
|
+
"framed": "Tego ekranu nie można wyświetlić wewnątrz innej strony. Otwórz go bezpośrednio.",
|
|
6
|
+
"error": "Coś poszło nie tak. Spróbuj ponownie z aplikacji, która Cię tu skierowała.",
|
|
7
|
+
"title": "{{client}} chce uzyskać dostęp do Twojego konta",
|
|
8
|
+
"known": "Korzystałeś już z tej aplikacji.",
|
|
9
|
+
"known-by-host": "Żądanie z {{host}}.",
|
|
10
|
+
"unverified": "Ta aplikacja zarejestrowała się samodzielnie i nie została zweryfikowana.",
|
|
11
|
+
"device-code": "Kod: {{code}}",
|
|
12
|
+
"device-name": "Urządzenie: {{name}}",
|
|
13
|
+
"redirect-host": "Wrócisz do {{host}}.",
|
|
14
|
+
"localhost-warning": "Ta aplikacja zarejestrowała wyłącznie adresy na Twoim własnym komputerze. Zatwierdź to tylko wtedy, gdy sam przed chwilą rozpocząłeś logowanie.",
|
|
15
|
+
"scope": "Żądany dostęp: {{scopes}}",
|
|
16
|
+
"approve": "Zatwierdź",
|
|
17
|
+
"deny": "Odrzuć",
|
|
18
|
+
"error-missing": "Nie ma tu nic do zatwierdzenia. Rozpocznij logowanie od nowa w aplikacji.",
|
|
19
|
+
"error-not-found": "To żądanie jest nieznane lub zostało już wykorzystane. Rozpocznij logowanie od nowa w aplikacji.",
|
|
20
|
+
"error-expired": "To żądanie wygasło. Rozpocznij logowanie od nowa w aplikacji.",
|
|
21
|
+
"error-forbidden": "Ten rodzaj konta nie może zatwierdzać dostępu. Zaloguj się kontem, którego używasz w OwlMeans, i spróbuj ponownie.",
|
|
22
|
+
"switch-account": "Użyj innego konta"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Połącz urządzenie",
|
|
26
|
+
"description": "Wpisz kod wyświetlony przez aplikację, z którą się łączysz.",
|
|
27
|
+
"code-label": "Kod",
|
|
28
|
+
"continue": "Dalej"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "Jesteś zalogowany",
|
|
32
|
+
"message": "Możesz zamknąć to okno i kontynuować w aplikacji, która Cię tu skierowała.",
|
|
33
|
+
"device-message": "Możesz zamknąć to okno. Aplikacja wykryje to automatycznie."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n/ru.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Проверка сеанса…",
|
|
4
|
+
"loading": "Загрузка запроса…",
|
|
5
|
+
"framed": "Этот экран нельзя показать внутри другой страницы. Откройте его напрямую.",
|
|
6
|
+
"error": "Что-то пошло не так. Повторите попытку из приложения, которое направило вас сюда.",
|
|
7
|
+
"title": "{{client}} запрашивает доступ к вашей учётной записи",
|
|
8
|
+
"known": "Вы уже использовали это приложение раньше.",
|
|
9
|
+
"known-by-host": "Запрос от {{host}}.",
|
|
10
|
+
"unverified": "Это приложение зарегистрировалось самостоятельно и не было проверено.",
|
|
11
|
+
"device-code": "Код: {{code}}",
|
|
12
|
+
"device-name": "Устройство: {{name}}",
|
|
13
|
+
"redirect-host": "Вы вернётесь на {{host}}.",
|
|
14
|
+
"localhost-warning": "Это приложение зарегистрировало только адреса на вашем собственном компьютере. Подтверждайте это, только если вы сами только что начали вход.",
|
|
15
|
+
"scope": "Запрашиваемый доступ: {{scopes}}",
|
|
16
|
+
"approve": "Разрешить",
|
|
17
|
+
"deny": "Отклонить",
|
|
18
|
+
"error-missing": "Здесь нечего подтверждать. Начните вход заново из приложения.",
|
|
19
|
+
"error-not-found": "Этот запрос неизвестен или уже использован. Начните вход заново из приложения.",
|
|
20
|
+
"error-expired": "Срок действия этого запроса истёк. Начните вход заново из приложения.",
|
|
21
|
+
"error-forbidden": "Аккаунт этого типа не может подтверждать доступ. Войдите в аккаунт, который вы используете в OwlMeans, и повторите попытку.",
|
|
22
|
+
"switch-account": "Использовать другой аккаунт"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Подключить устройство",
|
|
26
|
+
"description": "Введите код, показанный приложением, к которому вы подключаетесь.",
|
|
27
|
+
"code-label": "Код",
|
|
28
|
+
"continue": "Продолжить"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "Вы вошли в систему",
|
|
32
|
+
"message": "Можно закрыть это окно и продолжить работу в приложении, которое направило вас сюда.",
|
|
33
|
+
"device-message": "Можно закрыть это окно. Приложение подхватит это автоматически."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n/uk.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"consent": {
|
|
3
|
+
"checking": "Перевірка сеансу…",
|
|
4
|
+
"loading": "Завантаження запиту…",
|
|
5
|
+
"framed": "Цей екран не можна показати всередині іншої сторінки. Відкрийте його напряму.",
|
|
6
|
+
"error": "Щось пішло не так. Спробуйте ще раз із застосунку, який направив вас сюди.",
|
|
7
|
+
"title": "{{client}} хоче отримати доступ до вашого облікового запису",
|
|
8
|
+
"known": "Ви вже користувалися цим застосунком раніше.",
|
|
9
|
+
"known-by-host": "Запит від {{host}}.",
|
|
10
|
+
"unverified": "Цей застосунок зареєструвався самостійно і не був перевірений.",
|
|
11
|
+
"device-code": "Код: {{code}}",
|
|
12
|
+
"device-name": "Пристрій: {{name}}",
|
|
13
|
+
"redirect-host": "Ви повернетеся до {{host}}.",
|
|
14
|
+
"localhost-warning": "Цей застосунок зареєстрував лише адреси на вашому власному комп'ютері. Підтверджуйте це, лише якщо ви щойно самі розпочали вхід.",
|
|
15
|
+
"scope": "Запитуваний доступ: {{scopes}}",
|
|
16
|
+
"approve": "Дозволити",
|
|
17
|
+
"deny": "Відхилити",
|
|
18
|
+
"error-missing": "Тут нічого підтверджувати. Почніть вхід заново із застосунку.",
|
|
19
|
+
"error-not-found": "Цей запит невідомий або вже використаний. Почніть вхід заново із застосунку.",
|
|
20
|
+
"error-expired": "Термін дії цього запиту минув. Почніть вхід заново із застосунку.",
|
|
21
|
+
"error-forbidden": "Обліковий запис цього типу не може підтверджувати доступ. Увійдіть в обліковий запис, який ви використовуєте в OwlMeans, і спробуйте ще раз.",
|
|
22
|
+
"switch-account": "Використати інший обліковий запис"
|
|
23
|
+
},
|
|
24
|
+
"device": {
|
|
25
|
+
"title": "Підключити пристрій",
|
|
26
|
+
"description": "Введіть код, показаний застосунком, до якого ви підключаєтеся.",
|
|
27
|
+
"code-label": "Код",
|
|
28
|
+
"continue": "Продовжити"
|
|
29
|
+
},
|
|
30
|
+
"done": {
|
|
31
|
+
"title": "Ви увійшли в систему",
|
|
32
|
+
"message": "Можете закрити це вікно й продовжити роботу в застосунку, який направив вас сюди.",
|
|
33
|
+
"device-message": "Можете закрити це вікно. Застосунок підхопить це автоматично."
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/i18n.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { addI18nLib } from '@owlmeans/i18n'
|
|
2
|
+
import { OAUTH_I18N } from './consts.js'
|
|
3
|
+
|
|
4
|
+
import en from './i18n/en.json' with { type: 'json' }
|
|
5
|
+
import pl from './i18n/pl.json' with { type: 'json' }
|
|
6
|
+
import ru from './i18n/ru.json' with { type: 'json' }
|
|
7
|
+
import be from './i18n/be.json' with { type: 'json' }
|
|
8
|
+
import uk from './i18n/uk.json' with { type: 'json' }
|
|
9
|
+
import es from './i18n/es.json' with { type: 'json' }
|
|
10
|
+
import de from './i18n/de.json' with { type: 'json' }
|
|
11
|
+
|
|
12
|
+
addI18nLib('en', OAUTH_I18N, en)
|
|
13
|
+
addI18nLib('pl', OAUTH_I18N, pl)
|
|
14
|
+
addI18nLib('ru', OAUTH_I18N, ru)
|
|
15
|
+
addI18nLib('be', OAUTH_I18N, be)
|
|
16
|
+
addI18nLib('uk', OAUTH_I18N, uk)
|
|
17
|
+
addI18nLib('es', OAUTH_I18N, es)
|
|
18
|
+
addI18nLib('de', OAUTH_I18N, de)
|