@zlooks.cn/password-auth-server 1.0.2 → 1.0.3

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 (16) hide show
  1. package/.hile-rsc/{build-mtjl0eh7-90bc0b3a/client-browser/chunks/chunk-RZRQMKUX.js → build-mtsn68qv-a841a566/client-browser/chunks/chunk-CZF5VGOJ.js} +40053 -45863
  2. package/.hile-rsc/build-mtsn68qv-a841a566/client-browser/src-plugin-page-frame-07c4de56a6-C2WHPDGD.js +2312 -0
  3. package/.hile-rsc/build-mtsn68qv-a841a566/client-browser/src-plugin-password-form-3bd63d69e5-G5UQAB5W.js +4494 -0
  4. package/.hile-rsc/build-mtsn68qv-a841a566/client-ssr/chunks/chunk-RMKQVF3F.js +36281 -0
  5. package/.hile-rsc/build-mtsn68qv-a841a566/client-ssr/src-plugin-page-frame-07c4de56a6-ICZZGKBP.js +15609 -0
  6. package/.hile-rsc/{build-mtjl0eh7-90bc0b3a/client-ssr/chunks/chunk-SH36JXFV.js → build-mtsn68qv-a841a566/client-ssr/src-plugin-password-form-3bd63d69e5-UV3K6EC6.js} +104665 -140085
  7. package/.hile-rsc/{build-mtjl0eh7-90bc0b3a → build-mtsn68qv-a841a566}/plugin.json +18 -18
  8. package/.hile-rsc/{build-mtjl0eh7-90bc0b3a → build-mtsn68qv-a841a566}/server-rsc/index.js +2 -2
  9. package/package.json +3 -3
  10. package/.hile-rsc/build-mtjl0eh7-90bc0b3a/client-browser/src-plugin-page-frame-07c4de56a6-GJVQS7WE.js +0 -440
  11. package/.hile-rsc/build-mtjl0eh7-90bc0b3a/client-browser/src-plugin-password-form-3bd63d69e5-PXXZM4RL.js +0 -706
  12. package/.hile-rsc/build-mtjl0eh7-90bc0b3a/client-ssr/src-plugin-page-frame-07c4de56a6-JTUKAMPR.js +0 -441
  13. package/.hile-rsc/build-mtjl0eh7-90bc0b3a/client-ssr/src-plugin-password-form-3bd63d69e5-ESX5GCJR.js +0 -708
  14. /package/.hile-rsc/{build-mtjl0eh7-90bc0b3a → build-mtsn68qv-a841a566}/client-browser/src-plugin-page-frame-07c4de56a6-3F24AYCH.css +0 -0
  15. /package/.hile-rsc/{build-mtjl0eh7-90bc0b3a → build-mtsn68qv-a841a566}/client-browser/src-plugin-password-form-3bd63d69e5-TRYMJX4F.css +0 -0
  16. /package/.hile-rsc/{build-mtjl0eh7-90bc0b3a → build-mtsn68qv-a841a566}/styles/4b3193c4f2b317ffed425ccf401342a4bdd6ccfd5f9c42def3315e776f166975.css +0 -0
