@jimhoyd/urlcode-auth 0.1.0-alpha.1 → 0.1.0-alpha.2

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 (73) hide show
  1. package/dist/abuse-http.d.ts +8 -0
  2. package/dist/abuse-http.js +74 -0
  3. package/dist/abuse-store.d.ts +5 -0
  4. package/dist/abuse-store.js +40 -0
  5. package/dist/abuse.d.ts +27 -0
  6. package/dist/abuse.js +34 -0
  7. package/dist/admin-account-operations.d.ts +83 -0
  8. package/dist/admin-account-operations.js +50 -0
  9. package/dist/admin-account-store.d.ts +22 -0
  10. package/dist/admin-account-store.js +185 -0
  11. package/dist/auth-baseline.d.ts +30 -0
  12. package/dist/auth-baseline.js +153 -0
  13. package/dist/auth-core.d.ts +655 -0
  14. package/dist/auth-core.js +1066 -0
  15. package/dist/auth-flows.d.ts +30 -0
  16. package/dist/auth-flows.js +228 -0
  17. package/dist/auth-signup.d.ts +11 -0
  18. package/dist/auth-signup.js +145 -0
  19. package/dist/auth-store.d.ts +81 -0
  20. package/dist/auth-store.js +1601 -0
  21. package/dist/auth-templates.d.ts +13 -0
  22. package/dist/auth-templates.js +74 -0
  23. package/dist/auth-ui.d.ts +106 -0
  24. package/dist/auth-ui.js +205 -0
  25. package/dist/auth.d.ts +49 -0
  26. package/dist/auth.js +503 -0
  27. package/dist/backup.d.ts +18 -0
  28. package/dist/backup.js +121 -0
  29. package/dist/challenge-ui.d.ts +11 -0
  30. package/dist/challenge-ui.js +18 -0
  31. package/dist/challenge.d.ts +21 -0
  32. package/dist/challenge.js +65 -0
  33. package/dist/cli.d.ts +2 -0
  34. package/dist/cli.js +137 -0
  35. package/dist/deployment-check.d.ts +16 -0
  36. package/dist/deployment-check.js +41 -0
  37. package/dist/disposable-domain-data.d.ts +1 -0
  38. package/dist/disposable-domain-data.js +8886 -0
  39. package/dist/disposable-domains.d.ts +3 -0
  40. package/dist/disposable-domains.js +17 -0
  41. package/dist/email-copy.d.ts +114 -0
  42. package/dist/email-copy.js +58 -0
  43. package/dist/factor-recovery.d.ts +46 -0
  44. package/dist/factor-recovery.js +71 -0
  45. package/dist/index.d.ts +42 -0
  46. package/dist/index.js +18 -0
  47. package/dist/manual-recovery-store.d.ts +25 -0
  48. package/dist/manual-recovery-store.js +129 -0
  49. package/dist/manual-recovery.d.ts +87 -0
  50. package/dist/manual-recovery.js +35 -0
  51. package/dist/oidc.d.ts +31 -0
  52. package/dist/oidc.js +54 -0
  53. package/dist/passkeys.d.ts +24 -0
  54. package/dist/passkeys.js +29 -0
  55. package/dist/password-policy.d.ts +7 -0
  56. package/dist/password-policy.js +72 -0
  57. package/dist/presentation.d.ts +15 -0
  58. package/dist/presentation.js +458 -0
  59. package/dist/presets.d.ts +18 -0
  60. package/dist/presets.js +17 -0
  61. package/dist/providers.d.ts +13 -0
  62. package/dist/providers.js +15 -0
  63. package/dist/registration.d.ts +45 -0
  64. package/dist/registration.js +130 -0
  65. package/dist/scaffold.d.ts +44 -0
  66. package/dist/scaffold.js +212 -0
  67. package/dist/second-factor-flows.d.ts +28 -0
  68. package/dist/second-factor-flows.js +76 -0
  69. package/dist/senders.d.ts +86 -0
  70. package/dist/senders.js +153 -0
  71. package/dist/user-query.d.ts +28 -0
  72. package/dist/user-query.js +81 -0
  73. package/package.json +1 -1
