@oxyhq/core 12.0.0 → 12.1.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.
Files changed (67) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/i18n/locales/ar-SA.json +26 -2
  3. package/dist/cjs/i18n/locales/ca-ES.json +26 -2
  4. package/dist/cjs/i18n/locales/de-DE.json +26 -2
  5. package/dist/cjs/i18n/locales/en-US.json +25 -3
  6. package/dist/cjs/i18n/locales/es-ES.json +25 -3
  7. package/dist/cjs/i18n/locales/fr-FR.json +26 -2
  8. package/dist/cjs/i18n/locales/it-IT.json +26 -2
  9. package/dist/cjs/i18n/locales/ja-JP.json +26 -2
  10. package/dist/cjs/i18n/locales/ko-KR.json +26 -2
  11. package/dist/cjs/i18n/locales/locales/ar-SA.json +26 -2
  12. package/dist/cjs/i18n/locales/locales/ca-ES.json +26 -2
  13. package/dist/cjs/i18n/locales/locales/de-DE.json +26 -2
  14. package/dist/cjs/i18n/locales/locales/en-US.json +25 -3
  15. package/dist/cjs/i18n/locales/locales/es-ES.json +25 -3
  16. package/dist/cjs/i18n/locales/locales/fr-FR.json +26 -2
  17. package/dist/cjs/i18n/locales/locales/it-IT.json +26 -2
  18. package/dist/cjs/i18n/locales/locales/ja-JP.json +26 -2
  19. package/dist/cjs/i18n/locales/locales/ko-KR.json +26 -2
  20. package/dist/cjs/i18n/locales/locales/pt-PT.json +26 -2
  21. package/dist/cjs/i18n/locales/locales/zh-CN.json +26 -2
  22. package/dist/cjs/i18n/locales/pt-PT.json +26 -2
  23. package/dist/cjs/i18n/locales/zh-CN.json +26 -2
  24. package/dist/cjs/session/accountDialogController.js +83 -21
  25. package/dist/esm/.tsbuildinfo +1 -1
  26. package/dist/esm/i18n/locales/ar-SA.json +26 -2
  27. package/dist/esm/i18n/locales/ca-ES.json +26 -2
  28. package/dist/esm/i18n/locales/de-DE.json +26 -2
  29. package/dist/esm/i18n/locales/en-US.json +25 -3
  30. package/dist/esm/i18n/locales/es-ES.json +25 -3
  31. package/dist/esm/i18n/locales/fr-FR.json +26 -2
  32. package/dist/esm/i18n/locales/it-IT.json +26 -2
  33. package/dist/esm/i18n/locales/ja-JP.json +26 -2
  34. package/dist/esm/i18n/locales/ko-KR.json +26 -2
  35. package/dist/esm/i18n/locales/locales/ar-SA.json +26 -2
  36. package/dist/esm/i18n/locales/locales/ca-ES.json +26 -2
  37. package/dist/esm/i18n/locales/locales/de-DE.json +26 -2
  38. package/dist/esm/i18n/locales/locales/en-US.json +25 -3
  39. package/dist/esm/i18n/locales/locales/es-ES.json +25 -3
  40. package/dist/esm/i18n/locales/locales/fr-FR.json +26 -2
  41. package/dist/esm/i18n/locales/locales/it-IT.json +26 -2
  42. package/dist/esm/i18n/locales/locales/ja-JP.json +26 -2
  43. package/dist/esm/i18n/locales/locales/ko-KR.json +26 -2
  44. package/dist/esm/i18n/locales/locales/pt-PT.json +26 -2
  45. package/dist/esm/i18n/locales/locales/zh-CN.json +26 -2
  46. package/dist/esm/i18n/locales/pt-PT.json +26 -2
  47. package/dist/esm/i18n/locales/zh-CN.json +26 -2
  48. package/dist/esm/session/accountDialogController.js +83 -21
  49. package/dist/types/.tsbuildinfo +1 -1
  50. package/dist/types/index.d.ts +1 -1
  51. package/dist/types/session/accountDialogController.d.ts +81 -16
  52. package/package.json +1 -1
  53. package/src/i18n/locales/ar-SA.json +26 -2
  54. package/src/i18n/locales/ca-ES.json +26 -2
  55. package/src/i18n/locales/de-DE.json +26 -2
  56. package/src/i18n/locales/en-US.json +25 -3
  57. package/src/i18n/locales/es-ES.json +25 -3
  58. package/src/i18n/locales/fr-FR.json +26 -2
  59. package/src/i18n/locales/it-IT.json +26 -2
  60. package/src/i18n/locales/ja-JP.json +26 -2
  61. package/src/i18n/locales/ko-KR.json +26 -2
  62. package/src/i18n/locales/pt-PT.json +26 -2
  63. package/src/i18n/locales/zh-CN.json +26 -2
  64. package/src/index.ts +1 -0
  65. package/src/session/__tests__/accountDialogController.test.ts +79 -2
  66. package/src/session/__tests__/accountProjection.test.ts +30 -0
  67. package/src/session/accountDialogController.ts +128 -27
