@spfn/auth 0.3.0-beta.8 → 0.3.0-beta.9
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/README.md +31 -7
- package/dist/client-proof.js +1 -1
- package/dist/client-proof.js.map +1 -1
- package/dist/config.d.ts +18 -0
- package/dist/config.js +11 -4
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +23 -2
- package/dist/errors.js +12 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/{machine-principals-Bd5hp76H.d.ts → machine-principals-cC9TQZIt.d.ts} +4 -0
- package/dist/server.d.ts +20 -3
- package/dist/server.js +119 -5
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -586,10 +586,14 @@ declare const KEY_FINGERPRINT_PREFIX_LENGTH = 8;
|
|
|
586
586
|
*
|
|
587
587
|
* @throws KeyIdAlreadyRegisteredError keyId가 이미 쓰인 값일 때 (자기 폐기 키 재사용 · 남의 키)
|
|
588
588
|
* @throws InvalidKeyFingerprintError fingerprint가 publicKey와 맞지 않을 때
|
|
589
|
+
* @throws KeyAlgorithmMismatchError 키의 SPKI 타입이 선언된 algorithm과 다를 때
|
|
589
590
|
*/
|
|
590
591
|
declare function registerPublicKeyService(params: RegisterPublicKeyParams): Promise<void>;
|
|
591
592
|
/**
|
|
592
593
|
* Rotate user's public key (revoke old, register new)
|
|
594
|
+
*
|
|
595
|
+
* @throws InvalidKeyFingerprintError fingerprint가 newPublicKey와 맞지 않을 때
|
|
596
|
+
* @throws KeyAlgorithmMismatchError 새 키의 SPKI 타입이 선언된 algorithm과 다를 때
|
|
593
597
|
*/
|
|
594
598
|
declare function rotateKeyService(params: RotateKeyParams): Promise<RotateKeyResult>;
|
|
595
599
|
/**
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AuthInitOptions, o as OAuthProvider, l as VerificationPurpose, j as PermissionCategory, p as AuthContext } from './machine-principals-
|
|
2
|
-
export { q as ApproveDeviceAuthParams, r as AuthProfileOutcome, s as AuthProfileVerifier, t as ChangePasswordParams, u as CompleteSignupParams, v as ConfirmSignupLinkParams, C as ConfirmSignupLinkResult, w as DenyDeviceAuthParams, x as DeviceAuthApprovedResult, y as DeviceAuthInfoParams, D as DeviceAuthInfoResult, z as DeviceAuthPendingResult, B as DeviceAuthPollResponseSchema, E as DeviceNameSchema, F as EmailSchema, G as FingerprintSchema, I as IssueOneTimeTokenResult, H as KEY_FINGERPRINT_PREFIX_LENGTH, J as KeyIdSchema, K as KeySummary, M as LoginParams, L as LoginResult, N as LogoutParams, Q as MachinePrincipal, T as MachineVerifierRegistration, W as NativeVerifyOptions, X as NormalizedIdentity, Y as OAuthCallbackParams, Z as OAuthCallbackResult, _ as OAuthCodeExchangeOptions, $ as OAuthNativeParams, f as OAuthNativeResult, a0 as OAuthStartParams, O as OAuthStartResult, a1 as OAuthTokens, a2 as PasswordSchema, a3 as PhoneSchema, a4 as PlatformSchema, a5 as PollDeviceAuthParams, a6 as PollDeviceAuthResult, a7 as PublicKeySchema, a8 as RegisterParams, a9 as RegisterPublicKeyParams, a as RegisterResult, aa as RequestSignupLinkParams, b as RequestSignupLinkResult, ab as RevokeAllKeysParams, e as RevokeAllKeysResult, ac as RevokeKeyParams, ad as RotateKeyParams, d as RotateKeyResult, ae as SendVerificationCodeParams, S as SendVerificationCodeResult, af as StartDeviceAuthParams, c as StartDeviceAuthResult, ag as TargetTypeSchema, ah as UnlinkNotification, ai as UnlinkNotifyRejection, aj as UnlinkNotifyRequest, ak as UnlinkNotifyResult, al as UserCodeSchema, V as VERIFICATION_PURPOSES, k as VERIFICATION_TARGET_TYPES, am as VerificationPurposeSchema, n as VerificationTargetType, an as VerifyCodeParams, ao as VerifyCodeResult, ap as approveDeviceAuthService, m as authRouter, aq as authenticate, ar as buildOAuthErrorUrl, as as changePasswordService, at as completeSignupService, au as confirmSignupLinkService, av as denyDeviceAuthService, aw as getDeviceAuthInfoService, ax as getEnabledOAuthProviders, ay as getGoogleAccessToken, az as getMachinePrincipal, aA as getOAuthProvider, aB as getRegisteredProviders, aC as isOAuthProviderEnabled, aD as isSafeReturnPath, aE as issueOneTimeTokenService, aF as listKeysService, aG as loginService, aH as logoutService, aI as machineAuth, aJ as oauthCallbackService, aK as oauthNativeService, aL as oauthStartService, aM as oauthUnlinkNotifyService, aN as optionalAuth, aO as pollDeviceAuthService, aP as registerAuthProfile, aQ as registerMachineVerifier, aR as registerOAuthProvider, aS as registerPublicKeyService, aT as registerService, aU as requestSignupLinkService, aV as requireEnabledProvider, aW as requireMachineScope, aX as resolveAuthenticatedUser, aY as revokeAllKeysService, aZ as revokeKeyService, a_ as rotateKeyService, a$ as runAuthProfile, b0 as selectAuthProfile, b1 as sendVerificationCodeService, b2 as startDeviceAuthService, b3 as verifyCodeService, b4 as verifyOneTimeTokenService } from './machine-principals-
|
|
1
|
+
import { A as AuthInitOptions, o as OAuthProvider, l as VerificationPurpose, j as PermissionCategory, p as AuthContext } from './machine-principals-cC9TQZIt.js';
|
|
2
|
+
export { q as ApproveDeviceAuthParams, r as AuthProfileOutcome, s as AuthProfileVerifier, t as ChangePasswordParams, u as CompleteSignupParams, v as ConfirmSignupLinkParams, C as ConfirmSignupLinkResult, w as DenyDeviceAuthParams, x as DeviceAuthApprovedResult, y as DeviceAuthInfoParams, D as DeviceAuthInfoResult, z as DeviceAuthPendingResult, B as DeviceAuthPollResponseSchema, E as DeviceNameSchema, F as EmailSchema, G as FingerprintSchema, I as IssueOneTimeTokenResult, H as KEY_FINGERPRINT_PREFIX_LENGTH, J as KeyIdSchema, K as KeySummary, M as LoginParams, L as LoginResult, N as LogoutParams, Q as MachinePrincipal, T as MachineVerifierRegistration, W as NativeVerifyOptions, X as NormalizedIdentity, Y as OAuthCallbackParams, Z as OAuthCallbackResult, _ as OAuthCodeExchangeOptions, $ as OAuthNativeParams, f as OAuthNativeResult, a0 as OAuthStartParams, O as OAuthStartResult, a1 as OAuthTokens, a2 as PasswordSchema, a3 as PhoneSchema, a4 as PlatformSchema, a5 as PollDeviceAuthParams, a6 as PollDeviceAuthResult, a7 as PublicKeySchema, a8 as RegisterParams, a9 as RegisterPublicKeyParams, a as RegisterResult, aa as RequestSignupLinkParams, b as RequestSignupLinkResult, ab as RevokeAllKeysParams, e as RevokeAllKeysResult, ac as RevokeKeyParams, ad as RotateKeyParams, d as RotateKeyResult, ae as SendVerificationCodeParams, S as SendVerificationCodeResult, af as StartDeviceAuthParams, c as StartDeviceAuthResult, ag as TargetTypeSchema, ah as UnlinkNotification, ai as UnlinkNotifyRejection, aj as UnlinkNotifyRequest, ak as UnlinkNotifyResult, al as UserCodeSchema, V as VERIFICATION_PURPOSES, k as VERIFICATION_TARGET_TYPES, am as VerificationPurposeSchema, n as VerificationTargetType, an as VerifyCodeParams, ao as VerifyCodeResult, ap as approveDeviceAuthService, m as authRouter, aq as authenticate, ar as buildOAuthErrorUrl, as as changePasswordService, at as completeSignupService, au as confirmSignupLinkService, av as denyDeviceAuthService, aw as getDeviceAuthInfoService, ax as getEnabledOAuthProviders, ay as getGoogleAccessToken, az as getMachinePrincipal, aA as getOAuthProvider, aB as getRegisteredProviders, aC as isOAuthProviderEnabled, aD as isSafeReturnPath, aE as issueOneTimeTokenService, aF as listKeysService, aG as loginService, aH as logoutService, aI as machineAuth, aJ as oauthCallbackService, aK as oauthNativeService, aL as oauthStartService, aM as oauthUnlinkNotifyService, aN as optionalAuth, aO as pollDeviceAuthService, aP as registerAuthProfile, aQ as registerMachineVerifier, aR as registerOAuthProvider, aS as registerPublicKeyService, aT as registerService, aU as requestSignupLinkService, aV as requireEnabledProvider, aW as requireMachineScope, aX as resolveAuthenticatedUser, aY as revokeAllKeysService, aZ as revokeKeyService, a_ as rotateKeyService, a$ as runAuthProfile, b0 as selectAuthProfile, b1 as sendVerificationCodeService, b2 as startDeviceAuthService, b3 as verifyCodeService, b4 as verifyOneTimeTokenService } from './machine-principals-cC9TQZIt.js';
|
|
3
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
4
4
|
import { K as KeyAlgorithmType, d as InvitationStatus, j as SocialProvider, c as AccountDeletionRequestedBy, i as PurgeStrategy } from './types-DYyhze28.js';
|
|
5
5
|
export { A as ACCOUNT_DELETION_REQUESTED_BY, a as ACCOUNT_DELETION_REQUEST_STATUSES, b as AccountDeletionRequestStatus, I as INVITATION_STATUSES, e as KEY_ALGORITHM, f as KEY_DEVICE_NAME_MAX_LENGTH, g as KEY_PLATFORM, h as KeyPlatformType, P as PURGE_STRATEGIES, S as SOCIAL_PROVIDERS, U as USER_STATUSES, k as UserStatus } from './types-DYyhze28.js';
|
|
@@ -6681,6 +6681,23 @@ declare function decodeToken(token: string): TokenPayload | null;
|
|
|
6681
6681
|
* ```
|
|
6682
6682
|
*/
|
|
6683
6683
|
declare function verifyKeyFingerprint(publicKeyB64: string, expectedFingerprint: string): boolean;
|
|
6684
|
+
/**
|
|
6685
|
+
* Refuses a public key whose SPKI type is not the one its declared algorithm
|
|
6686
|
+
* needs, before the key is stored.
|
|
6687
|
+
*
|
|
6688
|
+
* The algorithm column is what proof verification later reads, and nothing
|
|
6689
|
+
* re-derives it from the key material — so an EC key parked as RS256 is
|
|
6690
|
+
* accepted at enrollment and fails on every request afterwards, with the device
|
|
6691
|
+
* already believing it is enrolled. Refusing at registration is what keeps that
|
|
6692
|
+
* mismatch from ever being written.
|
|
6693
|
+
*
|
|
6694
|
+
* Bytes that are no SPKI public key at all are refused the same way: the parser
|
|
6695
|
+
* throws on them, and an unreadable key is the same defect as a mismatched one.
|
|
6696
|
+
* Neither is a server fault, so both answer 400 rather than falling out as a 500.
|
|
6697
|
+
*
|
|
6698
|
+
* @throws KeyAlgorithmMismatchError when the key is not the algorithm's type.
|
|
6699
|
+
*/
|
|
6700
|
+
declare function assertKeyMatchesAlgorithm(publicKeyB64: string, algorithm: KeyAlgorithmType): void;
|
|
6684
6701
|
|
|
6685
6702
|
/**
|
|
6686
6703
|
* @spfn/auth - Permission Middleware
|
|
@@ -7980,4 +7997,4 @@ type AuthDeletionCancelledPayload = typeof authDeletionCancelledEvent._payload;
|
|
|
7980
7997
|
type AuthDeletionCompletedPayload = typeof authDeletionCompletedEvent._payload;
|
|
7981
7998
|
type OAuthUnlinkedPayload = typeof oauthUnlinkedEvent._payload;
|
|
7982
7999
|
|
|
7983
|
-
export { type AccountDeletionPurgeUser, type AccountDeletionRequest, AccountDeletionRequestedBy, AccountDeletionRequestsRepository, type AuthConfig, AuthContext, type AuthCsrfConfig, type AuthDeletionCancelledPayload, type AuthDeletionCompletedPayload, type AuthDeletionConfig, type AuthDeletionRequestedPayload, type AuthDeviceAuthConfig, type AuthLifecycleConfig, type AuthLifecycleOptions, type AuthLoginPayload, type AuthMetadataEntity, AuthMetadataRepository, AuthProviderSchema, type AuthRegisterPayload, type BeforeRegisterContext, COOKIE_NAMES, CSRF_HEADER, type CancelAccountDeletionParams, type CancelAccountDeletionResult, type CreateOAuthStateParams, type CsrfMode, DEFAULT_DELETION_ALLOW_SELF_IMMEDIATE, DEFAULT_DELETION_GRACE_PERIOD_DAYS, DEFAULT_DELETION_PURGE_CRON, DEFAULT_DELETION_PURGE_STRATEGY, DEFAULT_DELETION_SEND_NOTIFICATIONS, DEFAULT_DEVICE_AUTH_INTERVAL_MS, DEFAULT_DEVICE_AUTH_TTL_MS, DEVICE_AUTH_STATUSES, type DecryptedOAuthToken, type DeviceAuthStatus, type DeviceAuthorization, DeviceAuthorizationsRepository, type EmailNormalizationResult, EnvironmentKeyringTokenCipher, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, type InvitationAcceptedPayload, type InvitationCreatedPayload, InvitationStatus, InvitationsRepository, type IssuedOpsToken, KeyAlgorithmType, KeysRepository, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewDeviceAuthorization, type NewInvitation, type NewOpsToken, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewSignupLinkToken, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, OAuthProvider, type OAuthState, type OAuthTokenCipher, type OAuthTokenContext, type OAuthTokenType, type OAuthUnlinkedPayload, type OpsToken, OpsTokensRepository, type PendingDeletionInfo, type Permission, type PermissionEntity, PermissionsRepository, PurgeStrategy, type PurgeUserResult, type RegisterChannel, type RequestAccountDeletionParams, type RequestAccountDeletionResult, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionPayload, type SignupLinkToken, SignupLinkTokensRepository, SocialAccountsRepository, SocialProvider, type SweepDuePurgesResult, type TokenPayload, USER_CODE_ALPHABET, USER_CODE_LENGTH, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOpsToken, type VerifyIdTokenParams, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, appleProvider, assertCanAssignRole, authDeletionCancelledEvent, authDeletionCompletedEvent, authDeletionRequestedEvent, authJobRouter, authLogger, authLoginEvent, authMetadata, authMetadataRepository, authRegisterEvent, authSchema, cancelAccountDeletionService, cancelInvitation, checkUsernameAvailableService, configureAuth, configureDeletion, configureDeviceAuth, configureOAuthTokenCipher, createAuthDeletionJobRouter, createAuthDeletionPurgeJob, createAuthLifecycle, createInvitation, createOAuthState, createRole, decodeToken, decryptToken, deleteInvitation, deleteRole, deriveCsrfToken, deviceAuthorizations, deviceAuthorizationsRepository, encryptToken, exchangeCodeForTokens, expireOldInvitations, formatUserCode, generateDeviceCode, generateOAuthNonce, generateToken, generateUserCode, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getCsrfExemptPaths, getCsrfMode, getDeletionConfig, getDeviceAuthConfig, getDummyPasswordHash, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, githubProvider, googleProvider, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashDeviceCode, hashPassword, initOneTimeTokenManager, initializeAuth, invitationAcceptedEvent, invitationCreatedEvent, invitationsRepository, isEncrypted, isGoogleOAuthEnabled, issueOpsTokenService, kakaoProvider, keysRepository, listInvitations, listOpsTokensService, matchOAuthCsrfCookies, matchesCsrfToken, naverProvider, normalizeEmail, normalizeOptionalEmail, normalizeStoredEmails, normalizeUserCode, oauthUnlinkedEvent, oneTimeTokenAuth, opsTokenAuth, opsTokens, opsTokensRepository, parseDuration, permissions, permissionsRepository, purgeUserService, refreshAccessToken, removePermissionFromRole, requestAccountDeletionService, requireAnyPermission, requireOpsScope, requirePermissions, requireRole, resendInvitation, revokeOpsTokenService, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, runBeforeRegister, setRolePermissions, signupLinkTokens, signupLinkTokensRepository, socialAccountsRepository, sweepDuePurges, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken };
|
|
8000
|
+
export { type AccountDeletionPurgeUser, type AccountDeletionRequest, AccountDeletionRequestedBy, AccountDeletionRequestsRepository, type AuthConfig, AuthContext, type AuthCsrfConfig, type AuthDeletionCancelledPayload, type AuthDeletionCompletedPayload, type AuthDeletionConfig, type AuthDeletionRequestedPayload, type AuthDeviceAuthConfig, type AuthLifecycleConfig, type AuthLifecycleOptions, type AuthLoginPayload, type AuthMetadataEntity, AuthMetadataRepository, AuthProviderSchema, type AuthRegisterPayload, type BeforeRegisterContext, COOKIE_NAMES, CSRF_HEADER, type CancelAccountDeletionParams, type CancelAccountDeletionResult, type CreateOAuthStateParams, type CsrfMode, DEFAULT_DELETION_ALLOW_SELF_IMMEDIATE, DEFAULT_DELETION_GRACE_PERIOD_DAYS, DEFAULT_DELETION_PURGE_CRON, DEFAULT_DELETION_PURGE_STRATEGY, DEFAULT_DELETION_SEND_NOTIFICATIONS, DEFAULT_DEVICE_AUTH_INTERVAL_MS, DEFAULT_DEVICE_AUTH_TTL_MS, DEVICE_AUTH_STATUSES, type DecryptedOAuthToken, type DeviceAuthStatus, type DeviceAuthorization, DeviceAuthorizationsRepository, type EmailNormalizationResult, EnvironmentKeyringTokenCipher, type GoogleTokenResponse, type GoogleUserInfo, type Invitation, type InvitationAcceptedPayload, type InvitationCreatedPayload, InvitationStatus, InvitationsRepository, type IssuedOpsToken, KeyAlgorithmType, KeysRepository, type NewAccountDeletionRequest, type NewAuthMetadataEntity, type NewDeviceAuthorization, type NewInvitation, type NewOpsToken, type NewPermission, type NewPermissionEntity, type NewRole, type NewRoleEntity, type NewRolePermission, type NewSignupLinkToken, type NewUser, type NewUserPermission, type NewUserProfile, type NewUserPublicKey, type NewUserSocialAccount, type NewVerificationCode, OAuthProvider, type OAuthState, type OAuthTokenCipher, type OAuthTokenContext, type OAuthTokenType, type OAuthUnlinkedPayload, type OpsToken, OpsTokensRepository, type PendingDeletionInfo, type Permission, type PermissionEntity, PermissionsRepository, PurgeStrategy, type PurgeUserResult, type RegisterChannel, type RequestAccountDeletionParams, type RequestAccountDeletionResult, type Role, type RoleEntity, type RoleGuardOptions, type RolePermission, RolePermissionsRepository, RolesRepository, type SessionPayload, type SignupLinkToken, SignupLinkTokensRepository, SocialAccountsRepository, SocialProvider, type SweepDuePurgesResult, type TokenPayload, USER_CODE_ALPHABET, USER_CODE_LENGTH, type UpdateProfileParams, type User, type UserPermission, UserPermissionsRepository, type UserProfile, UserProfilesRepository, type UserPublicKey, type UserSocialAccount, UsersRepository, type VerificationCode, VerificationCodesRepository, VerificationPurpose, type VerifiedOpsToken, type VerifyIdTokenParams, acceptInvitation, accountDeletionRequests, accountDeletionRequestsRepository, addPermissionToRole, appleProvider, assertCanAssignRole, assertKeyMatchesAlgorithm, authDeletionCancelledEvent, authDeletionCompletedEvent, authDeletionRequestedEvent, authJobRouter, authLogger, authLoginEvent, authMetadata, authMetadataRepository, authRegisterEvent, authSchema, cancelAccountDeletionService, cancelInvitation, checkUsernameAvailableService, configureAuth, configureDeletion, configureDeviceAuth, configureOAuthTokenCipher, createAuthDeletionJobRouter, createAuthDeletionPurgeJob, createAuthLifecycle, createInvitation, createOAuthState, createRole, decodeToken, decryptToken, deleteInvitation, deleteRole, deriveCsrfToken, deviceAuthorizations, deviceAuthorizationsRepository, encryptToken, exchangeCodeForTokens, expireOldInvitations, formatUserCode, generateDeviceCode, generateOAuthNonce, generateToken, generateUserCode, getAllRoles, getAuth, getAuthConfig, getAuthSessionService, getCsrfExemptPaths, getCsrfMode, getDeletionConfig, getDeviceAuthConfig, getDummyPasswordHash, getGoogleAuthUrl, getGoogleOAuthConfig, getGoogleUserInfo, getInvitationByToken, getInvitationWithDetails, getKeyId, getLocale, getOneTimeTokenManager, getOpsToken, getOptionalAuth, getPendingDeletionInfo, getRole, getRoleByName, getRolePermissions, getSessionTtl, getUser, getUserByEmailService, getUserByIdService, getUserByPhoneService, getUserId, getUserPermissions, getUserProfileService, getUserRole, githubProvider, googleProvider, hasAllPermissions, hasAnyPermission, hasAnyRole, hasPermission, hasRole, hashDeviceCode, hashPassword, initOneTimeTokenManager, initializeAuth, invitationAcceptedEvent, invitationCreatedEvent, invitationsRepository, isEncrypted, isGoogleOAuthEnabled, issueOpsTokenService, kakaoProvider, keysRepository, listInvitations, listOpsTokensService, matchOAuthCsrfCookies, matchesCsrfToken, naverProvider, normalizeEmail, normalizeOptionalEmail, normalizeStoredEmails, normalizeUserCode, oauthUnlinkedEvent, oneTimeTokenAuth, opsTokenAuth, opsTokens, opsTokensRepository, parseDuration, permissions, permissionsRepository, purgeUserService, refreshAccessToken, removePermissionFromRole, requestAccountDeletionService, requireAnyPermission, requireOpsScope, requirePermissions, requireRole, resendInvitation, revokeOpsTokenService, roleGuard, rolePermissions, rolePermissionsRepository, roles, rolesRepository, runBeforeRegister, setRolePermissions, signupLinkTokens, signupLinkTokensRepository, socialAccountsRepository, sweepDuePurges, updateLastLoginService, updateLocaleService, updateRole, updateUserProfileService, updateUserService, updateUsernameService, userInvitations, userPermissions, userPermissionsRepository, userProfiles, userProfilesRepository, userPublicKeys, userSocialAccounts, users, usersRepository, validateInvitation, validatePasswordStrength, verificationCodes, verificationCodesRepository, verifyClientToken, verifyIdToken, verifyKeyFingerprint, verifyOAuthState, verifyOpsTokenService, verifyPassword, verifyToken };
|
package/dist/server.js
CHANGED
|
@@ -7568,7 +7568,7 @@ var init_schema5 = __esm({
|
|
|
7568
7568
|
},
|
|
7569
7569
|
SPFN_AUTH_GOOGLE_REDIRECT_URI: {
|
|
7570
7570
|
...envString({
|
|
7571
|
-
description: "Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/google/callback
|
|
7571
|
+
description: "Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/google/callback. The override must stay on the web app origin at this exact path \u2014 the CSRF cookie for the callback is host-only and the app rewrites /_auth/:path* to the API, so a callback that lands anywhere else is refused for CSRF. Checked at boot: a value off the web app origin or off the callback path refuses to start. The one case for an override elsewhere is the direct POST /_auth/oauth/start flow on a split deployment (no Next.js interceptor, so its CSRF cookie is on the API host), which also needs SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK=off.",
|
|
7572
7572
|
required: false,
|
|
7573
7573
|
examples: [
|
|
7574
7574
|
"https://app.example.com/_auth/oauth/google/callback",
|
|
@@ -7611,7 +7611,7 @@ var init_schema5 = __esm({
|
|
|
7611
7611
|
},
|
|
7612
7612
|
SPFN_AUTH_KAKAO_REDIRECT_URI: {
|
|
7613
7613
|
...envString({
|
|
7614
|
-
description: "Kakao OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/kakao/callback.",
|
|
7614
|
+
description: "Kakao OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/kakao/callback. The override must stay on the web app origin at this exact path \u2014 the CSRF cookie for the callback is host-only and the app rewrites /_auth/:path* to the API, so a callback that lands anywhere else is refused for CSRF. Checked at boot: a value off the web app origin or off the callback path refuses to start. The one case for an override elsewhere is the direct POST /_auth/oauth/start flow on a split deployment (no Next.js interceptor, so its CSRF cookie is on the API host), which also needs SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK=off.",
|
|
7615
7615
|
required: false,
|
|
7616
7616
|
examples: ["https://app.example.com/_auth/oauth/kakao/callback"]
|
|
7617
7617
|
})
|
|
@@ -7636,7 +7636,7 @@ var init_schema5 = __esm({
|
|
|
7636
7636
|
},
|
|
7637
7637
|
SPFN_AUTH_NAVER_REDIRECT_URI: {
|
|
7638
7638
|
...envString({
|
|
7639
|
-
description: "Naver OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/naver/callback.",
|
|
7639
|
+
description: "Naver OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/naver/callback. The override must stay on the web app origin at this exact path \u2014 the CSRF cookie for the callback is host-only and the app rewrites /_auth/:path* to the API, so a callback that lands anywhere else is refused for CSRF. Checked at boot: a value off the web app origin or off the callback path refuses to start. The one case for an override elsewhere is the direct POST /_auth/oauth/start flow on a split deployment (no Next.js interceptor, so its CSRF cookie is on the API host), which also needs SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK=off.",
|
|
7640
7640
|
required: false,
|
|
7641
7641
|
examples: ["https://app.example.com/_auth/oauth/naver/callback"]
|
|
7642
7642
|
})
|
|
@@ -7668,11 +7668,18 @@ var init_schema5 = __esm({
|
|
|
7668
7668
|
},
|
|
7669
7669
|
SPFN_AUTH_GITHUB_REDIRECT_URI: {
|
|
7670
7670
|
...envString({
|
|
7671
|
-
description: "GitHub OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/github/callback.",
|
|
7671
|
+
description: "GitHub OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}/_auth/oauth/github/callback. The override must stay on the web app origin at this exact path \u2014 the CSRF cookie for the callback is host-only and the app rewrites /_auth/:path* to the API, so a callback that lands anywhere else is refused for CSRF. Checked at boot: a value off the web app origin or off the callback path refuses to start. The one case for an override elsewhere is the direct POST /_auth/oauth/start flow on a split deployment (no Next.js interceptor, so its CSRF cookie is on the API host), which also needs SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK=off.",
|
|
7672
7672
|
required: false,
|
|
7673
7673
|
examples: ["https://app.example.com/_auth/oauth/github/callback"]
|
|
7674
7674
|
})
|
|
7675
7675
|
},
|
|
7676
|
+
SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK: {
|
|
7677
|
+
...envString({
|
|
7678
|
+
description: 'Boot-time check of the four SPFN_AUTH_<PROVIDER>_REDIRECT_URI overrides: each one that is set must sit on the web app origin ({NEXT_PUBLIC_SPFN_APP_URL || SPFN_APP_URL}) at /_auth/oauth/<provider>/callback, because the callback CSRF cookie is host-only. "off" is the only value that disables the check \u2014 unset, "on" and anything else all run it.',
|
|
7679
|
+
required: false,
|
|
7680
|
+
examples: ["off"]
|
|
7681
|
+
})
|
|
7682
|
+
},
|
|
7676
7683
|
// ============================================================================
|
|
7677
7684
|
// Native Social Login (mobile/web id_token verification)
|
|
7678
7685
|
//
|
|
@@ -8474,6 +8481,7 @@ function validatePasswordStrength(password) {
|
|
|
8474
8481
|
import jwt from "jsonwebtoken";
|
|
8475
8482
|
import crypto2 from "crypto";
|
|
8476
8483
|
import { env as env2 } from "@spfn/auth/config";
|
|
8484
|
+
import { KeyAlgorithmMismatchError } from "@spfn/auth/errors";
|
|
8477
8485
|
var PUBLIC_KEY_CACHE_MAX = 1e3;
|
|
8478
8486
|
var publicKeyCache = /* @__PURE__ */ new Map();
|
|
8479
8487
|
function getPublicKeyObject(publicKeyB64) {
|
|
@@ -8554,6 +8562,39 @@ function verifyKeyFingerprint(publicKeyB64, expectedFingerprint) {
|
|
|
8554
8562
|
return false;
|
|
8555
8563
|
}
|
|
8556
8564
|
}
|
|
8565
|
+
function readPublicKey(publicKeyB64) {
|
|
8566
|
+
try {
|
|
8567
|
+
return getPublicKeyObject(publicKeyB64);
|
|
8568
|
+
} catch {
|
|
8569
|
+
return null;
|
|
8570
|
+
}
|
|
8571
|
+
}
|
|
8572
|
+
function describeKeyType(key) {
|
|
8573
|
+
if (!key) {
|
|
8574
|
+
return "not a readable SPKI public key";
|
|
8575
|
+
}
|
|
8576
|
+
if (key.asymmetricKeyType === "ec") {
|
|
8577
|
+
return `a ${key.asymmetricKeyDetails?.namedCurve ?? "unknown-curve"} EC key`;
|
|
8578
|
+
}
|
|
8579
|
+
return `a ${key.asymmetricKeyType ?? "unrecognised"} key`;
|
|
8580
|
+
}
|
|
8581
|
+
function keyMatchesAlgorithm(key, algorithm) {
|
|
8582
|
+
if (!key) {
|
|
8583
|
+
return false;
|
|
8584
|
+
}
|
|
8585
|
+
if (algorithm === "ES256") {
|
|
8586
|
+
return key.asymmetricKeyType === "ec" && key.asymmetricKeyDetails?.namedCurve === "prime256v1";
|
|
8587
|
+
}
|
|
8588
|
+
return key.asymmetricKeyType === "rsa";
|
|
8589
|
+
}
|
|
8590
|
+
function assertKeyMatchesAlgorithm(publicKeyB64, algorithm) {
|
|
8591
|
+
const key = readPublicKey(publicKeyB64);
|
|
8592
|
+
if (!keyMatchesAlgorithm(key, algorithm)) {
|
|
8593
|
+
throw new KeyAlgorithmMismatchError({
|
|
8594
|
+
message: `Public key is ${describeKeyType(key)} but the declared algorithm is ${algorithm}`
|
|
8595
|
+
});
|
|
8596
|
+
}
|
|
8597
|
+
}
|
|
8557
8598
|
|
|
8558
8599
|
// src/server/helpers/context.ts
|
|
8559
8600
|
function getAuth(c) {
|
|
@@ -8950,6 +8991,7 @@ async function registerPublicKeyService(params) {
|
|
|
8950
8991
|
if (!isValidFingerprint) {
|
|
8951
8992
|
throw new InvalidKeyFingerprintError();
|
|
8952
8993
|
}
|
|
8994
|
+
assertKeyMatchesAlgorithm(publicKey, algorithm);
|
|
8953
8995
|
await keysRepository.create({
|
|
8954
8996
|
userId,
|
|
8955
8997
|
keyId,
|
|
@@ -8968,6 +9010,7 @@ async function rotateKeyService(params) {
|
|
|
8968
9010
|
if (!isValidFingerprint) {
|
|
8969
9011
|
throw new InvalidKeyFingerprintError();
|
|
8970
9012
|
}
|
|
9013
|
+
assertKeyMatchesAlgorithm(newPublicKey, algorithm);
|
|
8971
9014
|
const replaced = await keysRepository.findByKeyIdAndUserId(oldKeyId, userId);
|
|
8972
9015
|
await keysRepository.revokeByKeyIdAndUserId(
|
|
8973
9016
|
oldKeyId,
|
|
@@ -9912,6 +9955,7 @@ async function startDeviceAuthService(params) {
|
|
|
9912
9955
|
if (!verifyKeyFingerprint(params.publicKey, params.fingerprint)) {
|
|
9913
9956
|
throw new InvalidKeyFingerprintError2();
|
|
9914
9957
|
}
|
|
9958
|
+
assertKeyMatchesAlgorithm(params.publicKey, params.algorithm ?? DEFAULT_KEY_ALGORITHM);
|
|
9915
9959
|
const { ttlMs, intervalMs } = getDeviceAuthConfig();
|
|
9916
9960
|
const expiresAt = new Date(Date.now() + ttlMs);
|
|
9917
9961
|
for (let attempt = 0; attempt < USER_CODE_ATTEMPTS; attempt++) {
|
|
@@ -10377,6 +10421,7 @@ async function validateInvitation(token) {
|
|
|
10377
10421
|
}
|
|
10378
10422
|
async function acceptInvitation(params) {
|
|
10379
10423
|
const { token, password, publicKey, keyId, fingerprint, algorithm } = params;
|
|
10424
|
+
assertKeyMatchesAlgorithm(publicKey, algorithm);
|
|
10380
10425
|
const validation = await validateInvitation(token);
|
|
10381
10426
|
if (!validation.valid || !validation.invitation) {
|
|
10382
10427
|
throw new BadRequestError({ message: validation.error || "Invalid invitation" });
|
|
@@ -12966,7 +13011,7 @@ var CORE_PREREQUISITE_OPERATIONS = [
|
|
|
12966
13011
|
|
|
12967
13012
|
// src/server/client-proof/contract-bundle.ts
|
|
12968
13013
|
init_wire_headers();
|
|
12969
|
-
var CONTRACT_VERSION = "0.10.
|
|
13014
|
+
var CONTRACT_VERSION = "0.10.1";
|
|
12970
13015
|
var CONTRACT_SUPPORTED_RANGE = ">=0.10.0 <0.11.0";
|
|
12971
13016
|
function required(name, type) {
|
|
12972
13017
|
return { name, type, optional: false };
|
|
@@ -15510,6 +15555,72 @@ async function ensureAdminExists() {
|
|
|
15510
15555
|
}
|
|
15511
15556
|
}
|
|
15512
15557
|
|
|
15558
|
+
// src/server/lib/oauth/redirect-uri-check.ts
|
|
15559
|
+
var PROVIDERS = ["google", "kakao", "naver", "github"];
|
|
15560
|
+
var OPT_OUT_VAR = "SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK";
|
|
15561
|
+
function redirectUriVar(provider) {
|
|
15562
|
+
return `SPFN_AUTH_${provider.toUpperCase()}_REDIRECT_URI`;
|
|
15563
|
+
}
|
|
15564
|
+
function resolveWebAppOrigin(env16) {
|
|
15565
|
+
const configured2 = env16.NEXT_PUBLIC_SPFN_APP_URL || env16.SPFN_APP_URL;
|
|
15566
|
+
if (!configured2) {
|
|
15567
|
+
return null;
|
|
15568
|
+
}
|
|
15569
|
+
try {
|
|
15570
|
+
return new URL(configured2).origin;
|
|
15571
|
+
} catch {
|
|
15572
|
+
return null;
|
|
15573
|
+
}
|
|
15574
|
+
}
|
|
15575
|
+
function conformanceDetail(value, webAppOrigin, callbackPath) {
|
|
15576
|
+
let url;
|
|
15577
|
+
try {
|
|
15578
|
+
url = new URL(value);
|
|
15579
|
+
} catch {
|
|
15580
|
+
return " The value is not a URL.";
|
|
15581
|
+
}
|
|
15582
|
+
if (url.origin !== webAppOrigin || url.pathname !== callbackPath) {
|
|
15583
|
+
return "";
|
|
15584
|
+
}
|
|
15585
|
+
if (url.search !== "" || url.hash !== "") {
|
|
15586
|
+
return " The value carries a query string or fragment; the callback URL is the path alone.";
|
|
15587
|
+
}
|
|
15588
|
+
return null;
|
|
15589
|
+
}
|
|
15590
|
+
function providerRefusal(provider, env16, webAppOrigin) {
|
|
15591
|
+
const variable = redirectUriVar(provider);
|
|
15592
|
+
const value = env16[variable];
|
|
15593
|
+
if (!value) {
|
|
15594
|
+
return null;
|
|
15595
|
+
}
|
|
15596
|
+
const callbackPath = `/_auth/oauth/${provider}/callback`;
|
|
15597
|
+
const detail = conformanceDetail(value, webAppOrigin, callbackPath);
|
|
15598
|
+
if (detail === null) {
|
|
15599
|
+
return null;
|
|
15600
|
+
}
|
|
15601
|
+
return `${variable} must be on the web app origin (${webAppOrigin}) at ${callbackPath}: the callback's CSRF cookie is host-only and /_auth/* is forwarded to the API by the app's rewrite. Unset it to use the default, fix the origin, or set ${OPT_OUT_VAR}=off for a deployment that deliberately terminates the callback elsewhere.${detail}`;
|
|
15602
|
+
}
|
|
15603
|
+
function assertOAuthRedirectUris(env16 = process.env) {
|
|
15604
|
+
const examined = PROVIDERS.map(redirectUriVar).join(", ");
|
|
15605
|
+
if (env16[OPT_OUT_VAR] === "off") {
|
|
15606
|
+
authLogger.service.info(
|
|
15607
|
+
`${OPT_OUT_VAR}=off: the OAuth callback origin check is disabled. Not examined: ${examined}.`
|
|
15608
|
+
);
|
|
15609
|
+
return;
|
|
15610
|
+
}
|
|
15611
|
+
const webAppOrigin = resolveWebAppOrigin(env16);
|
|
15612
|
+
if (!webAppOrigin) {
|
|
15613
|
+
authLogger.service.info(
|
|
15614
|
+
`The OAuth callback origin check was skipped: neither NEXT_PUBLIC_SPFN_APP_URL nor SPFN_APP_URL resolves to a parseable URL, which the startup env validation reports on its own. Not examined: ${examined}.`
|
|
15615
|
+
);
|
|
15616
|
+
return;
|
|
15617
|
+
}
|
|
15618
|
+
const refusals = PROVIDERS.map((provider) => providerRefusal(provider, env16, webAppOrigin)).filter((refusal) => refusal !== null);
|
|
15619
|
+
if (refusals.length > 0) {
|
|
15620
|
+
throw new Error(refusals.join("\n"));
|
|
15621
|
+
}
|
|
15622
|
+
}
|
|
15623
|
+
|
|
15513
15624
|
// src/server/lifecycle.ts
|
|
15514
15625
|
function createAuthLifecycle(options = {}) {
|
|
15515
15626
|
configureDeletion(options.deletion);
|
|
@@ -15519,11 +15630,13 @@ function createAuthLifecycle(options = {}) {
|
|
|
15519
15630
|
* Initialize auth system after database is ready
|
|
15520
15631
|
*
|
|
15521
15632
|
* Performs:
|
|
15633
|
+
* 0. Refuses boot on an OAuth redirect URI override off the web app origin
|
|
15522
15634
|
* 1. Ensures admin account exists (creates if missing)
|
|
15523
15635
|
* 2. Initializes RBAC system with built-in + custom roles/permissions
|
|
15524
15636
|
* 3. Initializes one-time token manager
|
|
15525
15637
|
*/
|
|
15526
15638
|
afterInfrastructure: async () => {
|
|
15639
|
+
assertOAuthRedirectUris();
|
|
15527
15640
|
await initializeAuth(options);
|
|
15528
15641
|
try {
|
|
15529
15642
|
await normalizeStoredEmails();
|
|
@@ -15617,6 +15730,7 @@ export {
|
|
|
15617
15730
|
appleProvider,
|
|
15618
15731
|
approveDeviceAuthService,
|
|
15619
15732
|
assertCanAssignRole,
|
|
15733
|
+
assertKeyMatchesAlgorithm,
|
|
15620
15734
|
authDeletionCancelledEvent,
|
|
15621
15735
|
authDeletionCompletedEvent,
|
|
15622
15736
|
authDeletionRequestedEvent,
|