@@ -1,708 +0,0 @@
1
- "use client";
2
- import {
3
- RscLink,
4
- USER_SESSION_COOKIE,
5
- __toESM,
6
- browserApiDispatchResponseSchema,
7
- browserApiResponseSchema,
8
- external_exports,
9
- init_react,
10
- isBrowserApiFailure,
11
- jsx,
12
- jsxs,
13
- require_lib,
14
- useEffect,
15
- useRef,
16
- useRequest,
17
- useRscNavigation,
18
- useState
19
- } from "./chunks/chunk-SH36JXFV.js";
20
-
21
- // ../user-shared/dist/identity.js
22
- var USER_SERVICE_NAMESPACE = "cn.zlooks.user.server";
23
-
24
- // ../user-shared/dist/events/snapshots.js
25
- var userSessionRevocationReasonSchema = external_exports.enum([
26
- "logout",
27
- "user-request",
28
- "family-limit",
29
- "credential-recovery"
30
- ]);
31
- var displayNameSchema = external_exports.string().refine((value) => value === value.trim().normalize("NFKC"), "Display name must be normalized").refine((value) => Array.from(value).length >= 1 && Array.from(value).length <= 160, "Display name must contain 1 to 160 Unicode code points");
32
- var bioSchema = external_exports.string().refine((value) => value === value.trim().normalize("NFKC"), "Bio must be normalized").refine((value) => Array.from(value).length >= 1 && Array.from(value).length <= 500, "Bio must contain 1 to 500 Unicode code points");
33
- var httpUrlSchema = external_exports.url().max(2048).refine((value) => {
34
- const protocol = new URL(value).protocol;
35
- return protocol === "http:" || protocol === "https:";
36
- }, "URL must use HTTP or HTTPS").refine((value) => value === new URL(value).toString(), "URL must be canonical");
37
- var emailSchema = external_exports.email().max(320).refine((value) => value === value.toLocaleLowerCase("en-US"), "Email must be lowercase");
38
- var userEventSnapshotSchema = external_exports.strictObject({
39
- id: external_exports.uuid(),
40
- displayName: displayNameSchema.nullable(),
41
- avatar: httpUrlSchema.nullable(),
42
- homepage: httpUrlSchema.nullable(),
43
- bio: bioSchema.nullable(),
44
- email: emailSchema.nullable(),
45
- emailVerified: external_exports.boolean(),
46
- status: external_exports.enum(["active", "disabled", "deleted"]),
47
- createdAt: external_exports.iso.datetime({ offset: true }),
48
- updatedAt: external_exports.iso.datetime({ offset: true }),
49
- version: external_exports.number().int().positive()
50
- }).superRefine((user, context) => {
51
- if (user.emailVerified && user.email === null) {
52
- context.addIssue({
53
- code: "custom",
54
- message: "A verified user snapshot must include its email",
55
- path: ["email"]
56
- });
57
- }
58
- if (Date.parse(user.updatedAt) < Date.parse(user.createdAt)) {
59
- context.addIssue({
60
- code: "custom",
61
- message: "User updated time must not precede creation time",
62
- path: ["updatedAt"]
63
- });
64
- }
65
- }).readonly();
66
- var userSessionFamilyEventSnapshotSchema = external_exports.strictObject({
67
- id: external_exports.uuid(),
68
- userId: external_exports.uuid(),
69
- createdAt: external_exports.iso.datetime({ offset: true }),
70
- expiresAt: external_exports.iso.datetime({ offset: true }),
71
- lastSeenAt: external_exports.iso.datetime({ offset: true }),
72
- revokedAt: external_exports.iso.datetime({ offset: true }).nullable(),
73
- revokeReason: userSessionRevocationReasonSchema.nullable()
74
- }).superRefine((session, context) => {
75
- const createdAt = Date.parse(session.createdAt);
76
- if (session.revokedAt === null !== (session.revokeReason === null)) {
77
- context.addIssue({
78
- code: "custom",
79
- message: "Session revocation time and reason must be present together",
80
- path: ["revokedAt"]
81
- });
82
- }
83
- if (Date.parse(session.expiresAt) <= createdAt) {
84
- context.addIssue({
85
- code: "custom",
86
- message: "Session expiry must follow creation time",
87
- path: ["expiresAt"]
88
- });
89
- }
90
- const lastSeenAt = Date.parse(session.lastSeenAt);
91
- if (lastSeenAt < createdAt || lastSeenAt > Date.parse(session.expiresAt)) {
92
- context.addIssue({
93
- code: "custom",
94
- message: "Session last-seen time must fall within its lifetime",
95
- path: ["lastSeenAt"]
96
- });
97
- }
98
- if (session.revokedAt !== null && Date.parse(session.revokedAt) < createdAt) {
99
- context.addIssue({
100
- code: "custom",
101
- message: "Session revoked time must not precede creation time",
102
- path: ["revokedAt"]
103
- });
104
- }
105
- }).readonly();
106
-
107
- // ../event-bus/dist/index.js
108
- var eventType = external_exports.string().max(256).regex(/^[a-z][a-z0-9]*(?:\.[a-z][a-z0-9-]*)+\.v[1-9][0-9]*$/);
109
- var serviceNamespace = external_exports.string().max(256).regex(/^[a-z][a-z0-9]*(?:\.[a-z][a-z0-9]*)+$/);
110
- var aggregateType = external_exports.string().regex(/^[a-z][a-z0-9-]{0,63}$/);
111
- var aggregateId = external_exports.string().trim().min(1).max(256);
112
- var eventEnvelopeSchema = external_exports.strictObject({
113
- protocol: external_exports.literal("zlooks.event"),
114
- protocolVersion: external_exports.literal(1),
115
- eventId: external_exports.uuid(),
116
- type: eventType,
117
- producer: serviceNamespace,
118
- aggregate: external_exports.strictObject({
119
- type: aggregateType,
120
- id: aggregateId
121
- }).readonly(),
122
- occurredAt: external_exports.iso.datetime({ offset: true }),
123
- data: external_exports.unknown()
124
- }).readonly();
125
- function defineEvent(type, dataSchema5) {
126
- const parsedType = eventType.parse(type);
127
- return Object.freeze({
128
- type: parsedType,
129
- parse(value) {
130
- const envelope = eventEnvelopeSchema.parse(value);
131
- if (envelope.type !== parsedType) {
132
- throw new TypeError(`Expected event type ${parsedType}`);
133
- }
134
- return Object.freeze({
135
- ...envelope,
136
- type: parsedType,
137
- aggregate: Object.freeze({ ...envelope.aggregate }),
138
- data: dataSchema5.parse(envelope.data)
139
- });
140
- }
141
- });
142
- }
143
-
144
- // ../user-shared/dist/events/definition.js
145
- function defineUserEvent(type, aggregateType2, dataSchema5, aggregateId2) {
146
- const base = defineEvent(type, dataSchema5);
147
- return Object.freeze({
148
- type: base.type,
149
- parse(input) {
150
- const event = base.parse(input);
151
- if (event.producer !== USER_SERVICE_NAMESPACE) {
152
- throw new TypeError(`Expected event producer ${USER_SERVICE_NAMESPACE}`);
153
- }
154
- if (event.aggregate.type !== aggregateType2 || event.aggregate.id !== aggregateId2(event.data)) {
155
- throw new TypeError(`${type} aggregate does not identify its event data`);
156
- }
157
- return event;
158
- }
159
- });
160
- }
161
-
162
- // ../user-shared/dist/events/user-registered.js
163
- var USER_REGISTERED_EVENT_TYPE = "cn.zlooks.user.registered.v1";
164
- var userRegisteredDataSchema = external_exports.strictObject({
165
- user: userEventSnapshotSchema
166
- }).refine((data) => data.user.status === "active", {
167
- message: "A registered user snapshot must be active",
168
- path: ["user", "status"]
169
- }).readonly();
170
- var userRegisteredEvent = defineUserEvent(USER_REGISTERED_EVENT_TYPE, "user", userRegisteredDataSchema, (data) => data.user.id);
171
-
172
- // ../user-shared/dist/events/user-email-verified.js
173
- var USER_EMAIL_VERIFIED_EVENT_TYPE = "cn.zlooks.user.email-verified.v1";
174
- var dataSchema = external_exports.strictObject({ user: userEventSnapshotSchema }).refine((data) => data.user.email !== null && data.user.emailVerified, {
175
- message: "An email-verified event must contain a verified email snapshot",
176
- path: ["user", "emailVerified"]
177
- }).readonly();
178
- var userEmailVerifiedEvent = defineUserEvent(USER_EMAIL_VERIFIED_EVENT_TYPE, "user", dataSchema, (data) => data.user.id);
179
-
180
- // ../user-shared/dist/events/user-profile-updated.js
181
- var USER_PROFILE_UPDATED_EVENT_TYPE = "cn.zlooks.user.profile-updated.v1";
182
- var userProfileFieldSchema = external_exports.enum(["displayName", "avatar", "homepage", "bio"]);
183
- var dataSchema2 = external_exports.strictObject({
184
- user: userEventSnapshotSchema,
185
- changedFields: external_exports.array(userProfileFieldSchema).min(1).max(4).refine((fields) => new Set(fields).size === fields.length, "Profile fields must be unique").readonly()
186
- }).readonly();
187
- var userProfileUpdatedEvent = defineUserEvent(USER_PROFILE_UPDATED_EVENT_TYPE, "user", dataSchema2, (data) => data.user.id);
188
-
189
- // ../user-shared/dist/events/user-session-created.js
190
- var USER_SESSION_CREATED_EVENT_TYPE = "cn.zlooks.user.session-created.v1";
191
- var dataSchema3 = external_exports.strictObject({
192
- user: userEventSnapshotSchema,
193
- sessionFamily: userSessionFamilyEventSnapshotSchema,
194
- intent: external_exports.enum(["login", "registration", "recovery"])
195
- }).superRefine((data, context) => {
196
- if (data.sessionFamily.userId !== data.user.id) {
197
- context.addIssue({
198
- code: "custom",
199
- message: "Session and user snapshots must identify the same user",
200
- path: ["sessionFamily", "userId"]
201
- });
202
- }
203
- if (data.sessionFamily.revokedAt !== null) {
204
- context.addIssue({
205
- code: "custom",
206
- message: "A created session snapshot must be active",
207
- path: ["sessionFamily", "revokedAt"]
208
- });
209
- }
210
- if (data.user.status !== "active") {
211
- context.addIssue({
212
- code: "custom",
213
- message: "A session-created event must contain an active user snapshot",
214
- path: ["user", "status"]
215
- });
216
- }
217
- }).readonly();
218
- var userSessionCreatedEvent = defineUserEvent(USER_SESSION_CREATED_EVENT_TYPE, "session-family", dataSchema3, (data) => data.sessionFamily.id);
219
-
220
- // ../user-shared/dist/events/user-session-revoked.js
221
- var USER_SESSION_REVOKED_EVENT_TYPE = "cn.zlooks.user.session-revoked.v1";
222
- var dataSchema4 = external_exports.strictObject({
223
- user: userEventSnapshotSchema,
224
- sessionFamily: userSessionFamilyEventSnapshotSchema
225
- }).superRefine((data, context) => {
226
- if (data.sessionFamily.userId !== data.user.id) {
227
- context.addIssue({
228
- code: "custom",
229
- message: "Session and user snapshots must identify the same user",
230
- path: ["sessionFamily", "userId"]
231
- });
232
- }
233
- if (data.sessionFamily.revokedAt === null) {
234
- context.addIssue({
235
- code: "custom",
236
- message: "A revoked session snapshot must include its revocation",
237
- path: ["sessionFamily", "revokedAt"]
238
- });
239
- }
240
- }).readonly();
241
- var userSessionRevokedEvent = defineUserEvent(USER_SESSION_REVOKED_EVENT_TYPE, "session-family", dataSchema4, (data) => data.sessionFamily.id);
242
-
243
- // ../user-shared/dist/index.js
244
- var USER_BROWSER_API_PUBLIC_ROUTES = Object.freeze([
245
- Object.freeze({
246
- exact: "/api/auth/methods",
247
- methods: Object.freeze(["GET"]),
248
- forwardCookieNames: Object.freeze([])
249
- }),
250
- Object.freeze({
251
- exact: "/api/user/shell",
252
- methods: Object.freeze(["GET"]),
253
- forwardCookieNames: Object.freeze([USER_SESSION_COOKIE])
254
- }),
255
- Object.freeze({
256
- exact: "/api/user",
257
- methods: Object.freeze(["GET", "PATCH"]),
258
- forwardCookieNames: Object.freeze([USER_SESSION_COOKIE])
259
- }),
260
- Object.freeze({
261
- exact: "/api/user/sessions",
262
- methods: Object.freeze(["GET"]),
263
- forwardCookieNames: Object.freeze([USER_SESSION_COOKIE])
264
- }),
265
- Object.freeze({
266
- exact: "/api/auth/transactions",
267
- methods: Object.freeze(["POST"]),
268
- forwardCookieNames: Object.freeze([])
269
- }),
270
- Object.freeze({
271
- prefix: "/api/auth/transactions/",
272
- methods: Object.freeze(["POST"]),
273
- forwardCookieNames: Object.freeze([])
274
- }),
275
- Object.freeze({
276
- exact: "/api/auth/logout",
277
- methods: Object.freeze(["POST"]),
278
- forwardCookieNames: Object.freeze([USER_SESSION_COOKIE])
279
- }),
280
- Object.freeze({
281
- exact: "/api/auth/session/refresh",
282
- methods: Object.freeze(["POST"]),
283
- forwardCookieNames: Object.freeze([USER_SESSION_COOKIE])
284
- }),
285
- Object.freeze({
286
- prefix: "/api/user/sessions/",
287
- methods: Object.freeze(["POST"]),
288
- forwardCookieNames: Object.freeze([USER_SESSION_COOKIE])
289
- })
290
- ]);
291
- var USER_ACCOUNT_HREF = "/user.account/account";
292
- var USER_BROWSER_API_ERROR_CODES = Object.freeze({
293
- crossOriginRejected: 1001,
294
- requestRejected: 1002,
295
- authenticationRequired: 1003,
296
- sessionExpired: 1004,
297
- authenticationDenied: 1005,
298
- authenticationPending: 1006,
299
- routeNotFound: 1007,
300
- accountNotFound: 1008,
301
- accountAlreadyExists: 1009,
302
- invalidVerificationCode: 1010,
303
- verificationRateLimited: 1011,
304
- emailDeliveryFailed: 1012,
305
- serviceUnavailable: 1013
306
- });
307
- var absolutePath = external_exports.string().min(1).max(2048).regex(/^\/(?!\/)[^?#]*$/);
308
- var userShellViewSchema = external_exports.discriminatedUnion("status", [
309
- external_exports.strictObject({
310
- status: external_exports.literal("anonymous"),
311
- loginMethods: external_exports.array(external_exports.strictObject({
312
- id: external_exports.string().min(1).max(128),
313
- label: external_exports.string().min(1).max(80),
314
- href: absolutePath
315
- })).max(64)
316
- }),
317
- external_exports.strictObject({
318
- status: external_exports.literal("authenticated"),
319
- user: external_exports.strictObject({
320
- label: external_exports.string().min(1).max(160),
321
- secondary: external_exports.string().min(1).max(320).optional(),
322
- avatarText: external_exports.string().min(1).max(8),
323
- avatarUrl: external_exports.url({ protocol: /^https?$/ }).max(2048).optional()
324
- }),
325
- accountHref: absolutePath,
326
- logoutHref: absolutePath
327
- })
328
- ]).readonly();
329
- var sessionCookieSchema = external_exports.discriminatedUnion("action", [
330
- external_exports.strictObject({
331
- action: external_exports.literal("set"),
332
- value: external_exports.string().min(1).max(4096),
333
- expiresAt: external_exports.iso.datetime({ offset: true })
334
- }),
335
- external_exports.strictObject({ action: external_exports.literal("clear") })
336
- ]);
337
- var userCurrentUserRequestSchema = external_exports.strictObject({}).readonly();
338
- var userPublicProfileSchema = external_exports.strictObject({
339
- id: external_exports.uuid(),
340
- displayName: external_exports.string().trim().min(1).max(160).nullable(),
341
- avatar: external_exports.url({ protocol: /^https?$/ }).max(2048).nullable(),
342
- homepage: external_exports.url({ protocol: /^https?$/ }).max(2048).nullable().optional(),
343
- bio: external_exports.string().trim().min(1).max(500).nullable().optional()
344
- }).readonly();
345
- var userCurrentUserSchema = userPublicProfileSchema;
346
- var userCurrentUserResponseSchema = external_exports.discriminatedUnion("authenticated", [
347
- external_exports.strictObject({ authenticated: external_exports.literal(false) }),
348
- external_exports.strictObject({
349
- authenticated: external_exports.literal(true),
350
- user: userCurrentUserSchema
351
- })
352
- ]).readonly();
353
- var userPublicProfilesRequestSchema = external_exports.strictObject({
354
- userIds: external_exports.array(external_exports.uuid()).min(1).max(100).refine((userIds) => new Set(userIds).size === userIds.length, { message: "User IDs must be unique" }).readonly()
355
- }).readonly();
356
- var userPublicProfilesResponseSchema = external_exports.strictObject({
357
- users: external_exports.array(userPublicProfileSchema).max(100).refine((users) => new Set(users.map((user) => user.id)).size === users.length, { message: "Public user profiles must be unique" }).readonly()
358
- }).readonly();
359
- var userBrowserApiRequestSchema = external_exports.strictObject({
360
- method: external_exports.enum(["GET", "POST", "PATCH"]),
361
- path: absolutePath,
362
- origin: external_exports.string().max(2048).optional(),
363
- clientKey: external_exports.string().regex(/^[a-f0-9]{64}$/),
364
- body: external_exports.unknown().optional()
365
- }).readonly();
366
- var userBrowserApiProviderRequestSchema = external_exports.strictObject({
367
- method: external_exports.enum(["GET", "POST", "PATCH"]),
368
- path: absolutePath,
369
- origin: external_exports.string().max(2048).optional(),
370
- clientKey: external_exports.string().regex(/^[a-f0-9]{64}$/),
371
- body: external_exports.unknown().optional()
372
- }).readonly();
373
- var userBrowserApiProviderResponseSchema = browserApiDispatchResponseSchema.superRefine((response, context) => {
374
- for (const [index, effect] of (response.cookieEffects ?? []).entries()) {
375
- if (effect.name === USER_SESSION_COOKIE)
376
- continue;
377
- context.addIssue({
378
- code: "custom",
379
- message: "User Browser API may only mutate its declared session cookie",
380
- path: ["cookieEffects", index, "name"]
381
- });
382
- }
383
- }).readonly();
384
- var userBrowserApiResponseSchema = external_exports.strictObject({
385
- status: external_exports.number().int().min(200).max(599).refine((status) => status < 300 || status >= 400),
386
- body: browserApiResponseSchema,
387
- sessionCookie: sessionCookieSchema.optional()
388
- }).superRefine((response, context) => {
389
- const httpSucceeded = response.status >= 200 && response.status < 300;
390
- if (httpSucceeded === !isBrowserApiFailure(response.body))
391
- return;
392
- context.addIssue({
393
- code: "custom",
394
- message: "HTTP status and browser API response code disagree",
395
- path: ["body", "code"]
396
- });
397
- }).readonly();
398
- var userCredentialLifecycleEventSchema = external_exports.strictObject({
399
- protocol: external_exports.literal("zlooks.user.credential-lifecycle"),
400
- kind: external_exports.enum(["registration", "recovery"]),
401
- authenticationTransactionId: external_exports.uuid(),
402
- extensionId: external_exports.string().regex(/^[a-z][a-z0-9._-]{0,127}$/),
403
- methodId: external_exports.string().regex(/^[a-z][a-z0-9._-]{0,127}$/),
404
- subject: external_exports.string().trim().min(1).max(512),
405
- email: external_exports.email().max(320),
406
- occurredAt: external_exports.iso.datetime({ offset: true })
407
- }).readonly();
408
- var userCredentialLifecycleResponseSchema = external_exports.strictObject({
409
- acknowledged: external_exports.literal(true)
410
- }).readonly();
411
-
412
- // src/plugin/password-form.tsx
413
- var import_antd = __toESM(require_lib(), 1);
414
- init_react();
415
-
416
- // src/plugin/auth-response.ts
417
- function parseAuthenticationCompletion(input) {
418
- if (input === null || typeof input !== "object" || Array.isArray(input)) {
419
- throw new Error("\u8BA4\u8BC1\u54CD\u5E94\u65E0\u6548");
420
- }
421
- const response = input;
422
- if (response.status === "verified") return { status: "verified" };
423
- if (response.status === "denied") throw new Error("\u8BA4\u8BC1\u4FE1\u606F\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5");
424
- if (response.status === "pending") throw new Error("\u8BA4\u8BC1\u4ECD\u5728\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5");
425
- throw new Error("\u8BA4\u8BC1\u54CD\u5E94\u65E0\u6548");
426
- }
427
- function parseAuthenticationChallenge(input) {
428
- if (input === null || typeof input !== "object" || Array.isArray(input)) {
429
- throw new Error("\u9A8C\u8BC1\u7801\u54CD\u5E94\u65E0\u6548");
430
- }
431
- const response = input;
432
- if (response.status !== "pending" || !Number.isSafeInteger(response.retryAfterMs) || response.retryAfterMs <= 0 || response.retryAfterMs > 6e4) {
433
- throw new Error("\u9A8C\u8BC1\u7801\u54CD\u5E94\u65E0\u6548");
434
- }
435
- return { retryAfterMs: response.retryAfterMs };
436
- }
437
-
438
- // src/plugin/password-form.module.css
439
- var password_form_default = {
440
- authShell: "password_form_authShell",
441
- introduction: "password_form_introduction",
442
- eyebrow: "password_form_eyebrow",
443
- introductionTitle: "password_form_introductionTitle",
444
- introductionCopy: "password_form_introductionCopy",
445
- formRegion: "password_form_formRegion",
446
- formBody: "password_form_formBody",
447
- formNote: "password_form_formNote",
448
- codeRow: "password_form_codeRow",
449
- changeEmail: "password_form_changeEmail",
450
- alternate: "password_form_alternate",
451
- alternateLinks: "password_form_alternateLinks"
452
- };
453
-
454
- // src/plugin/password-form.tsx
455
- function PasswordForm(props) {
456
- const [form] = import_antd.Form.useForm();
457
- const { message } = import_antd.App.useApp();
458
- const request = useRequest();
459
- const navigation = useRscNavigation();
460
- const [transactionId, setTransactionId] = useState(props.transactionId);
461
- const [mode, setMode] = useState("password");
462
- const [codeSent, setCodeSent] = useState(false);
463
- const [countdown, setCountdown] = useState(0);
464
- const [submitting, setSubmitting] = useState(false);
465
- const [sending, setSending] = useState(false);
466
- const pendingSend = useRef(void 0);
467
- const usesCode = props.intent !== "login" || mode === "code";
468
- const needsPassword = props.intent !== "login" || mode === "password";
469
- useEffect(() => {
470
- if (countdown <= 0) return;
471
- const timer = window.setInterval(() => setCountdown((value) => Math.max(0, value - 1)), 1e3);
472
- return () => window.clearInterval(timer);
473
- }, [countdown > 0]);
474
- async function ensureTransaction() {
475
- if (transactionId) return transactionId;
476
- const created = await beginTransaction(request, props.intent);
477
- setTransactionId(created);
478
- return created;
479
- }
480
- async function sendCode() {
481
- try {
482
- const { email } = await form.validateFields(["email"]);
483
- setSending(true);
484
- const currentTransactionId = await ensureTransaction();
485
- const requestId = pendingSend.current?.email === email ? pendingSend.current.requestId : crypto.randomUUID();
486
- pendingSend.current = { email, requestId };
487
- const challenge = await request(
488
- `/api/auth/transactions/${encodeURIComponent(currentTransactionId)}/complete`,
489
- {
490
- method: "POST",
491
- headers: { "content-type": "application/json" },
492
- credentials: "same-origin",
493
- body: JSON.stringify({ input: { action: "send-code", email, requestId } })
494
- },
495
- { errorMessage: "\u9A8C\u8BC1\u7801\u53D1\u9001\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5", parse: parseAuthenticationChallenge }
496
- );
497
- setCodeSent(true);
498
- setCountdown(Math.ceil(challenge.retryAfterMs / 1e3));
499
- pendingSend.current = void 0;
500
- void message.success("\u9A8C\u8BC1\u7801\u5DF2\u53D1\u9001");
501
- } catch {
502
- } finally {
503
- setSending(false);
504
- }
505
- }
506
- async function submit(values) {
507
- setSubmitting(true);
508
- try {
509
- const currentTransactionId = await ensureTransaction();
510
- const input = usesCode ? {
511
- action: "verify-code",
512
- email: values.email,
513
- code: values.code,
514
- ...needsPassword ? { password: values.password } : {}
515
- } : { action: "password-login", email: values.email, password: values.password };
516
- await request(`/api/auth/transactions/${encodeURIComponent(currentTransactionId)}/complete`, {
517
- method: "POST",
518
- headers: { "content-type": "application/json" },
519
- credentials: "same-origin",
520
- body: JSON.stringify({ input })
521
- }, { errorMessage: "\u6CA1\u6709\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u8F93\u5165\u540E\u91CD\u8BD5", parse: parseAuthenticationCompletion });
522
- if (props.intent === "registration") {
523
- navigation.replace(USER_ACCOUNT_HREF);
524
- return;
525
- }
526
- navigation.replace("/");
527
- } catch {
528
- } finally {
529
- setSubmitting(false);
530
- }
531
- }
532
- const copy = pageCopy(props.intent);
533
- return /* @__PURE__ */ jsxs(
534
- "section",
535
- {
536
- "aria-labelledby": "password-auth-title",
537
- className: password_form_default.authShell,
538
- "data-auth-method": "password",
539
- "data-flat-auth-layout": true,
540
- children: [
541
- /* @__PURE__ */ jsxs("div", { className: password_form_default.introduction, children: [
542
- /* @__PURE__ */ jsx("p", { className: password_form_default.eyebrow, children: copy.step }),
543
- /* @__PURE__ */ jsx("h1", { className: password_form_default.introductionTitle, id: "password-auth-title", children: copy.title }),
544
- /* @__PURE__ */ jsx("p", { className: password_form_default.introductionCopy, children: copy.introduction }),
545
- /* @__PURE__ */ jsx(AlternateLinks, { intent: props.intent })
546
- ] }),
547
- /* @__PURE__ */ jsxs("div", { className: password_form_default.formRegion, children: [
548
- /* @__PURE__ */ jsx("div", { className: password_form_default.formBody, children: /* @__PURE__ */ jsxs(
549
- import_antd.Form,
550
- {
551
- form,
552
- layout: "vertical",
553
- requiredMark: false,
554
- scrollToFirstError: { focus: true },
555
- validateTrigger: "onBlur",
556
- onFinish: submit,
557
- children: [
558
- props.intent === "login" ? /* @__PURE__ */ jsx(import_antd.Form.Item, { children: /* @__PURE__ */ jsx(
559
- import_antd.Segmented,
560
- {
561
- "aria-label": "\u9009\u62E9\u767B\u5F55\u65B9\u5F0F",
562
- block: true,
563
- options: [{ label: "\u5BC6\u7801\u767B\u5F55", value: "password" }, { label: "\u9A8C\u8BC1\u7801\u767B\u5F55", value: "code" }],
564
- size: "large",
565
- value: mode,
566
- onChange: (value) => {
567
- setMode(value);
568
- setCodeSent(false);
569
- setCountdown(0);
570
- setTransactionId(props.transactionId);
571
- pendingSend.current = void 0;
572
- form.resetFields(["code"]);
573
- }
574
- }
575
- ) }) : null,
576
- /* @__PURE__ */ jsx(import_antd.Form.Item, { label: "\u90AE\u7BB1", name: "email", rules: emailRules, children: /* @__PURE__ */ jsx(import_antd.Input, { autoComplete: "username", disabled: codeSent, inputMode: "email", maxLength: 320, placeholder: "name@example.com", size: "large", type: "email" }) }),
577
- codeSent ? /* @__PURE__ */ jsx(
578
- import_antd.Button,
579
- {
580
- className: password_form_default.changeEmail,
581
- disabled: sending || submitting,
582
- type: "link",
583
- onClick: () => {
584
- setCodeSent(false);
585
- setCountdown(0);
586
- setTransactionId(void 0);
587
- pendingSend.current = void 0;
588
- form.resetFields(["code"]);
589
- window.requestAnimationFrame(() => form.focusField("email"));
590
- },
591
- children: "\u4FEE\u6539\u90AE\u7BB1"
592
- }
593
- ) : null,
594
- usesCode ? /* @__PURE__ */ jsx(import_antd.Form.Item, { label: "\u9A8C\u8BC1\u7801", required: true, children: /* @__PURE__ */ jsxs("div", { className: password_form_default.codeRow, children: [
595
- /* @__PURE__ */ jsx(import_antd.Form.Item, { noStyle: true, name: "code", rules: [{ required: true, message: "\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801" }, { len: 6, message: "\u9A8C\u8BC1\u7801\u5E94\u4E3A 6 \u4F4D\u6570\u5B57" }, { pattern: /^\d{6}$/, message: "\u9A8C\u8BC1\u7801\u5E94\u4E3A 6 \u4F4D\u6570\u5B57" }], children: /* @__PURE__ */ jsx(import_antd.Input, { "aria-label": "\u9A8C\u8BC1\u7801", autoComplete: "one-time-code", inputMode: "numeric", maxLength: 6, placeholder: "6 \u4F4D\u9A8C\u8BC1\u7801", size: "large" }) }),
596
- /* @__PURE__ */ jsx(import_antd.Button, { disabled: countdown > 0 || submitting, loading: sending, onClick: sendCode, size: "large", children: countdown > 0 ? `${countdown} \u79D2\u540E\u91CD\u53D1` : codeSent ? "\u91CD\u65B0\u53D1\u9001" : "\u53D1\u9001\u9A8C\u8BC1\u7801" })
597
- ] }) }) : null,
598
- needsPassword ? /* @__PURE__ */ jsx(
599
- import_antd.Form.Item,
600
- {
601
- extra: props.intent !== "login" ? "\u81F3\u5C11 12 \u4E2A\u5B57\u7B26\uFF0C\u5EFA\u8BAE\u4F7F\u7528\u5BC6\u7801\u7BA1\u7406\u5668\u751F\u6210\u5E76\u4FDD\u5B58\u3002" : void 0,
602
- label: props.intent === "recovery" ? "\u65B0\u5BC6\u7801" : "\u5BC6\u7801",
603
- name: "password",
604
- rules: passwordRules(props.intent !== "login"),
605
- children: /* @__PURE__ */ jsx(
606
- import_antd.Input.Password,
607
- {
608
- autoComplete: props.intent === "login" ? "current-password" : "new-password",
609
- maxLength: 128,
610
- placeholder: props.intent === "login" ? "\u8F93\u5165\u5BC6\u7801" : "\u521B\u5EFA\u4E00\u4E2A\u5B89\u5168\u5BC6\u7801",
611
- size: "large"
612
- }
613
- )
614
- }
615
- ) : null,
616
- /* @__PURE__ */ jsx(import_antd.Button, { block: true, htmlType: "submit", loading: submitting, size: "large", type: "primary", disabled: sending || usesCode && !codeSent, children: copy.submit })
617
- ]
618
- }
619
- ) }),
620
- /* @__PURE__ */ jsxs("aside", { className: password_form_default.formNote, children: [
621
- /* @__PURE__ */ jsx("p", { children: copy.description }),
622
- /* @__PURE__ */ jsx("span", { children: "\u4F60\u7684\u767B\u5F55\u4FE1\u606F\u53EA\u7528\u4E8E\u8BC6\u522B\u8D26\u6237\u3002" })
623
- ] })
624
- ] })
625
- ]
626
- }
627
- );
628
- }
629
- function AlternateLinks({ intent }) {
630
- if (intent === "registration") return /* @__PURE__ */ jsxs("p", { className: password_form_default.alternate, children: [
631
- "\u5DF2\u7ECF\u6709\u8D26\u53F7\uFF1F",
632
- /* @__PURE__ */ jsx(RscLink, { href: "/auth.password/login", children: "\u8FD4\u56DE\u767B\u5F55" })
633
- ] });
634
- if (intent === "recovery") return /* @__PURE__ */ jsxs("p", { className: password_form_default.alternate, children: [
635
- "\u60F3\u8D77\u5BC6\u7801\u4E86\uFF1F",
636
- /* @__PURE__ */ jsx(RscLink, { href: "/auth.password/login", children: "\u8FD4\u56DE\u767B\u5F55" })
637
- ] });
638
- return /* @__PURE__ */ jsxs("div", { className: password_form_default.alternateLinks, children: [
639
- /* @__PURE__ */ jsxs("p", { children: [
640
- /* @__PURE__ */ jsx("span", { children: "\u8FD8\u6CA1\u6709\u8D26\u6237\uFF1F" }),
641
- /* @__PURE__ */ jsx(RscLink, { href: "/auth.password/register", children: "\u521B\u5EFA\u8D26\u6237" })
642
- ] }),
643
- /* @__PURE__ */ jsxs("p", { children: [
644
- /* @__PURE__ */ jsx("span", { children: "\u5FD8\u8BB0\u5BC6\u7801\uFF1F" }),
645
- /* @__PURE__ */ jsx(RscLink, { href: "/auth.password/recovery", children: "\u627E\u56DE\u5BC6\u7801" })
646
- ] })
647
- ] });
648
- }
649
- async function beginTransaction(request, intent) {
650
- return request("/api/auth/transactions", {
651
- method: "POST",
652
- headers: { "content-type": "application/json" },
653
- credentials: "same-origin",
654
- body: JSON.stringify({ methodId: "password", intent })
655
- }, { errorMessage: "\u6682\u65F6\u65E0\u6CD5\u7EE7\u7EED\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5", parse: parseTransactionId });
656
- }
657
- function parseTransactionId(data) {
658
- if (data === null || typeof data !== "object" || Array.isArray(data)) throw new Error("Invalid transaction response");
659
- const transactionId = data.transactionId;
660
- if (typeof transactionId !== "string" || !UUID.test(transactionId)) {
661
- throw new Error("Invalid transaction response");
662
- }
663
- return transactionId;
664
- }
665
- var emailRules = [
666
- { required: true, message: "\u8BF7\u8F93\u5165\u90AE\u7BB1", whitespace: true },
667
- { type: "email", message: "\u8BF7\u8F93\u5165\u6709\u6548\u7684\u90AE\u7BB1\u5730\u5740" },
668
- { max: 320, message: "\u90AE\u7BB1\u5730\u5740\u4E0D\u80FD\u8D85\u8FC7 320 \u4E2A\u5B57\u7B26" }
669
- ];
670
- function passwordRules(requireMinimum) {
671
- return [
672
- { required: true, message: "\u8BF7\u8F93\u5165\u5BC6\u7801" },
673
- ...requireMinimum ? [{
674
- validator: async (_rule, value) => {
675
- if (!value) return;
676
- if (Array.from(value).length < 12) throw new Error("\u5BC6\u7801\u81F3\u5C11\u9700\u8981 12 \u4E2A\u5B57\u7B26");
677
- if (new TextEncoder().encode(value).byteLength > 128) throw new Error("\u5BC6\u7801\u8FC7\u957F\uFF0C\u8BF7\u7F29\u77ED\u540E\u91CD\u8BD5");
678
- }
679
- }] : [{ max: 128, message: "\u5BC6\u7801\u4E0D\u80FD\u8D85\u8FC7 128 \u4E2A\u5B57\u7B26" }]
680
- ];
681
- }
682
- var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
683
- function pageCopy(intent) {
684
- if (intent === "registration") return {
685
- introduction: "\u9A8C\u8BC1\u90AE\u7BB1\u5E76\u521B\u5EFA\u8D26\u53F7\u540E\uFF0C\u53EF\u4EE5\u7EE7\u7EED\u5B8C\u5584\u8D44\u6599\uFF0C\u6574\u7406\u5C5E\u4E8E\u4F60\u7684\u8BB0\u5F55\u3002",
686
- step: "ACCOUNT / REGISTER",
687
- title: "\u521B\u5EFA\u8D26\u6237",
688
- description: "\u4F7F\u7528\u90AE\u7BB1\u9A8C\u8BC1\u7801\u548C\u5BC6\u7801\u521B\u5EFA\u8D26\u53F7\u3002",
689
- submit: "\u521B\u5EFA\u8D26\u53F7"
690
- };
691
- if (intent === "recovery") return {
692
- introduction: "\u9A8C\u8BC1\u6CE8\u518C\u90AE\u7BB1\u540E\u8BBE\u7F6E\u65B0\u5BC6\u7801\uFF0C\u65E7\u8BBE\u5907\u4E0A\u7684\u767B\u5F55\u4F1A\u81EA\u52A8\u9000\u51FA\u3002",
693
- step: "ACCOUNT / RECOVERY",
694
- title: "\u627E\u56DE\u5BC6\u7801",
695
- description: "\u9A8C\u8BC1\u7801\u53EA\u4F1A\u53D1\u9001\u5230\u5DF2\u7ECF\u6CE8\u518C\u7684\u90AE\u7BB1\u3002",
696
- submit: "\u66F4\u65B0\u5BC6\u7801\u5E76\u767B\u5F55"
697
- };
698
- return {
699
- introduction: "\u767B\u5F55\u540E\u53EF\u4EE5\u7BA1\u7406\u4E2A\u4EBA\u8D44\u6599\u4E0E\u767B\u5F55\u4F1A\u8BDD\u3002",
700
- step: "ACCOUNT / SIGN IN",
701
- title: "\u767B\u5F55\u8D26\u6237",
702
- description: "\u4F7F\u7528\u5BC6\u7801\u6216\u90AE\u7BB1\u9A8C\u8BC1\u7801\u767B\u5F55\u4F60\u7684\u8D26\u6237\u3002",
703
- submit: "\u767B\u5F55"
704
- };
705
- }
706
- export {
707
- PasswordForm as default
708
- };