@aooth/auth-moost 0.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.
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@aooth/auth-moost",
3
+ "version": "0.1.1",
4
+ "description": "Moost auth integration for aoothjs — AuthGuard interceptor, useAuth composable, REST endpoints, workflows",
5
+ "keywords": [
6
+ "aoothjs",
7
+ "auth",
8
+ "authentication",
9
+ "guard",
10
+ "interceptor",
11
+ "moost",
12
+ "session",
13
+ "token",
14
+ "workflow"
15
+ ],
16
+ "homepage": "https://github.com/moostjs/aoothjs/tree/main/packages/auth-moost#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/moostjs/aoothjs/issues"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Artem Maltsev",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/moostjs/aoothjs.git",
25
+ "directory": "packages/auth-moost"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "src/atscript/models/forms.as",
30
+ "src/atscript/models/forms.as.d.ts"
31
+ ],
32
+ "type": "module",
33
+ "sideEffects": false,
34
+ "main": "dist/index.mjs",
35
+ "module": "./dist/index.mjs",
36
+ "types": "dist/index.d.mts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.mts",
40
+ "import": "./dist/index.mjs"
41
+ },
42
+ "./atscript": {
43
+ "types": "./dist/atscript/index.d.mts",
44
+ "import": "./dist/atscript/index.mjs"
45
+ },
46
+ "./atscript/models": "./src/atscript/models/forms.as",
47
+ "./atscript/models.as": "./src/atscript/models/forms.as",
48
+ "./package.json": "./package.json"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "dependencies": {
54
+ "@atscript/moost-wf": "^0.1.65",
55
+ "@aooth/arbac-moost": "^0.1.1",
56
+ "@aooth/auth": "0.1.1",
57
+ "@aooth/user": "0.1.1"
58
+ },
59
+ "devDependencies": {
60
+ "@atscript/core": "^0.1.56",
61
+ "@atscript/typescript": "^0.1.56",
62
+ "@atscript/ui": "^0.1.65",
63
+ "@moostjs/event-http": "^0.6.10",
64
+ "@moostjs/event-wf": "^0.6.10",
65
+ "moost": "^0.6.10",
66
+ "unplugin-atscript": "^0.1.56",
67
+ "wooks": "^0.7.12"
68
+ },
69
+ "peerDependencies": {
70
+ "@atscript/moost-wf": ">=0.1.58",
71
+ "@atscript/typescript": ">=0.1.54",
72
+ "@moostjs/event-http": ">=0.6.10",
73
+ "@moostjs/event-wf": ">=0.6.10",
74
+ "@wooksjs/event-core": ">=0.7.12",
75
+ "@wooksjs/event-http": ">=0.7.12",
76
+ "moost": ">=0.6.10"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "@atscript/typescript": {
80
+ "optional": true
81
+ }
82
+ },
83
+ "scripts": {
84
+ "gen:atscript": "node --experimental-strip-types scripts/gen-as.mjs",
85
+ "build": "vp pack",
86
+ "dev": "vp pack --watch",
87
+ "test": "vp test",
88
+ "check": "vp check"
89
+ }
90
+ }
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Default login credentials form.
3
+ *
4
+ * Override via `setupAuthWorkflows({ forms: { loginCredentials: MyForm } })`.
5
+ */
6
+ export interface LoginCredentialsForm {
7
+ @ui.form.type 'text'
8
+ @meta.label 'Username'
9
+ @ui.form.autocomplete 'username'
10
+ @meta.required
11
+ @expect.minLength 1
12
+ username: string
13
+
14
+ @ui.form.type 'password'
15
+ @meta.label 'Password'
16
+ @ui.form.autocomplete 'current-password'
17
+ @meta.sensitive
18
+ @meta.required
19
+ @expect.minLength 1
20
+ password: string
21
+ }
22
+
23
+ /**
24
+ * MFA code form (TOTP today; email/SMS OTP later).
25
+ */
26
+ export interface MfaCodeForm {
27
+ @ui.form.type 'text'
28
+ @meta.label 'Verification code'
29
+ @ui.form.autocomplete 'one-time-code'
30
+ @meta.required
31
+ @expect.minLength 4
32
+ @expect.maxLength 12
33
+ @expect.pattern '^[0-9]+$'
34
+ code: string
35
+ }
36
+
37
+ /**
38
+ * Backup-code form (alphanumeric, hyphen-grouped — e.g. `XXXX-XXXX-XX`).
39
+ *
40
+ * `UserService.generateBackupCodes` uses a 31-character alphabet (uppercase
41
+ * letters minus I/O/L, digits minus 0/1) formatted with hyphens between groups
42
+ * of 4 — the regex below mirrors that shape. Kept separate from
43
+ * `MfaCodeForm` so TOTP entry stays strict-digits.
44
+ */
45
+ export interface BackupCodeForm {
46
+ @ui.form.type 'text'
47
+ @meta.label 'Backup code'
48
+ @ui.form.autocomplete 'one-time-code'
49
+ @meta.required
50
+ @expect.minLength 4
51
+ @expect.maxLength 32
52
+ @expect.pattern '^[A-Z2-9-]+$'
53
+ code: string
54
+ }
55
+
56
+ /**
57
+ * Email identifier form — used for password recovery initiation.
58
+ *
59
+ * `@wf.context.pass 'defaults'` whitelists the `defaults` ctx key so the
60
+ * recovery `request` step can pre-fill the email field from the
61
+ * `?username=` query param (carried in by the login workflow's
62
+ * `forgotPassword` alt-action). Without this annotation the field is
63
+ * stripped by `extractPassContext` before reaching the client.
64
+ */
65
+ @wf.context.pass 'defaults'
66
+ export interface EmailIdentifierForm {
67
+ @ui.form.type 'text'
68
+ @meta.label 'Email'
69
+ @ui.form.autocomplete 'email'
70
+ @meta.required
71
+ email: string.email
72
+ }
73
+
74
+ /**
75
+ * Set new password form.
76
+ *
77
+ * `confirmPassword` equality is enforced in the workflow step (cross-field
78
+ * checks are not expressible via atscript annotations).
79
+ */
80
+ export interface SetPasswordForm {
81
+ @ui.form.type 'password'
82
+ @meta.label 'New password'
83
+ @ui.form.autocomplete 'new-password'
84
+ @meta.sensitive
85
+ @meta.required
86
+ @expect.minLength 8
87
+ newPassword: string
88
+
89
+ @ui.form.type 'password'
90
+ @meta.label 'Confirm password'
91
+ @ui.form.autocomplete 'new-password'
92
+ @meta.sensitive
93
+ @meta.required
94
+ @expect.minLength 8
95
+ confirmPassword: string
96
+ }
97
+
98
+ /**
99
+ * Invite form — used by an admin to send an invite magic link.
100
+ *
101
+ * `@wf.context.pass 'availableRoles'` whitelists the workflow ctx key so the
102
+ * `inviteAdminInviteForm` step can pass the role-picker options into the
103
+ * client form when `opts.getAvailableRoles` is wired.
104
+ */
105
+ @wf.context.pass 'availableRoles'
106
+ export interface InviteForm {
107
+ @ui.form.type 'text'
108
+ @meta.label 'Email'
109
+ @ui.form.autocomplete 'email'
110
+ @meta.required
111
+ email: string.email
112
+
113
+ @ui.form.type 'text'
114
+ @meta.label 'First name'
115
+ firstName?: string
116
+
117
+ @ui.form.type 'text'
118
+ @meta.label 'Last name'
119
+ lastName?: string
120
+
121
+ // UX: select-on-array currently renders single-text-per-item via AsArray;
122
+ // dedicated multi-select widget tracked as atscript-ui follow-up.
123
+ @ui.form.type 'select'
124
+ @ui.form.fn.options '(_, _data, context) => Array.isArray(context.availableRoles) ? context.availableRoles.map(r => ({ value: r, label: r })) : []'
125
+ @meta.label 'Roles'
126
+ roles?: string[]
127
+ }
128
+
129
+ /**
130
+ * Email-only form — used by `auth.reInvite` (loadPendingUser step) and
131
+ * `auth.cancelInvite` (cancelInvite step). Separate from `EmailIdentifierForm`
132
+ * so future invite-side tweaks don't ripple into the recovery form.
133
+ */
134
+ export interface InviteEmailForm {
135
+ @ui.form.type 'text'
136
+ @meta.label 'Email'
137
+ @ui.form.autocomplete 'email'
138
+ @meta.required
139
+ email: string.email
140
+ }
141
+
142
+ /**
143
+ * Send-mode picker — rendered only when
144
+ * `InviteWorkflowOptions.sendMode === 'choice'`. `mode` matches one of
145
+ * `'email'` or `'shareableLink'`.
146
+ */
147
+ export interface InviteSendModeForm {
148
+ @ui.form.type 'text'
149
+ @meta.label 'Delivery mode'
150
+ @meta.required
151
+ @expect.pattern '^(email|shareableLink)$'
152
+ mode: string
153
+ }
154
+
155
+ /**
156
+ * Select an enrolled MFA method (Phase 4 `select2fa` step).
157
+ *
158
+ * The workflow renders this only when the user has >1 enrolled methods after
159
+ * `opts.mfaTransports` filtering. `methodName` is the `MfaMethod.name`
160
+ * (e.g. `"totp"`, `"email"`, `"sms"`); the workflow itself validates that the
161
+ * supplied value is in the user's enrolled set.
162
+ */
163
+ export interface Select2faForm {
164
+ @ui.form.type 'text'
165
+ @meta.label 'MFA method'
166
+ @meta.required
167
+ methodName: string
168
+
169
+ @ui.form.type 'checkbox'
170
+ @meta.label 'Save as default'
171
+ saveAsDefault?: boolean
172
+ }
173
+
174
+ /**
175
+ * Generic 6-digit pincode form — used by both login and recovery OTP flows.
176
+ *
177
+ * `rememberDevice` is rendered only when `opts.deviceTrust && opts.deviceTrustOptIn`.
178
+ */
179
+ export interface PincodeForm {
180
+ @ui.form.type 'text'
181
+ @meta.label 'Verification code'
182
+ @ui.form.autocomplete 'one-time-code'
183
+ @meta.required
184
+ @expect.minLength 4
185
+ @expect.maxLength 12
186
+ @expect.pattern '^[0-9]+$'
187
+ code: string
188
+
189
+ @ui.form.type 'checkbox'
190
+ @meta.label 'Remember this device'
191
+ rememberDevice?: boolean
192
+ }
193
+
194
+ /**
195
+ * Email-only form for the `ensureEmail` enrollment loop.
196
+ */
197
+ export interface AskEmailForm {
198
+ @ui.form.type 'text'
199
+ @meta.label 'Email'
200
+ @ui.form.autocomplete 'email'
201
+ @meta.required
202
+ email: string.email
203
+ }
204
+
205
+ /**
206
+ * Phone-only form for the `ensurePhone` enrollment loop. Free-form text —
207
+ * E.164 normalization happens server-side.
208
+ */
209
+ export interface AskPhoneForm {
210
+ @ui.form.type 'text'
211
+ @meta.label 'Phone (E.164)'
212
+ @ui.form.autocomplete 'tel'
213
+ @meta.required
214
+ phone: string
215
+ }
216
+
217
+ /**
218
+ * Terms & conditions acceptance form.
219
+ */
220
+ export interface TermsAcceptForm {
221
+ @ui.form.type 'text'
222
+ @meta.label 'Accepted version'
223
+ @meta.required
224
+ acceptedVersion: string
225
+
226
+ @ui.form.type 'checkbox'
227
+ @meta.label 'I accept the Terms & Conditions'
228
+ @meta.required
229
+ accepted: boolean
230
+ }
231
+
232
+ /**
233
+ * Default minimal profile completion form. Consumers replace via
234
+ * `LoginWorkflowOptions.profileCompleteForm` for richer shapes.
235
+ */
236
+ export interface ProfileCompleteForm {
237
+ @ui.form.type 'text'
238
+ @meta.label 'First name'
239
+ firstName?: string
240
+
241
+ @ui.form.type 'text'
242
+ @meta.label 'Last name'
243
+ lastName?: string
244
+ }
245
+
246
+ /**
247
+ * Marketing consent opt-in.
248
+ */
249
+ export interface ConsentMarketingForm {
250
+ @ui.form.type 'checkbox'
251
+ @meta.label 'I would like to receive marketing emails'
252
+ optIn?: boolean
253
+ }
254
+
255
+ /**
256
+ * Tenant picker — `tenantId` matches one of `ctx.availableTenants[].id`.
257
+ */
258
+ export interface TenantSelectForm {
259
+ @ui.form.type 'text'
260
+ @meta.label 'Tenant'
261
+ @meta.required
262
+ tenantId: string
263
+ }
264
+
265
+ /**
266
+ * Persona picker — `personaId` matches one of `ctx.availablePersonas[].id`.
267
+ */
268
+ export interface PersonaSelectForm {
269
+ @ui.form.type 'text'
270
+ @meta.label 'Persona'
271
+ @meta.required
272
+ personaId: string
273
+ }
274
+
275
+ /**
276
+ * Concurrency-limit kick prompt — user picks between logging out other
277
+ * sessions or cancelling the login.
278
+ */
279
+ export interface ConcurrencyLimitForm {
280
+ @ui.form.type 'text'
281
+ @meta.label 'Action'
282
+ @meta.required
283
+ @expect.pattern '^(logoutOthers|cancel)$'
284
+ action: string
285
+ }
286
+
287
+ /**
288
+ * Identifier form for the magic-link login path — same shape as
289
+ * {@link EmailIdentifierForm} but kept separate because future iterations may
290
+ * accept either email or username.
291
+ */
292
+ export interface MagicLinkRequestForm {
293
+ @ui.form.type 'text'
294
+ @meta.label 'Email or username'
295
+ @ui.form.autocomplete 'username'
296
+ @meta.required
297
+ identifier: string
298
+ }
299
+
300
+ /**
301
+ * Recovery delivery-mode picker — rendered only when
302
+ * `RecoveryWorkflowOptions.deliveryMode === 'choice'`.
303
+ */
304
+ export interface RecoveryModeSelectForm {
305
+ @ui.form.type 'text'
306
+ @meta.label 'Recovery method'
307
+ @meta.required
308
+ @expect.pattern '^(magicLink|otp)$'
309
+ mode: string
310
+ }
311
+
312
+ /**
313
+ * Recovery factor-verification form — used when
314
+ * `RecoveryWorkflowOptions.requireKnownRecoveryFactor` is true. The user
315
+ * picks a factor type and supplies its value; the server validates against
316
+ * the enrolled factor (phone last-4 or current TOTP code).
317
+ */
318
+ export interface RecoveryFactorForm {
319
+ @ui.form.type 'text'
320
+ @meta.label 'Factor'
321
+ @meta.required
322
+ @expect.pattern '^(phone|totp)$'
323
+ factor: string
324
+
325
+ @ui.form.type 'text'
326
+ @meta.label 'Value'
327
+ @meta.required
328
+ @expect.minLength 4
329
+ @expect.maxLength 12
330
+ value: string
331
+ }