@@ -0,0 +1,458 @@
1
+ import { createPresentation as createUiPresentation } from '@jimhoyd/urlcode-ui';
2
+ export const englishCatalogue = Object.freeze({
3
+ "users.exportAll": "Export all matching accounts as CSV",
4
+ "users.exportLimits": "Complete export: at most 5,000 accounts, 4 MiB and 5 seconds. Narrow filters if the limit is exceeded.",
5
+ "abuse.required": "Challenge required. Return to the form and try again.",
6
+ "abuse.title": "Verification required",
7
+ "abuse.retry": "Try again",
8
+ "adminOps.title": "Account administration",
9
+ "adminOps.bulkInfo": "Apply role assignment or resend verification to at most 50 accounts. Delivery must succeed before changes apply.",
10
+ "adminOps.ids": "Account IDs (comma-separated, maximum 50)",
11
+ "adminOps.actionLabel": "Action",
12
+ "adminOps.roles": "Roles (comma-separated)",
13
+ "adminOps.reason": "Reason",
14
+ "adminOps.confirm": "Type {value} to confirm",
15
+ "adminOps.bulkConfirm": "Type ACTION COUNT (for example ASSIGN-ROLES 2)",
16
+ "adminOps.apply": "Deliver notices and apply",
17
+ "adminOps.info": "Actions require fresh administrator authentication and a reason. Notification delivery occurs before changes apply.",
18
+ "adminOps.password": "Password configured",
19
+ "adminOps.totp": "Authenticator configured",
20
+ "adminOps.yes": "Yes",
21
+ "adminOps.no": "No",
22
+ "adminOps.passkey": "Passkey",
23
+ "adminOps.secondFactor": "Enrolled second factor",
24
+ "adminOps.factorCase": "Reset factors through a two-administrator case",
25
+ "adminOps.email": "Requested new email address",
26
+ "adminOps.completed": "Account administration completed",
27
+ "adminOps.affected": "{count} accounts updated",
28
+ "adminOps.action.verifyEmail": "Verify email by human review",
29
+ "adminOps.action.forcePasswordReset": "Invalidate password and send setup link",
30
+ "adminOps.action.scheduleDeletion": "Schedule deletion with cancellation notice",
31
+ "adminOps.action.cancelDeletion": "Cancel scheduled deletion",
32
+ "adminOps.action.removePasskey": "Remove passkey",
33
+ "adminOps.action.removeExternal": "Remove external sign-in method",
34
+ "adminOps.action.requestEmailChange": "Request email change with 24-hour delay",
35
+ "adminOps.action.assignRoles": "Assign roles",
36
+ "adminOps.action.resendVerification": "Resend verification",
37
+ "users.filter.storedMethod": "Stored credential method",
38
+ "users.filter.anyStoredMethod": "Any stored credential method",
39
+ "users.filter.search": "Search email, masked email, name or account ID",
40
+ "users.filter.anyStatus": "Any status",
41
+ "users.filter.active": "Active",
42
+ "users.filter.locked": "Locked",
43
+ "users.filter.pendingDelete": "Pending deletion",
44
+ "users.filter.external": "External identity",
45
+ "users.filter.method": "Sign-in method",
46
+ "users.filter.verification": "Email verification",
47
+ "users.filter.anyVerification": "Any verification",
48
+ "users.filter.verified": "Verified",
49
+ "users.filter.unverified": "Unverified",
50
+ "users.filter.locale": "Locale",
51
+ "users.filter.createdFrom": "Created from UTC",
52
+ "users.filter.createdTo": "Created to UTC",
53
+ "users.filter.seenFrom": "Last seen from UTC",
54
+ "users.filter.seenTo": "Last seen to UTC",
55
+ "users.filter.sort": "Sort by",
56
+ "users.filter.direction": "Direction",
57
+ "users.filter.ascending": "Ascending",
58
+ "users.filter.descending": "Descending",
59
+ "users.filter.displayName": "Display name",
60
+ "users.filter.lastSeen": "Last seen",
61
+ "users.filter.apply": "Apply filters",
62
+ "users.filter.activityCaveat": "Last seen uses retained device and session activity; it is not a complete activity history.",
63
+ "mfa.passkeySignIn": "Passkey sign-in",
64
+ "mfa.primaryOrder": "If your account uses a second factor, confirm it before choosing your sign-in passkey.",
65
+ "manualRecovery.title": "Manual account recovery",
66
+ "manualRecovery.restoreTitle": "Restore account access",
67
+ "manualRecovery.restoreIntro": "This link was approved by two administrators after a manual identity review. Choose a new password, then enroll a second factor. Existing sign-in methods and sessions will be revoked.",
68
+ "manualRecovery.replace": "Replace credentials and enroll a second factor",
69
+ "manualRecovery.intro": "Internal human review only. Do not enter passwords, tokens, identity document images or other unnecessary sensitive data. A distinct authorized administrator must independently review the evidence. References are plain text and are never fetched.",
70
+ "manualRecovery.account": "Account",
71
+ "manualRecovery.address": "Approved replacement address",
72
+ "manualRecovery.status": "Status",
73
+ "manualRecovery.evidence": "Evidence assessment",
74
+ "manualRecovery.reference": "Internal evidence reference",
75
+ "manualRecovery.none": "None",
76
+ "manualRecovery.note": "Internal case note",
77
+ "manualRecovery.addNote": "Add note",
78
+ "manualRecovery.closure": "Closure reason",
79
+ "manualRecovery.close": "Close without restoring access",
80
+ "manualRecovery.approval": "Independent approval reason",
81
+ "manualRecovery.confirmation": "Type RESTORE to confirm",
82
+ "manualRecovery.approve": "Approve and send restoration link",
83
+ "manualRecovery.accountId": "Account ID",
84
+ "manualRecovery.verifiedAddress": "Human-verified replacement email",
85
+ "manualRecovery.boundedEvidence": "Evidence assessment (maximum 2000 characters)",
86
+ "manualRecovery.reason": "Reason",
87
+ "manualRecovery.create": "Open case for independent review",
88
+ "manualRecovery.newPassword": "New password",
89
+ "manualRecovery.state.review": "Awaiting independent review",
90
+ "manualRecovery.state.delivery": "Awaiting delivery",
91
+ "manualRecovery.state.ready": "Ready for restoration",
92
+ "manualRecovery.state.redeemed": "Restored",
93
+ "manualRecovery.state.cancelled": "Cancelled",
94
+ "page.secondFactors": "Second factors",
95
+ "page.trustedDevices": "Remembered devices",
96
+ "mfa.distinctKey": "A second-factor passkey must be different from the passkey used for primary sign-in.",
97
+ "mfa.setupPasskey": "Set up a passkey second factor",
98
+ "mfa.enablePasskey": "Enable passkey second factor",
99
+ "mfa.disablePasskey": "Disable passkey second factor",
100
+ "mfa.invalidSetting": "Invalid factor setting",
101
+ "device.rememberExplanation": "Remembering a device requires a real second factor. Sensitive actions still require fresh verification.",
102
+ "device.label": "Device label",
103
+ "device.remember": "Remember this device",
104
+ "device.forget": "Forget device",
105
+ "recovery.title": "Recover your authenticator",
106
+ "recovery.intro": "This optional email recovery process requires proof from your verified email address, a 24-hour cancellation period, and enrollment of a new authenticator. Existing authentication methods remain unchanged until recovery completes.",
107
+ "recovery.send": "Send recovery instructions",
108
+ "recovery.cancelTitle": "Cancel authenticator recovery",
109
+ "recovery.cancel": "Cancel recovery",
110
+ "recovery.confirmTitle": "Confirm authenticator recovery",
111
+ "recovery.confirmInfo": "Confirming email possession starts a 24-hour waiting period. Return in this same browser after the waiting period. Completing recovery signs out all sessions and requires enrollment of a new authenticator before application access.",
112
+ "recovery.confirm": "Confirm email and show recovery time",
113
+ "recovery.complete": "Complete recovery after waiting period",
114
+ "recovery.waitTitle": "Authenticator recovery waiting period",
115
+ "recovery.waitInfo": "Recovery becomes available at {time}. Keep the email and return using this browser. You can cancel using the separate link in that email.",
116
+ "recovery.lost": "Lost your authenticator?",
117
+ "action.exportAudit": "Export audit range as JSON",
118
+ "mfa.usePasskey": "Use a passkey as your second factor",
119
+ "mfa.passkeyConfirmed": "Passkey confirmed. Continue signing in.",
120
+ "page.health": "Service health",
121
+ "health.component": "Component",
122
+ "health.status": "Status",
123
+ "health.updated": "Last checked",
124
+ "health.version": "Runtime version",
125
+ "health.routes": "Routes",
126
+ "health.unavailable": "No operator health integration is configured.",
127
+ "health.runtime": "Runtime",
128
+ "health.readiness": "Readiness",
129
+ "health.healthy": "Healthy",
130
+ "health.degraded": "Degraded",
131
+ "health.unavailableStatus": "Unavailable",
132
+ "health.unknown": "Unknown",
133
+ "health.sender": "Email delivery",
134
+ "health.provider": "Identity provider",
135
+ "health.alerts": "Alerts",
136
+ "signup.pending": "Your request has been received. If eligible, an administrator will review it before you can sign in.",
137
+ "signup.checkEmail": "Check your email for a signup code. Enter it to continue.",
138
+ "signup.createPasskey": "Create a passkey",
139
+ "signup.restart": "Start again",
140
+ "signup.browserRequired": "Signup browser binding required",
141
+ "signup.restartRequired": "Restart signup",
142
+ "signup.previousStep": "Complete the previous signup step",
143
+ "signup.verifiedRequired": "Complete verified signup first",
144
+ "notice.emailCodeEligible": "If this account is eligible, a sign-in code will be sent.",
145
+ "notice.passwordResetEligible": "If this account is eligible, a reset message will be sent.",
146
+ "notice.verificationEligible": "If this account is eligible, a verification message will be sent.",
147
+ "action.selectAccount": "Select {account}",
148
+ "error.httpInvalidRequestEncoding": "Invalid request encoding",
149
+ "error.httpInvalidJSONBody": "Invalid JSON body",
150
+ "error.httpExpectedAnObject": "Expected an object",
151
+ "error.httpUseJSONOrFormData": "Use JSON or form data",
152
+ "error.httpTooManyFields": "Too many fields",
153
+ "error.httpInvalidRequestField": "Invalid request field",
154
+ "error.httpInvalidCookies": "Invalid cookies",
155
+ "error.httpDuplicateSessionCookie": "Duplicate session cookie",
156
+ "error.httpInvalidSessionCookie": "Invalid session cookie",
157
+ "error.httpSameOriginRequestRequired": "Same-origin request required",
158
+ "error.httpInvalidCSRFToken": "Invalid CSRF token",
159
+ "error.httpExportExceedsOnePage": "Export exceeds one page",
160
+ "error.httpDuplicateFilter": "Duplicate filter",
161
+ "error.httpUseAUTCDateAndTimeEndingInZ": "Use a UTC date and time ending in Z",
162
+ "error.httpInvalidAuditTime": "Invalid audit time",
163
+ "error.httpInvalidTimeRange": "Invalid time range",
164
+ "error.httpInvalidEncoding": "Invalid encoding",
165
+ "error.httpInvalidJSON": "Invalid JSON",
166
+ "error.httpInvalidSelection": "Invalid selection",
167
+ "error.httpUseOneSelectionFormat": "Use one selection format",
168
+ "error.httpSelectBetweenOneAndFiftyDistinctAccounts": "Select between one and fifty distinct accounts",
169
+ "message.accountState": "Email: {email}. Authenticator: {authenticator}.",
170
+ "state.verified": "verified",
171
+ "state.unverified": "not yet verified",
172
+ "state.enabled": "enabled",
173
+ "state.disabled": "not enabled",
174
+ "message.sessionStarted": "Started {created}; expires {expires}",
175
+ "message.deletionGrace": "Deletion signs out all sessions immediately. A cancellation link will be emailed, valid for {days} days before permanent removal. Confirm your identity first.",
176
+ "message.adminTotals": "{users} accounts; {locked} locked; {pending} pending deletion; {sessions} sessions; {waitlist} waiting for approval.",
177
+ "message.sessionsOnPage": { "one": "{count} session on this page.", "other": "{count} sessions on this page." },
178
+ "message.bulkUpdated": { "one": "{count} account updated.", "other": "{count} accounts updated." },
179
+ "message.sessionAccountDetail": "Account {account}; started {created}; expires {expires}",
180
+ "message.caseSummary": "{action} for {account} \u2014 {status}",
181
+ "common.yes": "Yes",
182
+ "common.no": "No",
183
+ "provider.link": "Link {provider}",
184
+ "provider.signIn": "Sign in with {provider}",
185
+ "number.value": "{value}",
186
+ "error.serviceUnavailable": "Service unavailable",
187
+ "error.passkeyUnavailable": "Passkeys are unavailable in this browser. Use another sign-in method.",
188
+ "error.passkeyFailed": "Passkey request failed",
189
+ "error.passkeyCancelled": "Passkey ceremony cancelled",
190
+ "field.booleanHint": "true or false",
191
+ "message.acceptTerms": "I accept terms version {version}",
192
+ "error.invalidNumericMetadata": "Invalid numeric metadata",
193
+ "error.invalidBooleanMetadata": "Invalid boolean metadata",
194
+ "error.emailDeliveryIsNotConfigured": "Email delivery is not configured",
195
+ "error.verifyYourEmailBeforeEnrollingAnAuthenticator": "Verify your email before enrolling an authenticator",
196
+ "action.continue": "Continue",
197
+ "copy.emailSignIn": "Email sign in",
198
+ "error.invalidInvitation": "Invalid invitation",
199
+ "error.notFound": "Not found",
200
+ "copy.leaveEmpty": "Leave empty",
201
+ "error.invalidEmailFlow": "Invalid email flow",
202
+ "error.aSingleTokenIsRequired": "A single token is required",
203
+ "action.confirmOperation": "Confirm",
204
+ "copy.confirmOnlyAnAccountYouCreatedVerificationConfirmsThisEmailAddressItDoesNotSetOrResetAPassword": "Confirm only an account you created. Verification confirms this email address; it does not set or reset a password.",
205
+ "page.completeAccountEnrollment": "Complete account enrollment",
206
+ "copy.applicationAccessRemainsBlockedUntilAllRequiredEnrollmentStepsAreComplete": "Application access remains blocked until all required enrollment steps are complete.",
207
+ "copy.verifyYourEmailFirst": "Verify your email first",
208
+ "copy.emailDeliveryIsUnavailableContactTheSiteOperator": "Email delivery is unavailable. Contact the site operator.",
209
+ "copy.enrollAnAuthenticator": "Enroll an authenticator",
210
+ "copy.ifYourRecentSignInHasExpired": "if your recent sign-in has expired.",
211
+ "copy.youAreViewingThisAccountAsASupportAdministratorAccountSecurityChangesAreDisabledEndImpersonationToSignInAsYour": "You are viewing this account as a support administrator. Account security changes are disabled. End impersonation to sign in as yourself.",
212
+ "action.requestEmailChange24HourCoolingPeriod": "Request email change (24-hour cooling period)",
213
+ "action.revokeThisSession": "Revoke this session",
214
+ "page.signInMethods": "Sign-in methods",
215
+ "copy.passkeys": "Passkeys",
216
+ "action.removePasskey": "Remove passkey",
217
+ "copy.linkedProviders": "Linked providers",
218
+ "action.unlinkProvider": "Unlink provider",
219
+ "copy.theLastSignInMethodCannotBeRemoved": "The last sign-in method cannot be removed.",
220
+ "error.enterAnEmailAddress": "Enter an email address",
221
+ "error.securityChangesAreDisabledDuringImpersonation": "Security changes are disabled during impersonation",
222
+ "error.emailDeliveryRequired": "Email delivery required",
223
+ "error.emailDeliveryFailedChangeCancelled": "Email delivery failed; change cancelled",
224
+ "error.emailDeliveryIsRequiredForDeletionRecovery": "Email delivery is required for deletion recovery",
225
+ "error.deletionConfirmationRequired": "Deletion confirmation required",
226
+ "copy.addThisKeyToYourAuthenticator": "Add this key to your authenticator:",
227
+ "copy.storeTheseCodesSecurelyEachCanBeUsedOnce": "Store these codes securely. Each can be used once.",
228
+ "copy.continueToYourAccount": "Continue to your account",
229
+ "error.invalidAuthenticationFlow": "Invalid authentication flow",
230
+ "error.authenticationFlowBelongsToAnotherBrowser": "Authentication flow belongs to another browser",
231
+ "error.requestBodyTooLarge": "Request body too large",
232
+ "error.jSONRequired": "JSON required",
233
+ "error.invalidAuthenticationPayload": "Invalid authentication payload",
234
+ "error.confirmYourIdentityFirst": "Confirm your identity first",
235
+ "error.pOSTRequired": "POST required",
236
+ "error.invalidProviderResponse": "Invalid provider response",
237
+ "error.gETOrPOSTRequired": "GET or POST required",
238
+ "error.formCallbackRequired": "Form callback required",
239
+ "error.invalidProviderState": "Invalid provider state",
240
+ "error.providerFlowMismatch": "Provider flow mismatch",
241
+ "error.invalidIdentityIssuer": "Invalid identity issuer",
242
+ "error.anExistingLinkedAccountIsRequired": "An existing linked account is required",
243
+ "page.completeYourAccount": "Complete your account",
244
+ "error.identityChangedDuringSignIn": "Identity changed during sign in",
245
+ "error.invalidEnrollment": "Invalid enrollment",
246
+ "error.identityChangedDuringEnrollment": "Identity changed during enrollment",
247
+ "error.unknownAuthenticationField": "Unknown authentication field",
248
+ "error.browserFlowRequired": "Browser flow required",
249
+ "error.flowIDRequired": "Flow ID required",
250
+ "error.invalidChallenge": "Invalid challenge",
251
+ "error.invalidCredential": "Invalid credential",
252
+ "error.accountChangedDuringCeremony": "Account changed during ceremony",
253
+ "error.passkeyAuthenticationFailed": "Passkey authentication failed",
254
+ "error.passkeyBelongsToAnotherAccount": "Passkey belongs to another account",
255
+ "error.invalidSecondFactor": "Invalid second factor",
256
+ "action.startTenMinuteSupportImpersonation": "Start ten-minute support impersonation",
257
+ "copy.selectASectionOnlyPermittedOperationsAreShownConfigurationRemainsInVersionControlledProjectFiles": "Select a section. Only permitted operations are shown. Configuration remains in version-controlled project files.",
258
+ "copy.authenticationActivityLast30UTCDays": "Authentication activity: last 30 UTC days",
259
+ "copy.recordedAccountCreationsSuccessfulSignInsAndFailedSignInsTheseFiguresDescribeAuthenticationActivityDeploymentH": "Recorded account creations, successful sign-ins and failed sign-ins. These figures describe authentication activity; deployment health is not measured here.",
260
+ "copy.dailyAuthenticationCounts": "Daily authentication counts",
261
+ "copy.uTCDay": "UTC day",
262
+ "copy.signUps": "Sign-ups",
263
+ "copy.signIns": "Sign-ins",
264
+ "copy.failedSignIns": "Failed sign-ins",
265
+ "copy.authenticationMethodsOverTheSame30Days": "Authentication methods over the same 30 days",
266
+ "copy.method": "Method",
267
+ "copy.recentEvents": "Recent events",
268
+ "page.supportCases": "Support cases",
269
+ "action.closeWithoutApplying": "Close without applying",
270
+ "action.approveAndApply": "Approve and apply",
271
+ "action.createCaseForASecondAdministrator": "Create case for a second administrator",
272
+ "action.approveAccount": "Approve account",
273
+ "action.sendInvitation": "Send invitation",
274
+ "error.accountNotFound": "Account not found",
275
+ "page.accountDetails": "Account details",
276
+ "copy.email": "Email",
277
+ "copy.status": "Status",
278
+ "copy.emailVerified": "Email verified",
279
+ "copy.authenticatorEnabled": "Authenticator enabled",
280
+ "copy.created": "Created",
281
+ "copy.language": "Language",
282
+ "copy.termsVersion": "Terms version",
283
+ "copy.recentAccountActivity": "Recent account activity",
284
+ "copy.viewAccountAudit": "View account audit",
285
+ "action.createAccountAndSendSetupLink": "Create account and send setup link",
286
+ "copy.filterUsers": "Filter users",
287
+ "action.exportThisPageAsCSV": "Export this page as CSV",
288
+ "copy.exportThisFilteredPageOnlyAtMost50AccountsEmailAddressesStayMasked": "Export this filtered page only, at most 50 accounts. Email addresses stay masked.",
289
+ "copy.bulkAction": "Bulk action",
290
+ "copy.lock": "Lock",
291
+ "copy.unlock": "Unlock",
292
+ "field.typeLOCKUNLOCKOrREVOKESESSIONSFollowedByASpaceAndTheSelectedCount": "Type LOCK, UNLOCK or REVOKE-SESSIONS followed by a space and the selected count",
293
+ "copy.selectAccountsInTheTableAllSelectedAccountsMustBePermittedOtherwiseNoneAreChanged": "Select accounts in the table. All selected accounts must be permitted; otherwise none are changed.",
294
+ "copy.applyBulkAction": "Apply bulk action",
295
+ "copy.accountsEmailAddressesMasked": "Accounts (email addresses masked)",
296
+ "copy.select": "Select",
297
+ "copy.actions": "Actions",
298
+ "copy.roleDefinitionsAreReadOnlyHere": "Role definitions are read-only here.",
299
+ "action.revokeAllSessions": "Revoke all sessions",
300
+ "field.fromUTC20260101T0000Z": "From UTC (2026-01-01T00:00Z)",
301
+ "field.toUTC20260102T0000Z": "To UTC (2026-01-02T00:00Z)",
302
+ "copy.filterAudit": "Filter audit",
303
+ "copy.recentSecurityEvents": "Recent security events",
304
+ "copy.time": "Time",
305
+ "copy.action": "Action",
306
+ "copy.actor": "Actor",
307
+ "copy.subject": "Subject",
308
+ "error.aReasonIsRequired": "A reason is required",
309
+ "error.confirmYourIdentityBeforeThisAction": "Confirm your identity before this action",
310
+ "error.invalidBulkAction": "Invalid bulk action",
311
+ "error.typedConfirmationMustMatchTheActionAndSelectedCount": "Typed confirmation must match the action and selected count",
312
+ "page.bulkUpdateCompleted": "Bulk update completed",
313
+ "error.setupDeliveryUnavailable": "Setup delivery unavailable",
314
+ "error.invalidCaseAction": "Invalid case action",
315
+ "error.impersonationNotificationIsRequired": "Impersonation notification is required",
316
+ "error.invitationDeliveryUnavailable": "Invitation delivery unavailable",
317
+ "error.invalidStatus": "Invalid status",
318
+ "field.currentPassword": "Current password",
319
+ "field.currentPasswordOptional": "Current password (if configured)",
320
+ "field.displayName": "Display name",
321
+ "field.invitation": "Invitation token",
322
+ "field.newEmail": "New email address",
323
+ "field.passwordMinimum": "Password (at least 15 characters)",
324
+ "field.passwordOptional": "Password (if configured)",
325
+ "field.locale": "Preferred language",
326
+ "field.recoveryAlternative": "Recovery code (instead of authenticator code)",
327
+ "field.totpOptional": "Authenticator code (if enabled)",
328
+ "field.emailCode": "Six-digit email code",
329
+ "field.deleteConfirmation": "Type DELETE to confirm",
330
+ "field.accountId": "Account ID",
331
+ "field.caseAction": "Action: reset-factors, lock, unlock or roles",
332
+ "field.approvalReason": "Approval reason",
333
+ "field.caseNote": "Case note",
334
+ "field.closureReason": "Closure reason",
335
+ "field.emailFilter": "Email contains",
336
+ "field.role": "Role name",
337
+ "field.roles": "Role names separated by commas",
338
+ "field.caseRoles": "Roles (for roles action)",
339
+ "field.status": "Status: active, locked or pending-delete",
340
+ "page.passwordReset": "Reset password",
341
+ "page.newPassword": "Choose a new password",
342
+ "page.emailVerification": "Verify email",
343
+ "page.emailCode": "Sign in by email",
344
+ "page.enterEmailCode": "Enter your email code",
345
+ "page.deletionCancellation": "Cancel account deletion",
346
+ "page.totpSetup": "Set up authenticator",
347
+ "page.recoveryCodes": "Save your recovery codes",
348
+ "page.supportImpersonation": "Support impersonation",
349
+ "page.registrationRequest": "Request an account",
350
+ "page.verifyEmailChange": "Verify email change",
351
+ "page.cancelEmailChange": "Cancel email change",
352
+ "page.secondFactor": "Confirm second factor",
353
+ "page.users": "Users",
354
+ "page.roles": "Roles",
355
+ "page.audit": "Audit",
356
+ "page.cases": "Cases",
357
+ "page.registrations": "Registration requests",
358
+ "page.updateCompleted": "Update completed",
359
+ "page.completeRegistration": "Complete registration",
360
+ "action.sendEmailCode": "Send sign-in code",
361
+ "action.keepAccount": "Keep my account",
362
+ "action.sendVerification": "Send verification email",
363
+ "action.setupTotp": "Set up authenticator",
364
+ "action.disableTotp": "Disable authenticator",
365
+ "action.confirmTotp": "Confirm authenticator",
366
+ "action.updateProfile": "Update profile",
367
+ "action.changePassword": "Change password and sign out all sessions",
368
+ "action.exportData": "Export account data",
369
+ "action.scheduleDeletion": "Schedule account deletion",
370
+ "action.signOutAll": "Sign out all sessions",
371
+ "action.endImpersonation": "End impersonation",
372
+ "action.requestAccount": "Request account",
373
+ "action.completeSignIn": "Complete sign in",
374
+ "action.sendReset": "Send reset link",
375
+ "action.findSessions": "Find sessions",
376
+ "action.revokeSessions": "Revoke sessions",
377
+ "action.assignRoles": "Assign roles",
378
+ "action.lock": "Lock account",
379
+ "action.unlock": "Unlock account",
380
+ "action.addPasskey": "Add a passkey",
381
+ "action.signInPasskey": "Sign in with a passkey",
382
+ "action.changeEmail": "Change email address",
383
+ "action.approveCase": "Approve case",
384
+ "action.closeCase": "Close case",
385
+ "action.addNote": "Add note",
386
+ "action.search": "Search",
387
+ "nav.overview": "Overview",
388
+ "nav.users": "Users",
389
+ "nav.roles": "Roles",
390
+ "nav.audit": "Audit",
391
+ "nav.cases": "Cases",
392
+ "nav.registration": "Registration",
393
+ "nav.forgotPassword": "Forgot password",
394
+ "message.operationCompleted": "The operation completed.",
395
+ "message.registrationReceived": "Registration request received.",
396
+ "message.noSession": "Sign in required",
397
+ "message.permissionRequired": "Permission required",
398
+ "page.requestCancelled": "Request cancelled",
399
+ "ux.requestCancelled": "Your request has been cancelled.",
400
+ "page.emailVerified": "Email verified",
401
+ "ux.emailVerified": "Your email address has been verified.",
402
+ "ux.emailChangeRequested": "Check your new email for confirmation instructions. The change can only finish after the 24-hour cooling period.",
403
+ "page.sessionSignedOut": "Session signed out",
404
+ "ux.sessionSignedOut": "The selected session has been signed out.",
405
+ "page.deletionScheduled": "Account deletion scheduled",
406
+ "ux.deletionScheduled": "Your account deletion is scheduled. Check your email for cancellation instructions if you change your mind.",
407
+ "ux.disableAuthenticator": "Disable authenticator",
408
+ "ux.signupProgress": "Step {current} of {total}",
409
+ "ux.credentialChoiceShort": "Use a password or passkey.",
410
+ "ux.passwordHintShort": "At least 15 characters. Use a unique password.",
411
+ "ux.waitlistShort": "An administrator must approve your request.",
412
+ "ux.signInFailed": "Sign-in failed. Check your password and any required verification code.",
413
+ "ux.tryAgain": "Try again",
414
+ "ux.twoStep": "Two-step verification (if enabled)",
415
+ "ux.twoStepHelp": "If your account uses two-step verification, enter an authenticator code or a recovery code. Otherwise, leave this section closed.",
416
+ "ux.change": "Change",
417
+ "ux.passwordIntro": "Enter the password for this account.",
418
+ "ux.resetIntro": "Enter your account email. If it is eligible, we will send a password reset link.",
419
+ "ux.resetSent": "If this account is eligible, a reset message will be sent. Check your inbox and spam folder, then follow the link to choose a new password.",
420
+ "ux.backSignIn": "Back to sign in",
421
+ "ux.passwordUpdated": "Your password has been updated. Sign in with your new password.",
422
+ "page.enterPassword": "Enter your password",
423
+ "page.checkEmail": "Check your email",
424
+ "page.passwordUpdated": "Password updated",
425
+ "page.secureAccount": "Secure your account",
426
+ "page.createPassword": "Create a password",
427
+ "page.yourDetails": "Your details",
428
+ "ux.setupProgress": "Account setup progress",
429
+ "ux.alreadyAccount": "Already have an account?",
430
+ "ux.signupVerifiedIntro": "Start with your email. We will verify it before you choose how to sign in.",
431
+ "ux.signupIntro": "Start with your email, then choose how to sign in.",
432
+ "ux.signupCheckEmail": "If this address is eligible, a signup code has been sent. Enter the code to continue.",
433
+ "ux.signupCredentialChoice": "Choose a password or create a passkey. You only need one sign-in method to continue.",
434
+ "ux.signupPasswordIntro": "Choose a password with at least 15 characters. A long, unique passphrase works well.",
435
+ "ux.passwordRules": "Use at least 15 characters. Avoid passwords you use elsewhere.",
436
+ "ux.signupWaitlistIntro": "Review your details and submit your request. An administrator must approve it before you can sign in.",
437
+ "ux.signupProfileIntro": "Add your details and review any required terms to finish creating your account.",
438
+ "ux.signupRestartHelp": "Starting again clears this signup progress. No account is created until you finish.",
439
+ "ux.factorRecoverySent": "If this account is eligible, recovery instructions will be sent. Continue in this browser.",
440
+ "page.recoveryCancelled": "Recovery cancelled",
441
+ "ux.recoveryCancelled": "This recovery request has been cancelled. Your existing sign-in methods are unchanged.",
442
+ 'copy.signInIntro': 'Enter your email to continue to your account.', 'action.differentEmail': 'Use a different email address',
443
+ 'section.profile': 'Profile', 'section.authenticator': 'Authenticator', 'section.accountData': 'Account data', 'section.deleteAccount': 'Delete account',
444
+ 'page.signIn': 'Sign in', 'page.register': 'Create account', 'page.account': 'Your account', 'page.sessions': 'Your sessions', 'page.stepUp': 'Confirm your identity', 'page.error': 'Request could not be completed', 'page.admin': 'Administration',
445
+ 'field.email': 'Email address', 'field.password': 'Password', 'field.newPassword': 'New password', 'field.reason': 'Reason', 'field.totp': 'Authenticator code', 'field.recoveryCode': 'Recovery code',
446
+ 'action.signIn': 'Sign in', 'action.register': 'Create account', 'action.signOut': 'Sign out', 'action.confirm': 'Confirm identity', 'action.resetPassword': 'Reset password', 'action.save': 'Save changes', 'action.next': 'Next page',
447
+ 'nav.account': 'Account', 'nav.sessions': 'Sessions', 'nav.security': 'Security', 'nav.admin': 'Administration', 'nav.skip': 'Skip to content',
448
+ 'message.sessionCount': Object.freeze({ one: '{count} session', other: '{count} sessions' }),
449
+ 'message.accessDenied': 'Access denied', 'message.requestFailed': 'Request could not be completed', 'message.csrfRequired': 'Reload the page before submitting again.',
450
+ });
451
+ /** Legacy auth theme names are adapted here; the shared UI package knows no auth fields. */
452
+ export function createPresentation(options = {}) {
453
+ const theme = options.theme;
454
+ if (theme !== undefined && (!theme || typeof theme !== 'object' || Array.isArray(theme) || Object.keys(theme).length > 10))
455
+ throw new Error('Invalid presentation theme');
456
+ const translated = theme ? Object.fromEntries(Object.entries(theme).map(([name, value]) => [name.startsWith('--auth-') ? name.replace('--auth-', '--ui-') : name, value])) : undefined;
457
+ return createUiPresentation({ ...options, ...(translated ? { theme: translated } : {}), defaults: englishCatalogue });
458
+ }
@@ -0,0 +1,18 @@
1
+ import type { AuthOptions } from './auth-core.ts';
2
+ import type { AuthExtensionOptions } from './auth.ts';
3
+ import type { EmailSender } from './senders.ts';
4
+ export interface AuthPresetOptions {
5
+ preset?: 'standard' | 'hardened';
6
+ origin: string;
7
+ rpName: string;
8
+ sender?: EmailSender;
9
+ checkPassword?: AuthOptions['checkPassword'];
10
+ }
11
+ export interface AuthPreset {
12
+ service: Pick<AuthOptions, 'sessionTtlMs' | 'sessionIdleMs' | 'requireEmailVerification' | 'requireMfa' | 'deletionGraceMs' | 'checkPassword'>;
13
+ extension: Pick<AuthExtensionOptions, 'passkeys' | 'sendToken' | 'sendEmailCode' | 'sendSignupCode' | 'sendFactorRecovery' | 'sendNotice'>;
14
+ notices: readonly string[];
15
+ }
16
+ /** Operator defaults, not project capabilities. Spread these defaults before explicit configuration.
17
+ * Hardened requires actual email and password-screening adapters and restricted enrollment. */
18
+ export declare function createAuthPreset(options: AuthPresetOptions): AuthPreset;
@@ -0,0 +1,17 @@
1
+ import { createPasskeyProvider } from "./passkeys.js";
2
+ /** Operator defaults, not project capabilities. Spread these defaults before explicit configuration.
3
+ * Hardened requires actual email and password-screening adapters and restricted enrollment. */
4
+ export function createAuthPreset(options) {
5
+ const preset = options.preset ?? 'standard';
6
+ if (preset !== 'standard' && preset !== 'hardened')
7
+ throw new Error('Unknown auth preset');
8
+ const hardened = preset === 'hardened';
9
+ if (options.sender && (typeof options.sender !== 'function' || typeof options.sender.notify !== 'function' || typeof options.sender.sendEmailCode !== 'function' || typeof options.sender.sendSignupCode !== 'function' || typeof options.sender.sendFactorRecovery !== 'function'))
10
+ throw new Error('Invalid email sender');
11
+ if (hardened && (!options.sender || typeof options.checkPassword !== 'function'))
12
+ throw new Error('Hardened auth requires email delivery and password breach screening');
13
+ const passkeys = createPasskeyProvider({ origin: options.origin, rpId: new URL(options.origin).hostname, rpName: options.rpName });
14
+ const service = { sessionTtlMs: hardened ? 8 * 60 * 60 * 1000 : 24 * 60 * 60 * 1000, sessionIdleMs: hardened ? 15 * 60 * 1000 : 30 * 60 * 1000, requireEmailVerification: hardened, requireMfa: hardened, deletionGraceMs: (hardened ? 30 : 7) * 86400000, ...(options.checkPassword ? { checkPassword: options.checkPassword } : {}) };
15
+ const sender = options.sender;
16
+ return { service: Object.freeze(service), extension: Object.freeze({ passkeys, ...(sender ? { sendToken: sender, sendFactorRecovery: sender.sendFactorRecovery.bind(sender), sendSignupCode: sender.sendSignupCode.bind(sender), sendEmailCode: sender.sendEmailCode.bind(sender), sendNotice: sender.notify.bind(sender) } : {}) }), notices: Object.freeze(sender ? [] : ['Email verification, recovery and notices are unavailable until an operator sender is configured.']) };
17
+ }
@@ -0,0 +1,13 @@
1
+ import type { OidcProvider, OidcProviderOptions } from './oidc.ts';
2
+ export type GoogleProviderOptions = Pick<OidcProviderOptions, 'clientId' | 'clientSecret' | 'redirectUri' | 'fetch'>;
3
+ export declare function createGoogleProvider(options: GoogleProviderOptions): Promise<OidcProvider>;
4
+ export interface AppleProviderOptions {
5
+ teamId: string;
6
+ keyId: string;
7
+ clientId: string;
8
+ privateKey: string;
9
+ redirectUri: string;
10
+ fetch?: typeof globalThis.fetch;
11
+ }
12
+ /** Operator-owned signing key; no Apple key or client secret enters project YAML. */
13
+ export declare function createAppleProvider(options: AppleProviderOptions): Promise<OidcProvider>;
@@ -0,0 +1,15 @@
1
+ import { SignJWT, importPKCS8 } from 'jose';
2
+ import { createOidcProvider } from "./oidc.js";
3
+ export function createGoogleProvider(options) { return createOidcProvider({ ...options, issuer: 'https://accounts.google.com' }); }
4
+ /** Operator-owned signing key; no Apple key or client secret enters project YAML. */
5
+ export async function createAppleProvider(options) {
6
+ if (!/^[A-Z0-9]{10}$/.test(options.teamId) || !/^[A-Z0-9]{10}$/.test(options.keyId) || !/^[A-Za-z0-9.-]{1,255}$/.test(options.clientId) || options.privateKey.length > 16384)
7
+ throw new Error('Invalid Apple operator configuration');
8
+ const key = await importPKCS8(options.privateKey, 'ES256');
9
+ // A fresh five-minute credential for each protocol exchange avoids long-lived
10
+ // client-secret expiry silently disabling a running deployment.
11
+ const client = async () => createOidcProvider({ issuer: 'https://appleid.apple.com', clientId: options.clientId, clientSecret: await new SignJWT({}).setProtectedHeader({ alg: 'ES256', kid: options.keyId }).setIssuer(options.teamId).setSubject(options.clientId).setAudience('https://appleid.apple.com').setIssuedAt().setExpirationTime('5m').sign(key), redirectUri: options.redirectUri, scope: 'name email', responseMode: 'form_post', appleEmailClaim: true, ...(options.fetch ? { fetch: options.fetch } : {}) });
12
+ // Validate discovery during operator activation, not after rendering a button.
13
+ await client();
14
+ return { async start() { return (await client()).start(); }, async complete(callback, flow) { return (await client()).complete(callback, flow); } };
15
+ }
@@ -0,0 +1,45 @@
1
+ /** Registration data is descriptive, never authority. Roles, grants and session state are separate service operations. */
2
+ export type MetadataValue = string | number | boolean;
3
+ export interface MetadataField {
4
+ type: 'string' | 'number' | 'boolean';
5
+ scope: 'public' | 'private' | 'unsafe';
6
+ required?: boolean;
7
+ default?: MetadataValue;
8
+ enum?: MetadataValue[];
9
+ maxLength?: number;
10
+ minimum?: number;
11
+ maximum?: number;
12
+ }
13
+ export interface RegistrationOptions {
14
+ termsVersion?: string;
15
+ metadata?: Record<string, MetadataField>;
16
+ locales?: string[];
17
+ }
18
+ export interface RegistrationInput {
19
+ displayName?: string;
20
+ locale?: string;
21
+ metadata?: Record<string, MetadataValue>;
22
+ termsAccepted?: boolean;
23
+ }
24
+ export interface RegistrationProfile {
25
+ displayName?: string;
26
+ locale?: string;
27
+ metadata: Record<string, MetadataValue>;
28
+ terms?: {
29
+ version: string;
30
+ acceptedAt: number;
31
+ };
32
+ }
33
+ export interface RegistrationPolicy {
34
+ publicSchema(): RegistrationOptions;
35
+ validate(input: RegistrationInput, context: {
36
+ now: number;
37
+ existing?: RegistrationProfile;
38
+ operator?: boolean;
39
+ }): RegistrationProfile;
40
+ /** Public and unsafe metadata remain untrusted user content. Private metadata never leaves this projection. */
41
+ publicProfile(profile: RegistrationProfile): RegistrationProfile;
42
+ }
43
+ export declare function createRegistrationPolicy(options?: RegistrationOptions): RegistrationPolicy;
44
+ /** Quiet refusal is an HTTP integration decision; this helper never creates a fake account or session. */
45
+ export declare function isHoneypotFilled(value: unknown): boolean;