@spfn/auth 0.2.0-beta.9 → 0.2.0-beta.91
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 +1 -1
- package/README.md +1007 -1739
- package/dist/authenticate-DlTGaBT8.d.ts +1403 -0
- package/dist/client-proof.d.ts +606 -0
- package/dist/client-proof.js +1842 -0
- package/dist/client-proof.js.map +1 -0
- package/dist/config.d.ts +487 -39
- package/dist/config.js +243 -29
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +208 -3
- package/dist/errors.js +140 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +392 -110
- package/dist/index.js +186 -7
- package/dist/index.js.map +1 -1
- package/dist/nextjs/api.js +591 -61
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/client.d.ts +28 -0
- package/dist/nextjs/client.js +80 -0
- package/dist/nextjs/client.js.map +1 -0
- package/dist/nextjs/server.d.ts +92 -3
- package/dist/nextjs/server.js +288 -24
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +2618 -1092
- package/dist/server.js +6553 -1500
- package/dist/server.js.map +1 -1
- package/dist/session-DTHahDQ9.d.ts +53 -0
- package/dist/types-DYyhze28.d.ts +98 -0
- package/dist/wire-version-CtzMKvBB.d.ts +134 -0
- package/migrations/20251125021229_premium_famine/snapshot.json +2641 -0
- package/migrations/20260225130050_smooth_the_fury/migration.sql +3 -0
- package/migrations/20260225130050_smooth_the_fury/snapshot.json +2686 -0
- package/migrations/20260308141417_deep_iceman/migration.sql +11 -0
- package/migrations/20260308141417_deep_iceman/snapshot.json +2686 -0
- package/migrations/20260308151309_perfect_deathbird/migration.sql +3 -0
- package/migrations/20260308151309_perfect_deathbird/snapshot.json +2731 -0
- package/migrations/20260308201135_concerned_rawhide_kid/migration.sql +5 -0
- package/migrations/20260308201135_concerned_rawhide_kid/snapshot.json +2786 -0
- package/migrations/20260629103209_lethal_lifeguard/migration.sql +32 -0
- package/migrations/20260629103209_lethal_lifeguard/snapshot.json +2786 -0
- package/migrations/20260709073531_easy_hardball/migration.sql +24 -0
- package/migrations/20260709073531_easy_hardball/snapshot.json +3119 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/migration.sql +1 -0
- package/migrations/20260714081434_glossy_major_mapleleaf/snapshot.json +3112 -0
- package/migrations/20260804105939_amazing_bushwacker/migration.sql +3 -0
- package/migrations/20260804105939_amazing_bushwacker/snapshot.json +3112 -0
- package/migrations/20260804110033_fat_piledriver/migration.sql +2 -0
- package/migrations/20260804110033_fat_piledriver/snapshot.json +3138 -0
- package/migrations/20260805143152_vengeful_ravenous/migration.sql +4 -0
- package/migrations/20260805143152_vengeful_ravenous/snapshot.json +3190 -0
- package/package.json +60 -46
- package/dist/dto-CRlgoCP5.d.ts +0 -645
- package/migrations/meta/0000_snapshot.json +0 -1632
- package/migrations/meta/_journal.json +0 -13
- /package/migrations/{0000_premium_famine.sql → 20251125021229_premium_famine/migration.sql} +0 -0
package/dist/index.js
CHANGED
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
ValidationError,
|
|
16
16
|
UnauthorizedError,
|
|
17
17
|
ForbiddenError,
|
|
18
|
-
ConflictError
|
|
18
|
+
ConflictError,
|
|
19
|
+
NotFoundError
|
|
19
20
|
} from "@spfn/core/errors";
|
|
20
21
|
var InvalidCredentialsError = class extends UnauthorizedError {
|
|
21
22
|
constructor(data = {}) {
|
|
@@ -29,6 +30,12 @@ var InvalidTokenError = class extends UnauthorizedError {
|
|
|
29
30
|
this.name = "InvalidTokenError";
|
|
30
31
|
}
|
|
31
32
|
};
|
|
33
|
+
var InvalidSocialTokenError = class extends UnauthorizedError {
|
|
34
|
+
constructor(data = {}) {
|
|
35
|
+
super({ message: data.message || "Invalid social id_token", details: data.details });
|
|
36
|
+
this.name = "InvalidSocialTokenError";
|
|
37
|
+
}
|
|
38
|
+
};
|
|
32
39
|
var TokenExpiredError = class extends UnauthorizedError {
|
|
33
40
|
constructor(data = {}) {
|
|
34
41
|
super({ message: data.message || "Authentication token has expired", details: data.details });
|
|
@@ -51,6 +58,33 @@ var AccountDisabledError = class extends ForbiddenError {
|
|
|
51
58
|
this.name = "AccountDisabledError";
|
|
52
59
|
}
|
|
53
60
|
};
|
|
61
|
+
var AccountPendingDeletionError = class extends ForbiddenError {
|
|
62
|
+
constructor(data = {}) {
|
|
63
|
+
super({
|
|
64
|
+
message: data.message || "Account is scheduled for deletion",
|
|
65
|
+
details: { status: "pending_deletion", purgeScheduledAt: data.purgeScheduledAt, ...data.details }
|
|
66
|
+
});
|
|
67
|
+
this.name = "AccountPendingDeletionError";
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var DeletionAlreadyRequestedError = class extends ConflictError {
|
|
71
|
+
constructor(data = {}) {
|
|
72
|
+
super({ message: data.message || "Account deletion has already been requested", details: data.details });
|
|
73
|
+
this.name = "DeletionAlreadyRequestedError";
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var DeletionNotRequestedError = class extends NotFoundError {
|
|
77
|
+
constructor(data = {}) {
|
|
78
|
+
super({ message: data.message || "No pending account deletion request found", details: data.details });
|
|
79
|
+
this.name = "DeletionNotRequestedError";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
var ImmediateDeletionNotAllowedError = class extends ForbiddenError {
|
|
83
|
+
constructor(data = {}) {
|
|
84
|
+
super({ message: data.message || "Immediate self-service deletion is not enabled", details: data.details });
|
|
85
|
+
this.name = "ImmediateDeletionNotAllowedError";
|
|
86
|
+
}
|
|
87
|
+
};
|
|
54
88
|
var AccountAlreadyExistsError = class extends ConflictError {
|
|
55
89
|
constructor(data = {}) {
|
|
56
90
|
super({
|
|
@@ -64,6 +98,12 @@ var AccountAlreadyExistsError = class extends ConflictError {
|
|
|
64
98
|
this.name = "AccountAlreadyExistsError";
|
|
65
99
|
}
|
|
66
100
|
};
|
|
101
|
+
var RegistrationRejectedError = class extends ForbiddenError {
|
|
102
|
+
constructor(data = {}) {
|
|
103
|
+
super({ message: data.message || "Registration rejected", details: data.details });
|
|
104
|
+
this.name = "RegistrationRejectedError";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
67
107
|
var InvalidVerificationCodeError = class extends ValidationError {
|
|
68
108
|
constructor(data = {}) {
|
|
69
109
|
super({ message: data.message || "Invalid verification code", details: data.details });
|
|
@@ -76,12 +116,54 @@ var InvalidVerificationTokenError = class extends ValidationError {
|
|
|
76
116
|
this.name = "InvalidVerificationTokenError";
|
|
77
117
|
}
|
|
78
118
|
};
|
|
119
|
+
var KeyIdAlreadyRegisteredError = class extends ConflictError {
|
|
120
|
+
constructor(data = {}) {
|
|
121
|
+
super({
|
|
122
|
+
message: data.message || "This keyId is already registered. Generate a new keyId and retry.",
|
|
123
|
+
details: data.details
|
|
124
|
+
});
|
|
125
|
+
this.name = "KeyIdAlreadyRegisteredError";
|
|
126
|
+
}
|
|
127
|
+
};
|
|
79
128
|
var InvalidKeyFingerprintError = class extends ValidationError {
|
|
80
129
|
constructor(data = {}) {
|
|
81
130
|
super({ message: data.message || "Invalid key fingerprint", details: data.details });
|
|
82
131
|
this.name = "InvalidKeyFingerprintError";
|
|
83
132
|
}
|
|
84
133
|
};
|
|
134
|
+
var KeyNotFoundError = class extends NotFoundError {
|
|
135
|
+
constructor(data = {}) {
|
|
136
|
+
super({ message: data.message || "Key not found", details: data.details });
|
|
137
|
+
this.name = "KeyNotFoundError";
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var NonceKeyBindingError = class extends ValidationError {
|
|
141
|
+
constructor(data = {}) {
|
|
142
|
+
super({
|
|
143
|
+
message: data.message || "nonce must be the fingerprint of the submitted public key",
|
|
144
|
+
details: data.details
|
|
145
|
+
});
|
|
146
|
+
this.name = "NonceKeyBindingError";
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
var NativeSignInUnsupportedError = class extends ValidationError {
|
|
150
|
+
constructor(data = {}) {
|
|
151
|
+
super({
|
|
152
|
+
message: data.message || "This provider does not support native id_token sign-in.",
|
|
153
|
+
details: data.details
|
|
154
|
+
});
|
|
155
|
+
this.name = "NativeSignInUnsupportedError";
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var UnverifiedEmailLinkError = class extends ValidationError {
|
|
159
|
+
constructor(data = {}) {
|
|
160
|
+
super({
|
|
161
|
+
message: data.message || "Cannot link to existing account with unverified email. Please verify your email with the provider first.",
|
|
162
|
+
details: data.details
|
|
163
|
+
});
|
|
164
|
+
this.name = "UnverifiedEmailLinkError";
|
|
165
|
+
}
|
|
166
|
+
};
|
|
85
167
|
var VerificationTokenPurposeMismatchError = class extends ValidationError {
|
|
86
168
|
constructor(data = {}) {
|
|
87
169
|
const expected = data.expected || "unknown";
|
|
@@ -102,6 +184,24 @@ var VerificationTokenTargetMismatchError = class extends ValidationError {
|
|
|
102
184
|
this.name = "VerificationTokenTargetMismatchError";
|
|
103
185
|
}
|
|
104
186
|
};
|
|
187
|
+
var ReservedUsernameError = class extends ValidationError {
|
|
188
|
+
constructor(data = {}) {
|
|
189
|
+
super({
|
|
190
|
+
message: data.message || "This username is reserved",
|
|
191
|
+
details: { username: data.username, ...data.details }
|
|
192
|
+
});
|
|
193
|
+
this.name = "ReservedUsernameError";
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
var UsernameAlreadyTakenError = class extends ConflictError {
|
|
197
|
+
constructor(data = {}) {
|
|
198
|
+
super({
|
|
199
|
+
message: data.message || "Username is already taken",
|
|
200
|
+
details: { username: data.username, ...data.details }
|
|
201
|
+
});
|
|
202
|
+
this.name = "UsernameAlreadyTakenError";
|
|
203
|
+
}
|
|
204
|
+
};
|
|
105
205
|
var InsufficientPermissionsError = class extends ForbiddenError {
|
|
106
206
|
constructor(data = {}) {
|
|
107
207
|
const requiredPermissions = data.requiredPermissions || [];
|
|
@@ -128,19 +228,79 @@ var authErrorRegistry = new ErrorRegistry();
|
|
|
128
228
|
authErrorRegistry.append([
|
|
129
229
|
InvalidCredentialsError,
|
|
130
230
|
InvalidTokenError,
|
|
231
|
+
InvalidSocialTokenError,
|
|
131
232
|
TokenExpiredError,
|
|
132
233
|
KeyExpiredError,
|
|
133
234
|
AccountDisabledError,
|
|
235
|
+
AccountPendingDeletionError,
|
|
236
|
+
DeletionAlreadyRequestedError,
|
|
237
|
+
DeletionNotRequestedError,
|
|
238
|
+
ImmediateDeletionNotAllowedError,
|
|
134
239
|
AccountAlreadyExistsError,
|
|
240
|
+
RegistrationRejectedError,
|
|
241
|
+
ReservedUsernameError,
|
|
242
|
+
UsernameAlreadyTakenError,
|
|
135
243
|
InvalidVerificationCodeError,
|
|
136
244
|
InvalidVerificationTokenError,
|
|
137
245
|
InvalidKeyFingerprintError,
|
|
246
|
+
NonceKeyBindingError,
|
|
247
|
+
NativeSignInUnsupportedError,
|
|
248
|
+
UnverifiedEmailLinkError,
|
|
249
|
+
KeyNotFoundError,
|
|
250
|
+
KeyIdAlreadyRegisteredError,
|
|
138
251
|
VerificationTokenPurposeMismatchError,
|
|
139
252
|
VerificationTokenTargetMismatchError,
|
|
140
253
|
InsufficientPermissionsError,
|
|
141
254
|
InsufficientRoleError
|
|
142
255
|
]);
|
|
143
256
|
|
|
257
|
+
// src/generated/route-map.ts
|
|
258
|
+
var routeMap = {
|
|
259
|
+
sendVerificationCode: { method: "POST", path: "/_auth/codes" },
|
|
260
|
+
verifyCode: { method: "POST", path: "/_auth/codes/verify" },
|
|
261
|
+
register: { method: "POST", path: "/_auth/register" },
|
|
262
|
+
login: { method: "POST", path: "/_auth/login" },
|
|
263
|
+
logout: { method: "POST", path: "/_auth/logout" },
|
|
264
|
+
rotateKey: { method: "POST", path: "/_auth/keys/rotate" },
|
|
265
|
+
listKeys: { method: "POST", path: "/_auth/keys/list" },
|
|
266
|
+
revokeKey: { method: "POST", path: "/_auth/keys/revoke" },
|
|
267
|
+
revokeAllKeys: { method: "POST", path: "/_auth/keys/revoke-all" },
|
|
268
|
+
changePassword: { method: "PUT", path: "/_auth/password" },
|
|
269
|
+
getAuthSession: { method: "GET", path: "/_auth/session" },
|
|
270
|
+
issueOneTimeToken: { method: "POST", path: "/_auth/tokens" },
|
|
271
|
+
getInvitation: { method: "GET", path: "/_auth/invitations/:token" },
|
|
272
|
+
acceptInvitation: { method: "POST", path: "/_auth/invitations/accept" },
|
|
273
|
+
createInvitation: { method: "POST", path: "/_auth/invitations" },
|
|
274
|
+
listInvitations: { method: "GET", path: "/_auth/invitations" },
|
|
275
|
+
cancelInvitation: { method: "POST", path: "/_auth/invitations/cancel" },
|
|
276
|
+
resendInvitation: { method: "POST", path: "/_auth/invitations/resend" },
|
|
277
|
+
deleteInvitation: { method: "POST", path: "/_auth/invitations/delete" },
|
|
278
|
+
getUserProfile: { method: "GET", path: "/_auth/users/profile" },
|
|
279
|
+
updateUserProfile: { method: "PATCH", path: "/_auth/users/profile" },
|
|
280
|
+
checkUsername: { method: "GET", path: "/_auth/users/username/check" },
|
|
281
|
+
updateUsername: { method: "PATCH", path: "/_auth/users/username" },
|
|
282
|
+
updateLocale: { method: "PATCH", path: "/_auth/users/locale" },
|
|
283
|
+
oauthGoogleStart: { method: "GET", path: "/_auth/oauth/google" },
|
|
284
|
+
oauthGoogleCallback: { method: "GET", path: "/_auth/oauth/google/callback" },
|
|
285
|
+
oauthStart: { method: "POST", path: "/_auth/oauth/start" },
|
|
286
|
+
oauthProviders: { method: "GET", path: "/_auth/oauth/providers" },
|
|
287
|
+
getGoogleOAuthUrl: { method: "POST", path: "/_auth/oauth/google/url" },
|
|
288
|
+
oauthFinalize: { method: "POST", path: "/_auth/oauth/finalize" },
|
|
289
|
+
oauthProviderStart: { method: "GET", path: "/_auth/oauth/:provider" },
|
|
290
|
+
oauthProviderCallback: { method: "GET", path: "/_auth/oauth/:provider/callback" },
|
|
291
|
+
getProviderOAuthUrl: { method: "POST", path: "/_auth/oauth/:provider/url" },
|
|
292
|
+
oauthNative: { method: "POST", path: "/_auth/oauth/:provider/native" },
|
|
293
|
+
oauthUnlinkNotify: { method: "POST", path: "/_auth/oauth/:provider/unlink-notify" },
|
|
294
|
+
oauthUnlinkNotifyGet: { method: "GET", path: "/_auth/oauth/:provider/unlink-notify" },
|
|
295
|
+
listRoles: { method: "GET", path: "/_auth/admin/roles" },
|
|
296
|
+
createAdminRole: { method: "POST", path: "/_auth/admin/roles" },
|
|
297
|
+
updateAdminRole: { method: "PATCH", path: "/_auth/admin/roles/:id" },
|
|
298
|
+
deleteAdminRole: { method: "DELETE", path: "/_auth/admin/roles/:id" },
|
|
299
|
+
updateUserRole: { method: "PATCH", path: "/_auth/admin/users/:userId/role" },
|
|
300
|
+
requestAccountDeletion: { method: "POST", path: "/_auth/deletion/request" },
|
|
301
|
+
cancelAccountDeletion: { method: "POST", path: "/_auth/deletion/cancel" }
|
|
302
|
+
};
|
|
303
|
+
|
|
144
304
|
// src/lib/types.ts
|
|
145
305
|
var EMAIL_PATTERN = "^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
|
|
146
306
|
var PHONE_PATTERN = "^\\+[1-9]\\d{1,14}$";
|
|
@@ -274,9 +434,14 @@ var BUILTIN_ROLE_PERMISSIONS = {
|
|
|
274
434
|
|
|
275
435
|
// src/server/types.ts
|
|
276
436
|
var KEY_ALGORITHM = ["ES256", "RS256"];
|
|
437
|
+
var KEY_PLATFORM = ["ios", "android", "web", "desktop"];
|
|
438
|
+
var KEY_DEVICE_NAME_MAX_LENGTH = 64;
|
|
277
439
|
var INVITATION_STATUSES = ["pending", "accepted", "expired", "cancelled"];
|
|
278
|
-
var USER_STATUSES = ["active", "inactive", "suspended"];
|
|
279
|
-
var SOCIAL_PROVIDERS = ["google", "github", "kakao", "naver"];
|
|
440
|
+
var USER_STATUSES = ["active", "inactive", "suspended", "pending_deletion", "deleted"];
|
|
441
|
+
var SOCIAL_PROVIDERS = ["google", "apple", "github", "kakao", "naver", "superself"];
|
|
442
|
+
var ACCOUNT_DELETION_REQUEST_STATUSES = ["pending", "cancelled", "completed"];
|
|
443
|
+
var ACCOUNT_DELETION_REQUESTED_BY = ["self", "admin"];
|
|
444
|
+
var PURGE_STRATEGIES = ["anonymize", "hard-delete"];
|
|
280
445
|
|
|
281
446
|
// ../../node_modules/.pnpm/@sinclair+typebox@0.34.41/node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
|
|
282
447
|
var value_exports = {};
|
|
@@ -2899,9 +3064,18 @@ var PhoneSchema = Type.String({
|
|
|
2899
3064
|
pattern: PHONE_PATTERN2,
|
|
2900
3065
|
description: "Phone number in E.164 format (e.g., +821012345678)"
|
|
2901
3066
|
});
|
|
3067
|
+
var DeviceNameSchema = Type.String({
|
|
3068
|
+
maxLength: KEY_DEVICE_NAME_MAX_LENGTH,
|
|
3069
|
+
description: `Device label shown in the key list (max ${KEY_DEVICE_NAME_MAX_LENGTH} chars)`
|
|
3070
|
+
});
|
|
3071
|
+
var PlatformSchema = Type.Union(
|
|
3072
|
+
KEY_PLATFORM.map((platform) => Type.Literal(platform)),
|
|
3073
|
+
{ description: "Platform the key lives on" }
|
|
3074
|
+
);
|
|
2902
3075
|
var PasswordSchema = Type.String({
|
|
2903
3076
|
minLength: 8,
|
|
2904
|
-
|
|
3077
|
+
maxLength: 72,
|
|
3078
|
+
description: "User password (8\u201372 characters). bcrypt silently ignores bytes past 72, so longer inputs are rejected rather than truncated."
|
|
2905
3079
|
});
|
|
2906
3080
|
var TargetTypeSchema = Type.Union([
|
|
2907
3081
|
Type.Literal("email"),
|
|
@@ -2915,17 +3089,20 @@ var VerificationPurposeSchema = Type.Union([
|
|
|
2915
3089
|
Type.Literal("login"),
|
|
2916
3090
|
Type.Literal("password_reset"),
|
|
2917
3091
|
Type.Literal("email_change"),
|
|
2918
|
-
Type.Literal("phone_change")
|
|
3092
|
+
Type.Literal("phone_change"),
|
|
3093
|
+
Type.Literal("account_deletion")
|
|
2919
3094
|
], {
|
|
2920
3095
|
description: "Purpose of verification"
|
|
2921
3096
|
});
|
|
2922
|
-
var VERIFICATION_PURPOSES = ["registration", "login", "password_reset", "email_change", "phone_change"];
|
|
3097
|
+
var VERIFICATION_PURPOSES = ["registration", "login", "password_reset", "email_change", "phone_change", "account_deletion"];
|
|
2923
3098
|
|
|
2924
3099
|
// src/index.ts
|
|
2925
3100
|
var authApi = createApi({
|
|
2926
3101
|
errorRegistry: [authErrorRegistry]
|
|
2927
3102
|
});
|
|
2928
3103
|
export {
|
|
3104
|
+
ACCOUNT_DELETION_REQUESTED_BY,
|
|
3105
|
+
ACCOUNT_DELETION_REQUEST_STATUSES,
|
|
2929
3106
|
BASE64_PATTERN,
|
|
2930
3107
|
BUILTIN_PERMISSIONS,
|
|
2931
3108
|
BUILTIN_ROLES,
|
|
@@ -2936,11 +3113,13 @@ export {
|
|
|
2936
3113
|
KEY_ALGORITHM,
|
|
2937
3114
|
PERMISSION_CATEGORIES,
|
|
2938
3115
|
PHONE_PATTERN,
|
|
3116
|
+
PURGE_STRATEGIES,
|
|
2939
3117
|
SOCIAL_PROVIDERS,
|
|
2940
3118
|
USER_STATUSES,
|
|
2941
3119
|
UUID_PATTERN,
|
|
2942
3120
|
VERIFICATION_PURPOSES,
|
|
2943
3121
|
VERIFICATION_TARGET_TYPES,
|
|
2944
|
-
authApi
|
|
3122
|
+
authApi,
|
|
3123
|
+
routeMap as authRouteMap
|
|
2945
3124
|
};
|
|
2946
3125
|
//# sourceMappingURL=index.js.map
|