@@ -99,7 +99,7 @@ export { deviceStateToClientSessions, activeSessionIdOf, activeUserOf, accountId
99
99
  export { projectSwitchableAccounts, switchableAccountIds, } from './session/accountProjection';
100
100
  export type { SwitchableAccount, SwitchableAccountUser, ProjectSwitchableAccountsInput, } from './session/accountProjection';
101
101
  export { AccountDialogController, createAccountDialogController, } from './session/accountDialogController';
102
- export type { AccountDialogControllerOptions, AccountDialogSnapshot, AccountDialogView, SignInFlowPhase, SignInFlowState, } from './session/accountDialogController';
102
+ export type { AccountDialogControllerOptions, AccountDialogSnapshot, AccountDialogView, CommonsAvailability, SignInFlowPhase, SignInFlowState, } from './session/accountDialogController';
103
103
  export { createWebAuthStateStore, createNativeAuthStateStore, createMemoryAuthStateStore, AUTH_STATE_STORAGE_KEY, } from './session/authStateStore';
104
104
  export type { PersistedAuthState, AuthStateStore, NativeKeyValueStorage, } from './session/authStateStore';
105
105
  export { refreshPersistedSession, refreshDeviceSecretArm, createAuthRefreshHandler, installAuthRefreshHandler, startTokenRefreshScheduler, TOKEN_REFRESH_LEAD_MS, } from './session/refresh';
@@ -12,17 +12,23 @@
12
12
  * - the unified account list (via {@link projectSwitchableAccounts}), fetched
13
13
  * from `SessionClient` state ∪ `oxyServices.listAccounts()` and hydrated
14
14
  * with `oxyServices.getUsersByIds()`;
15
- * - the dialog `view` state machine (`accounts` | `signin` | `qr` | `add`);
15
+ * - the dialog `view` state machine (`accounts` | `signin` | `qr` | `add` |
16
+ * `signup`);
16
17
  * - `switchTo` (the uniform switch: `SessionClient.switchAccount` for an
17
18
  * account already on the device, `oxyServices.switchToAccount` to mint on
18
19
  * first entry into a graph account — reusing the existing SDK primitives, no
19
20
  * new switch path);
20
21
  * - the "Sign in with Oxy" device flow (same-device shared-keychain via
21
22
  * `oxyServices.signInWithSharedIdentity`, else the cross-device QR handoff
22
- * via `startCommonsSignIn` → poll → `claimSessionByToken`).
23
+ * via `startCommonsSignIn` → poll → `claimSessionByToken`);
24
+ * - `commonsAvailability` — whether Commons is installed on this device
25
+ * (native only, via the injected `canOpenApp` probe), so the QR view can
26
+ * offer a "Get Commons" fallback instead of a same-device dead end.
23
27
  *
24
28
  * Sign-in is passkey (WebAuthn) or the Commons QR / shared-keychain handoff —
25
- * password, social login, and 2FA were removed ecosystem-wide.
29
+ * password, social login, and 2FA were removed ecosystem-wide. Account
30
+ * creation (`signup` view) is the same two identity backends: a passkey
31
+ * ceremony on web, or a Commons-created identity.
26
32
  */
27
33
  import type { OxyServices } from '../OxyServices';
28
34
  import type { SessionLoginResponse, MinimalUserData } from '../models/session';
@@ -30,7 +36,19 @@ import type { SessionClient } from './SessionClient';
30
36
  import type { SocketIOFactory } from './socketLoader';
31
37
  import { type SwitchableAccount } from './accountProjection';
32
38
  /** The dialog's top-level view. */
33
- export type AccountDialogView = 'accounts' | 'signin' | 'qr' | 'add';
39
+ export type AccountDialogView = 'accounts' | 'signin' | 'qr' | 'add' | 'signup';
40
+ /**
41
+ * Whether Commons is installed on this device, as resolved by the injected
42
+ * `canOpenApp` probe:
43
+ * - `'unknown'` — not yet probed, OR no probe was injected (web — there is
44
+ * no API to ask a browser whether a custom URL scheme is registered, so
45
+ * this stays `'unknown'` forever there and the QR view renders
46
+ * unconditionally, no gating).
47
+ * - `'checking'` — the probe is in flight.
48
+ * - `'available'` / `'unavailable'` — the probe's resolved terminal answer
49
+ * (native only). A probe error is treated as `'unavailable'` (fail-closed).
50
+ */
51
+ export type CommonsAvailability = 'unknown' | 'checking' | 'available' | 'unavailable';
34
52
  /** Lifecycle phase of the "Sign in with Oxy" device flow. */
35
53
  export type SignInFlowPhase = 'idle' | 'starting' | 'waiting' | 'authorized' | 'error';
36
54
  /** State of the "Sign in with Oxy" (shared-key / QR) device flow. */
@@ -67,6 +85,8 @@ export interface AccountDialogSnapshot {
67
85
  switchingAccountId: string | null;
68
86
  /** The "Sign in with Oxy" device-flow state. */
69
87
  signIn: SignInFlowState;
88
+ /** Whether Commons is installed on this device. See {@link CommonsAvailability}. */
89
+ commonsAvailability: CommonsAvailability;
70
90
  }
71
91
  /** Construction options for {@link AccountDialogController}. */
