@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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/atscript/index.d.mts +2 -0
- package/dist/atscript/index.mjs +2 -0
- package/dist/forms-BE62OrN1.mjs +230 -0
- package/dist/index.d.mts +1279 -0
- package/dist/index.mjs +3347 -0
- package/package.json +90 -0
- package/src/atscript/models/forms.as +331 -0
- package/src/atscript/models/forms.as.d.ts +357 -0
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
|
+
}
|