72
92
  export interface AccountDialogControllerOptions {
@@ -84,15 +104,36 @@ export interface AccountDialogControllerOptions {
84
104
  /** Locale for display-name resolution. */
85
105
  locale?: string;
86
106
  /**
87
- * Commit a freshly-authorized session (device flow / shared identity / minted
88
- * graph switch) into the host's session set — device-first registration +
89
- * durable persist + profile hydration. The consumer supplies its provider's
90
- * commit path (`useOxy().handleWebSession` / the auth-sdk equivalent). Called
91
- * AFTER the SDK has planted the access token. When omitted the controller
92
- * falls back to `SessionClient.registerAndActivate` (registration + activation
93
- * only — no provider-side durable persist/hydration).
107
+ * Commit a freshly-authorized SIGN-IN session (device flow / shared identity)
108
+ * into the host's session set — device-first registration + durable persist +
109
+ * profile hydration. The consumer supplies its provider's commit path
110
+ * (`useOxy().handleWebSession` / the auth-sdk equivalent). Called AFTER the SDK
111
+ * has planted the access token. When omitted the controller falls back to
112
+ * `SessionClient.registerAndActivate` (registration + activation only — no
113
+ * provider-side durable persist/hydration).
114
+ *
115
+ * This is the SIGN-IN commit: on an official web origin it may run the
116
+ * cross-origin hub-sync (a full-page redirect to `auth.oxy.so/sync`) that
117
+ * bootstraps silent OAuth restore on OTHER origins. A first sign-in on a web
118
+ * origin legitimately needs that. An account SWITCH does NOT — see
119
+ * {@link commitSwitchedSession}.
94
120
  */
95
121
  commitSession?: (session: SessionLoginResponse) => Promise<void>;
122
+ /**
123
+ * Commit a minted graph SWITCH session into the host's session set — same
124
+ * device-first registration + durable persist + profile hydration as
125
+ * {@link commitSession}, but IN-PLACE: it must NOT trigger the cross-origin
126
+ * hub-sync redirect. Switching into an account you already operate reuses the
127
+ * device credential that was already hub-synced at the original sign-in, so
128
+ * re-syncing is redundant and a full-page redirect on switch is the exact
129
+ * regression this separation prevents. Cross-tab/app propagation of the switch
130
+ * still happens instantly via the server's device-scoped `session_state` /
131
+ * `session_accounts_changed` socket broadcast — no navigation required.
132
+ *
133
+ * When omitted the controller falls back to {@link commitSession} (if wired)
134
+ * and then to `SessionClient.registerAndActivate`.
135
+ */
136
+ commitSwitchedSession?: (session: SessionLoginResponse) => Promise<void>;
96
137
  /** Notified after a completed sign-in (bearer planted + session committed). */
97
138
  onSignedIn?: (user: MinimalUserData) => void;
98
139
  /**
@@ -133,6 +174,7 @@ export declare class AccountDialogController {
133
174
  private readonly clientId;
134
175
  private readonly locale?;
135
176
  private readonly commitSession?;
177
+ private readonly commitSwitchedSession?;
136
178
  private readonly onSignedIn?;
137
179
  private readonly pollIntervalMs;
138
180
  private readonly openUrl?;
@@ -146,6 +188,7 @@ export declare class AccountDialogController {
146
188
  private error;
147
189
  private switchingAccountId;
148
190
  private signIn;
191
+ private commonsAvailability;
149
192
  /** The secret device-flow token of the active QR flow (never surfaced). */
150
193
  private signInToken;
151
194
  private pollTimer;
@@ -214,6 +257,8 @@ export declare class AccountDialogController {
214
257
  close(): void;
215
258
  /** Switch to the "add account" view (the sign-in entry chooser). */
216
259
  add(): void;
260
+ /** Switch to the "create account" view (passkey / Commons signup entry). */
261
+ startSignup(): void;
217
262
  /**
218
263
  * Reload the account graph and per-account profiles, then re-project. Safe to
219
264
  * call repeatedly; concurrent calls are reconciled by a sequence guard so a
@@ -259,11 +304,25 @@ export declare class AccountDialogController {
259
304
  */
260
305
  showQr(): Promise<void>;
261
306
  /**
262
- * When a `canOpenApp` probe is injected and reports Commons installed, open the
263
- * approve deep link via the injected `openUrl`. Best-effort and non-blocking: a
264
- * probe/open failure is logged and swallowed the QR/polling fallback remains.
307
+ * Resolve whether Commons is installed on this device via the injected
308
+ * `canOpenApp` probe, updating {@link commonsAvailability} as durable,
309
+ * observable snapshot state. Native onlya no-op when `canOpenApp` was
310
+ * not injected (web), where `commonsAvailability` stays `'unknown'` forever
311
+ * and the QR view renders unconditionally (no gating).
312
+ *
313
+ * Replaces the old `maybeOpenCommons` fire-and-forget probe, whose outcome
314
+ * was only ever reflected by whether Commons silently opened — a probe
315
+ * failure or "not installed" answer was swallowed into a debug log with no
316
+ * way for the UI to react. `commonsAvailability` fixes that.
265
317
  */
266
- private maybeOpenCommons;
318
+ private resolveCommonsAvailability;
319
+ /**
320
+ * When Commons is confirmed installed, deep-link straight into its approve
321
+ * screen via the injected `openUrl` with the same `oxycommons://approve?...`
322
+ * payload the QR encodes. Best-effort and non-blocking — the QR/polling
323
+ * fallback stays live regardless of the outcome here.
324
+ */
325
+ private deepLinkIntoCommonsIfAvailable;
267
326
  /** Tear down the active sign-in device flow (timers + socket + token) and reset to idle. */
268
327
  cancelSignIn(): void;
269
328
  private scheduleNextPoll;
@@ -283,8 +342,14 @@ export declare class AccountDialogController {
283
342
  private completeSignIn;
284
343
  /**
285
344
  * Register a token-planted session into the device set. Prefers the
286
- * consumer's `commitSession` (durable persist + hydration); falls back to
345
+ * consumer's commit funnel (durable persist + hydration); falls back to
287
346
  * `SessionClient.registerAndActivate` (registration + activation only).
347
+ *
348
+ * A SWITCH (`opts.fromSwitch`) uses the IN-PLACE `commitSwitchedSession` funnel
349
+ * so it never runs the cross-origin hub-sync redirect; a SIGN-IN uses
350
+ * `commitSession` (which may hub-sync on an official web origin). When the
351
+ * switch funnel is not wired it falls back to the sign-in funnel, then to
352
+ * `registerAndActivate`.
288
353
  */
289
354
  private commitAuthorizedSession;
290
355
  private failSignIn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/core",
3
- "version": "12.0.0",
3
+ "version": "12.1.1",
4
4
  "description": "OxyHQ SDK Foundation — API client, authentication, cryptographic identity, and shared utilities",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -43,11 +43,25 @@
43
43
  "currentAccount": "الحالي",
44
44
  "or": "أو",
45
45
  "viewAllAccounts": "عرض {{count}} المزيد",
46
+ "createAccountLink": "جديد على Oxy؟ أنشئ حسابًا",
46
47
  "status": {
47
- "accountSwitched": "استخدام {{name}} الآن"
48
+ "accountSwitched": "استخدام {{name}} الآن",
49
+ "signingIn": "جارٍ تسجيل الدخول…"
48
50
  }
49
51
  },
50
52
  "signup": {
53
+ "commonsHeadline": "أنشئ هويتك في Commons",
54
+ "commonsExplainer": "‏Commons هي هوية Oxy الخاصة بك بحفظ ذاتي كامل — تطبيق واحد يعمل في كل مكان.",
55
+ "createInCommons": "أنشئ هويتك في Commons",
56
+ "passkeyAlternative": "لا تملك Commons؟ أنشئ مفتاح مرور على هذا الجهاز بدلاً من ذلك",
57
+ "createAccount": "إنشاء حساب",
58
+ "creating": "جارٍ الإنشاء…",
59
+ "usernamePlaceholder": "اختر اسم مستخدم",
60
+ "usernameChecking": "جارٍ التحقق…",
61
+ "usernameAvailable": "متاح",
62
+ "usernameTaken": "اسم المستخدم هذا مستخدم بالفعل",
63
+ "backToSignInLink": "لديك حساب بالفعل؟ سجّل الدخول",
64
+ "notAvailableHere": "‏إنشاء الحساب غير متاح في هذا التطبيق بعد — أنشئ هويتك باستخدام Commons، أو تفضّل بزيارة oxy.so للتسجيل باستخدام مفتاح مرور.",
51
65
  "welcome": {
52
66
  "title": "مرحبًا بك في Oxy!",
53
67
  "subtitle": "أنشئ حسابك في خطوات قليلة",
@@ -94,6 +108,15 @@
94
108
  "legalReminder": "بإنشاء حساب، فإنك توافق على شروط الخدمة وسياسة الخصوصية الخاصة بنا."
95
109
  }
96
110
  },
111
+ "accountSwitcher": {
112
+ "qrHeadline": "سجّل الدخول بهوية Oxy الخاصة بك",
113
+ "signInWithOxy": "تسجيل الدخول باستخدام Oxy",
114
+ "useIdentityOnDevice": "لا تملك Commons؟ استخدم مفتاح مرور على هذا الجهاز بدلاً من ذلك",
115
+ "passkeySigningIn": "جارٍ تسجيل الدخول…",
116
+ "getCommons": "احصل على Commons",
117
+ "commonsNotInstalled": "لا تملك Commons؟ احصل على التطبيق لتسجيل الدخول بمعرّف Oxy الخاص بك.",
118
+ "showQrAnyway": "لدي Commons على جهاز آخر"
119
+ },
97
120
  "common": {
98
121
  "actions": {
99
122
  "back": "رجوع",
@@ -105,7 +128,8 @@
105
128
  "verify": "التحقق",
106
129
  "resetPassword": "إعادة تعيين كلمة المرور",
107
130
  "signedOut": "تم تسجيل الخروج",
108
- "close": "إغلاق"
131
+ "close": "إغلاق",
132
+ "tryAgain": "حاول مرة أخرى"
109
133
  },
110
134
  "links": {
111
135
  "recoverAccount": "استعادة حسابك",
@@ -43,11 +43,25 @@
43
43
  "currentAccount": "Actual",
44
44
  "or": "o",
45
45
  "viewAllAccounts": "Veure {{count}} més",
46
+ "createAccountLink": "Ets nou a Oxy? Crea'n una",
46
47
  "status": {
47
- "accountSwitched": "Ara utilitzant {{name}}"
48
+ "accountSwitched": "Ara utilitzant {{name}}",
49
+ "signingIn": "Iniciant sessió…"
48
50
  }
49
51
  },
50
52
  "signup": {
53
+ "commonsHeadline": "Crea la teva identitat a Commons",
54
+ "commonsExplainer": "Commons és la teva identitat d'Oxy amb autocustòdia completa: una app que funciona a tot arreu.",
55
+ "createInCommons": "Crea la teva identitat a Commons",
56
+ "passkeyAlternative": "No tens Commons? Crea una clau d'accés en aquest dispositiu",
57
+ "createAccount": "Crear compte",
58
+ "creating": "Creant…",
59
+ "usernamePlaceholder": "Tria un nom d'usuari",
60
+ "usernameChecking": "Comprovant…",
61
+ "usernameAvailable": "Disponible",
62
+ "usernameTaken": "Aquest nom d'usuari ja està en ús",
63
+ "backToSignInLink": "Ja tens compte? Inicia sessió",
64
+ "notAvailableHere": "La creació de comptes encara no està disponible en aquesta app: crea la teva identitat amb Commons o visita oxy.so per registrar-te amb una clau d'accés.",
51
65
  "welcome": {
52
66
  "title": "Benvingut a Oxy!",
53
67
  "subtitle": "Crea el teu compte en pocs passos",
@@ -94,6 +108,15 @@
94
108
  "legalReminder": "En crear un compte, acceptes els nostres Termes de servei i Política de privacitat."
95
109
  }
96
110
  },
111
+ "accountSwitcher": {
112
+ "qrHeadline": "Inicia sessió amb la teva identitat d'Oxy",
113
+ "signInWithOxy": "Inicia sessió amb Oxy",
114
+ "useIdentityOnDevice": "No tens Commons? Fes servir una clau d'accés en aquest dispositiu",
115
+ "passkeySigningIn": "Iniciant sessió…",
116
+ "getCommons": "Descarrega Commons",
117
+ "commonsNotInstalled": "No tens Commons? Descarrega l'app per iniciar sessió amb el teu Oxy ID.",
118
+ "showQrAnyway": "Tinc Commons en un altre dispositiu"
119
+ },
97
120
  "common": {
98
121
  "actions": {
99
122
  "back": "Enrere",
@@ -105,7 +128,8 @@
105
128
  "verify": "Verificar",
106
129
  "resetPassword": "Restablir contrasenya",
107
130
  "signedOut": "Sessió tancada",
108
- "close": "Tanca"
131
+ "close": "Tanca",
132
+ "tryAgain": "Torna-ho a provar"
109
133
  },
110
134
  "links": {
111
135
  "recoverAccount": "Recuperar el teu compte",
@@ -43,11 +43,25 @@
43
43
  "currentAccount": "Aktuell",
44
44
  "or": "oder",
45
45
  "viewAllAccounts": "{{count}} weitere anzeigen",
46
+ "createAccountLink": "Neu bei Oxy? Konto erstellen",
46
47
  "status": {
47
- "accountSwitched": "Verwende jetzt {{name}}"
48
+ "accountSwitched": "Verwende jetzt {{name}}",
49
+ "signingIn": "Anmeldung läuft…"
48
50
  }
49
51
  },
50
52
  "signup": {
53
+ "commonsHeadline": "Erstellen Sie Ihre Identität in Commons",
54
+ "commonsExplainer": "Commons ist Ihre vollständig selbstverwaltete Oxy-Identität – eine App, überall einsetzbar.",
55
+ "createInCommons": "Erstellen Sie Ihre Identität in Commons",
56
+ "passkeyAlternative": "Kein Commons? Erstellen Sie stattdessen einen Passkey auf diesem Gerät",
57
+ "createAccount": "Konto erstellen",
58
+ "creating": "Wird erstellt…",
59
+ "usernamePlaceholder": "Benutzernamen wählen",
60
+ "usernameChecking": "Wird geprüft…",
61
+ "usernameAvailable": "Verfügbar",
62
+ "usernameTaken": "Dieser Benutzername ist bereits vergeben",
63
+ "backToSignInLink": "Sie haben bereits ein Konto? Anmelden",
64
+ "notAvailableHere": "Die Kontoerstellung ist in dieser App noch nicht verfügbar – erstellen Sie Ihre Identität mit Commons oder besuchen Sie oxy.so, um sich mit einem Passkey zu registrieren.",
51
65
  "welcome": {
52
66
  "title": "Willkommen bei Oxy!",
53
67
  "subtitle": "Erstellen Sie Ihr Konto in nur wenigen Schritten",
@@ -94,6 +108,15 @@
94
108
  "legalReminder": "Durch die Erstellung eines Kontos stimmen Sie unseren Nutzungsbedingungen und der Datenschutzrichtlinie zu."
95
109
  }
96
110
  },
111
+ "accountSwitcher": {
112
+ "qrHeadline": "Melden Sie sich mit Ihrer Oxy-Identität an",
113
+ "signInWithOxy": "Mit Oxy anmelden",
114
+ "useIdentityOnDevice": "Kein Commons? Verwenden Sie stattdessen einen Passkey auf diesem Gerät",
115
+ "passkeySigningIn": "Anmeldung läuft…",
116
+ "getCommons": "Commons herunterladen",
117
+ "commonsNotInstalled": "Kein Commons? Holen Sie sich die App, um sich mit Ihrer Oxy-ID anzumelden.",
118
+ "showQrAnyway": "Ich habe Commons auf einem anderen Gerät"
119
+ },
97
120
  "common": {
98
121
  "actions": {
99
122
  "back": "Zurück",
@@ -105,7 +128,8 @@
105
128
  "verify": "Überprüfen",
106
129
  "resetPassword": "Passwort zurücksetzen",
107
130
  "signedOut": "Abgemeldet",
108
- "close": "Schließen"
131
+ "close": "Schließen",
132
+ "tryAgain": "Erneut versuchen"
109
133
  },
110
134
  "links": {
111
135
  "recoverAccount": "Ihr Konto wiederherstellen",
@@ -50,11 +50,25 @@
50
50
  "currentAccount": "Current",
51
51
  "or": "or",
52
52
  "viewAllAccounts": "View {{count}} more",
53
+ "createAccountLink": "New to Oxy? Create one",
53
54
  "status": {
54
- "accountSwitched": "Now using {{name}}"
55
+ "accountSwitched": "Now using {{name}}",
56
+ "signingIn": "Signing in…"
55
57
  }
56
58
  },
57
59
  "signup": {
60
+ "commonsHeadline": "Create your identity in Commons",
61
+ "commonsExplainer": "Commons is your full self-custody Oxy identity — one app, works everywhere.",
62
+ "createInCommons": "Create your identity in Commons",
63
+ "passkeyAlternative": "No Commons? Create a passkey on this device instead",
64
+ "createAccount": "Create account",
65
+ "creating": "Creating…",
66
+ "usernamePlaceholder": "Choose a username",
67
+ "usernameChecking": "Checking…",
68
+ "usernameAvailable": "Available",
69
+ "usernameTaken": "This username is taken",
70
+ "backToSignInLink": "Already have an account? Sign in",
71
+ "notAvailableHere": "Account creation isn't available in this app yet — create your identity with Commons, or visit oxy.so to sign up with a passkey.",
58
72
  "welcome": {
59
73
  "title": "Welcome to Oxy!",
60
74
  "subtitle": "Let's create your account in just a few steps",
@@ -391,7 +405,14 @@
391
405
  "scanTitle": "Scan to sign in",
392
406
  "scanSubtitle": "Open the Oxy app on your phone and scan this code",
393
407
  "scanWithOxy": "Scan with the Oxy app to continue",
394
- "scanQr": "Scan QR code"
408
+ "scanQr": "Scan QR code",
409
+ "qrHeadline": "Sign in with your Oxy identity",
410
+ "signInWithOxy": "Sign in with Oxy",
411
+ "useIdentityOnDevice": "No Commons? Use a passkey on this device instead",
412
+ "passkeySigningIn": "Signing in…",
413
+ "getCommons": "Get Commons",
414
+ "commonsNotInstalled": "Don't have Commons? Get the app to sign in with your Oxy ID.",
415
+ "showQrAnyway": "I have Commons on another device"
395
416
  },
396
417
  "reputation": {
397
418
  "faq": {
@@ -1130,7 +1151,8 @@
1130
1151
  "resetPassword": "Reset Password",
1131
1152
  "signedOut": "Signed out",
1132
1153
  "close": "Close",
1133
- "delete": "Delete"
1154
+ "delete": "Delete",
1155
+ "tryAgain": "Try again"
1134
1156
  },
1135
1157
  "cancel": "Cancel",
1136
1158
  "revoke": "Revoke",
@@ -50,11 +50,25 @@
50
50
  "currentAccount": "Actual",
51
51
  "or": "o",
52
52
  "viewAllAccounts": "Ver {{count}} más",
53
+ "createAccountLink": "¿Nuevo en Oxy? Crea una cuenta",
53
54
  "status": {
54
- "accountSwitched": "Ahora usando {{name}}"
55
+ "accountSwitched": "Ahora usando {{name}}",
56
+ "signingIn": "Iniciando sesión…"
55
57
  }
56
58
  },
57
59
  "signup": {
60
+ "commonsHeadline": "Crea tu identidad en Commons",
61
+ "commonsExplainer": "Commons es tu identidad de Oxy con autocustodia completa: una app que funciona en todas partes.",
62
+ "createInCommons": "Crea tu identidad en Commons",
63
+ "passkeyAlternative": "¿No tienes Commons? Crea una clave de acceso en este dispositivo",
64
+ "createAccount": "Crear cuenta",
65
+ "creating": "Creando…",
66
+ "usernamePlaceholder": "Elige un usuario",
67
+ "usernameChecking": "Comprobando…",
68
+ "usernameAvailable": "Disponible",
69
+ "usernameTaken": "Este usuario ya está en uso",
70
+ "backToSignInLink": "¿Ya tienes cuenta? Inicia sesión",
71
+ "notAvailableHere": "La creación de cuentas aún no está disponible en esta app: crea tu identidad con Commons o visita oxy.so para registrarte con una clave de acceso.",
58
72
  "welcome": {
59
73
  "title": "¡Te damos la bienvenida a Oxy!",
60
74
  "subtitle": "Crea tu cuenta en pocos pasos",
@@ -303,7 +317,8 @@
303
317
  "resetPassword": "Restablecer contraseña",
304
318
  "signedOut": "Sesión cerrada",
305
319
  "close": "Cerrar",
306
- "delete": "Eliminar"
320
+ "delete": "Eliminar",
321
+ "tryAgain": "Reintentar"
307
322
  },
308
323
  "cancel": "Cancelar",
309
324
  "revoke": "Revocar",
@@ -588,7 +603,14 @@
588
603
  "scanTitle": "Escanea para iniciar sesión",
589
604
  "scanSubtitle": "Abre la app de Oxy en tu móvil y escanea este código",
590
605
  "scanWithOxy": "Escanea con la app de Oxy para continuar",
591
- "scanQr": "Escanear código QR"
606
+ "scanQr": "Escanear código QR",
607
+ "qrHeadline": "Inicia sesión con tu identidad de Oxy",
608
+ "signInWithOxy": "Inicia sesión con Oxy",
609
+ "useIdentityOnDevice": "¿No tienes Commons? Usa una clave de acceso en este dispositivo",
610
+ "passkeySigningIn": "Iniciando sesión…",
611
+ "getCommons": "Descargar Commons",
612
+ "commonsNotInstalled": "¿No tienes Commons? Descarga la app para iniciar sesión con tu Oxy ID.",
613
+ "showQrAnyway": "Tengo Commons en otro dispositivo"
592
614
  },
593
615
  "feedback": {
594
616
  "type": {
@@ -43,11 +43,25 @@
43
43
  "currentAccount": "Actuel",
44
44
  "or": "ou",
45
45
  "viewAllAccounts": "Voir {{count}} de plus",
46
+ "createAccountLink": "Nouveau sur Oxy ? Créez un compte",
46
47
  "status": {
47
- "accountSwitched": "Utilisation de {{name}}"
48
+ "accountSwitched": "Utilisation de {{name}}",
49
+ "signingIn": "Connexion…"
48
50
  }
49
51
  },
50
52
  "signup": {
53
+ "commonsHeadline": "Créez votre identité dans Commons",
54
+ "commonsExplainer": "Commons est votre identité Oxy en autoconservation complète : une seule app, partout.",
55
+ "createInCommons": "Créez votre identité dans Commons",
56
+ "passkeyAlternative": "Pas de Commons ? Créez une clé d'accès sur cet appareil",
57
+ "createAccount": "Créer un compte",
58
+ "creating": "Création…",
59
+ "usernamePlaceholder": "Choisissez un nom d'utilisateur",
60
+ "usernameChecking": "Vérification…",
61
+ "usernameAvailable": "Disponible",
62
+ "usernameTaken": "Ce nom d'utilisateur est déjà pris",
63
+ "backToSignInLink": "Vous avez déjà un compte ? Connectez-vous",
64
+ "notAvailableHere": "La création de compte n'est pas encore disponible dans cette app — créez votre identité avec Commons, ou rendez-vous sur oxy.so pour vous inscrire avec une clé d'accès.",
51
65
  "welcome": {
52
66
  "title": "Bienvenue sur Oxy !",
53
67
  "subtitle": "Créez votre compte en quelques étapes",
@@ -94,6 +108,15 @@
94
108
  "legalReminder": "En créant un compte, vous acceptez nos Conditions d'utilisation et notre Politique de confidentialité."
95
109
  }
96
110
  },
111
+ "accountSwitcher": {
112
+ "qrHeadline": "Connectez-vous avec votre identité Oxy",
113
+ "signInWithOxy": "Se connecter avec Oxy",
114
+ "useIdentityOnDevice": "Pas de Commons ? Utilisez une clé d'accès sur cet appareil",
115
+ "passkeySigningIn": "Connexion…",
116
+ "getCommons": "Obtenir Commons",
117
+ "commonsNotInstalled": "Pas de Commons ? Téléchargez l'app pour vous connecter avec votre Oxy ID.",
118
+ "showQrAnyway": "J'ai Commons sur un autre appareil"
119
+ },
97
120
  "common": {
98
121
  "actions": {
99
122
  "back": "Retour",
@@ -105,7 +128,8 @@
105
128
  "verify": "Vérifier",
106
129
  "resetPassword": "Réinitialiser le mot de passe",
107
130
  "signedOut": "Déconnecté",
108
- "close": "Fermer"
131
+ "close": "Fermer",
132
+ "tryAgain": "Réessayer"
109
133
  },
110
134
  "links": {
111
135
  "recoverAccount": "Récupérer votre compte",
@@ -43,11 +43,25 @@
43
43
  "currentAccount": "Attuale",
44
44
  "or": "o",
45
45
  "viewAllAccounts": "Visualizza {{count}} altri",
46
+ "createAccountLink": "Nuovo su Oxy? Creane uno",
46
47
  "status": {
47
- "accountSwitched": "Ora usando {{name}}"
48
+ "accountSwitched": "Ora usando {{name}}",
49
+ "signingIn": "Accesso in corso…"
48
50
  }
49
51
  },
50
52
  "signup": {
53
+ "commonsHeadline": "Crea la tua identità in Commons",
54
+ "commonsExplainer": "Commons è la tua identità Oxy in piena autocustodia: un'unica app, ovunque.",
55
+ "createInCommons": "Crea la tua identità in Commons",
56
+ "passkeyAlternative": "Non hai Commons? Crea una passkey su questo dispositivo",
57
+ "createAccount": "Crea account",
58
+ "creating": "Creazione…",
59
+ "usernamePlaceholder": "Scegli un nome utente",
60
+ "usernameChecking": "Verifica in corso…",
61
+ "usernameAvailable": "Disponibile",
62
+ "usernameTaken": "Questo nome utente è già in uso",
63
+ "backToSignInLink": "Hai già un account? Accedi",
64
+ "notAvailableHere": "La creazione dell'account non è ancora disponibile in questa app: crea la tua identità con Commons oppure visita oxy.so per registrarti con una passkey.",
51
65
  "welcome": {
52
66
  "title": "Benvenuto su Oxy!",
53
67
  "subtitle": "Crea il tuo account in pochi passaggi",
@@ -94,6 +108,15 @@
94
108
  "legalReminder": "Creando un account, accetti i nostri Termini di servizio e l'Informativa sulla privacy."
95
109
  }
96
110
  },
111
+ "accountSwitcher": {
112
+ "qrHeadline": "Accedi con la tua identità Oxy",
113
+ "signInWithOxy": "Accedi con Oxy",
114
+ "useIdentityOnDevice": "Non hai Commons? Usa una passkey su questo dispositivo",
115
+ "passkeySigningIn": "Accesso in corso…",
116
+ "getCommons": "Ottieni Commons",
117
+ "commonsNotInstalled": "Non hai Commons? Scarica l'app per accedere con il tuo Oxy ID.",
118
+ "showQrAnyway": "Ho Commons su un altro dispositivo"
119
+ },
97
120
  "common": {
98
121
  "actions": {
99
122
  "back": "Indietro",
@@ -105,7 +128,8 @@
105
128
  "verify": "Verifica",
106
129
  "resetPassword": "Reimposta password",
107
130
  "signedOut": "Disconnesso",
108
- "close": "Chiudi"
131
+ "close": "Chiudi",
132
+ "tryAgain": "Riprova"
109
133
  },
110
134
  "links": {
111
135
  "recoverAccount": "Recupera il tuo account",
@@ -43,11 +43,25 @@
43
43
  "currentAccount": "現在",
44
44
  "or": "または",
45
45
  "viewAllAccounts": "さらに{{count}}件を表示",
46
+ "createAccountLink": "Oxyは初めてですか?アカウントを作成",
46
47
  "status": {
47
- "accountSwitched": "{{name}}を使用中"
48
+ "accountSwitched": "{{name}}を使用中",
49
+ "signingIn": "サインインしています…"
48
50
  }
49
51
  },
50
52
  "signup": {
53
+ "commonsHeadline": "Commonsであなたのアイデンティティを作成",
54
+ "commonsExplainer": "Commonsは完全に自己管理できるあなたのOxy IDです。1つのアプリでどこでも使えます。",
55
+ "createInCommons": "Commonsであなたのアイデンティティを作成",
56
+ "passkeyAlternative": "Commonsがありませんか?このデバイスでパスキーを作成",
57
+ "createAccount": "アカウントを作成",
58
+ "creating": "作成しています…",
59
+ "usernamePlaceholder": "ユーザー名を選択",
60
+ "usernameChecking": "確認しています…",
61
+ "usernameAvailable": "利用可能",
62
+ "usernameTaken": "このユーザー名は既に使用されています",
63
+ "backToSignInLink": "すでにアカウントをお持ちですか?サインイン",
64
+ "notAvailableHere": "このアプリではまだアカウントを作成できません。Commonsでアイデンティティを作成するか、oxy.soにアクセスしてパスキーで登録してください。",
51
65
  "welcome": {
52
66
  "title": "Oxyへようこそ!",
53
67
  "subtitle": "数ステップでアカウントを作成",
@@ -94,6 +108,15 @@
94
108
  "legalReminder": "アカウントを作成することで、利用規約とプライバシーポリシーに同意したことになります。"
95
109
  }
96
110
  },
111
+ "accountSwitcher": {
112
+ "qrHeadline": "Oxy IDでサインイン",
113
+ "signInWithOxy": "Oxyでサインイン",
114
+ "useIdentityOnDevice": "Commonsがありませんか?このデバイスのパスキーを使用",
115
+ "passkeySigningIn": "サインインしています…",
116
+ "getCommons": "Commonsを入手",
117
+ "commonsNotInstalled": "Commonsがありませんか?アプリを入手してOxy IDでサインインしましょう。",
118
+ "showQrAnyway": "別のデバイスにCommonsがあります"
119
+ },
97
120
  "common": {
98
121
  "actions": {
99
122
  "back": "戻る",
@@ -105,7 +128,8 @@
105
128
  "verify": "確認",
106
129
  "resetPassword": "パスワードをリセット",
107
130
  "signedOut": "ログアウトしました",
108
- "close": "閉じる"
131
+ "close": "閉じる",
132
+ "tryAgain": "再試行"
109
133
  },
110
134
  "links": {
111
135
  "recoverAccount": "アカウントを回復",