@spfn/auth 0.2.0-beta.52 → 0.2.0-beta.54

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.
@@ -40,6 +40,7 @@ interface AuthSession {
40
40
  email: string | null;
41
41
  emailVerified: boolean;
42
42
  phoneVerified: boolean;
43
+ hasPassword: boolean;
43
44
  role: Role;
44
45
  permissions: Permission[];
45
46
  }
@@ -182,7 +183,7 @@ interface LogoutParams {
182
183
  }
183
184
  interface ChangePasswordParams {
184
185
  userId: number;
185
- currentPassword: string;
186
+ currentPassword?: string;
186
187
  newPassword: string;
187
188
  passwordHash?: string;
188
189
  }
@@ -558,7 +559,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
558
559
  }, RotateKeyResult>;
559
560
  changePassword: _spfn_core_route.RouteDef<{
560
561
  body: _sinclair_typebox.TObject<{
561
- currentPassword: _sinclair_typebox.TString;
562
+ currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
562
563
  newPassword: _sinclair_typebox.TString;
563
564
  }>;
564
565
  }, {}, void>;
@@ -580,6 +581,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
580
581
  email: string | null;
581
582
  emailVerified: boolean;
582
583
  phoneVerified: boolean;
584
+ hasPassword: boolean;
583
585
  }>;
584
586
  issueOneTimeToken: _spfn_core_route.RouteDef<{}, {}, IssueOneTimeTokenResult>;
585
587
  oauthGoogleStart: _spfn_core_route.RouteDef<{
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _spfn_core_nextjs from '@spfn/core/nextjs';
2
- import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, I as IssueOneTimeTokenResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-eucncHxN.js';
3
- export { l as AuthInitOptions, A as AuthSession, d as INVITATION_STATUSES, o as InvitationStatus, K as KEY_ALGORITHM, n as KeyAlgorithmType, j as PERMISSION_CATEGORIES, k as PermissionCategory, f as SOCIAL_PROVIDERS, q as SocialProvider, e as USER_STATUSES, p as UserStatus, i as VERIFICATION_PURPOSES, h as VERIFICATION_TARGET_TYPES, g as VerificationPurpose, V as VerificationTargetType } from './authenticate-eucncHxN.js';
2
+ import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, I as IssueOneTimeTokenResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-D11PAt8l.js';
3
+ export { l as AuthInitOptions, A as AuthSession, d as INVITATION_STATUSES, o as InvitationStatus, K as KEY_ALGORITHM, n as KeyAlgorithmType, j as PERMISSION_CATEGORIES, k as PermissionCategory, f as SOCIAL_PROVIDERS, q as SocialProvider, e as USER_STATUSES, p as UserStatus, i as VERIFICATION_PURPOSES, h as VERIFICATION_TARGET_TYPES, g as VerificationPurpose, V as VerificationTargetType } from './authenticate-D11PAt8l.js';
4
4
  import * as _spfn_core_route from '@spfn/core/route';
5
5
  import { HttpMethod } from '@spfn/core/route';
6
6
  import * as _sinclair_typebox from '@sinclair/typebox';
@@ -154,7 +154,7 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
154
154
  }, RotateKeyResult>;
155
155
  changePassword: _spfn_core_route.RouteDef<{
156
156
  body: _sinclair_typebox.TObject<{
157
- currentPassword: _sinclair_typebox.TString;
157
+ currentPassword: _sinclair_typebox.TOptional<_sinclair_typebox.TString>;
158
158
  newPassword: _sinclair_typebox.TString;
159
159
  }>;
160
160
  }, {}, void>;
@@ -176,6 +176,7 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
176
176
  email: string | null;
177
177
  emailVerified: boolean;
178
178
  phoneVerified: boolean;
179
+ hasPassword: boolean;
179
180
  }>;
180
181
  issueOneTimeToken: _spfn_core_route.RouteDef<{}, {}, IssueOneTimeTokenResult>;
181
182
  oauthGoogleStart: _spfn_core_route.RouteDef<{
@@ -160,6 +160,7 @@ declare function getAuthSessionData(): Promise<{
160
160
  email: string | null;
161
161
  emailVerified: boolean;
162
162
  phoneVerified: boolean;
163
+ hasPassword: boolean;
163
164
  } | null>;
164
165
  /**
165
166
  * Get user role
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { l as AuthInitOptions, n as KeyAlgorithmType, o as InvitationStatus, g as VerificationPurpose, k as PermissionCategory, q as SocialProvider, r as AuthContext } from './authenticate-eucncHxN.js';
2
- export { D as ChangePasswordParams, x as CheckAccountExistsParams, C as CheckAccountExistsResult, a9 as EmailSchema, d as INVITATION_STATUSES, I as IssueOneTimeTokenResult, K as KEY_ALGORITHM, z as LoginParams, L as LoginResult, B as LogoutParams, a5 as OAuthCallbackParams, a6 as OAuthCallbackResult, a4 as OAuthStartParams, O as OAuthStartResult, ab as PasswordSchema, aa as PhoneSchema, y as RegisterParams, T as RegisterPublicKeyParams, a as RegisterResult, X as RevokeKeyParams, W as RotateKeyParams, b as RotateKeyResult, f as SOCIAL_PROVIDERS, G as SendVerificationCodeParams, S as SendVerificationCodeResult, ac as TargetTypeSchema, e as USER_STATUSES, p as UserStatus, i as VERIFICATION_PURPOSES, h as VERIFICATION_TARGET_TYPES, ad as VerificationPurposeSchema, V as VerificationTargetType, H as VerifyCodeParams, J as VerifyCodeResult, m as authRouter, a7 as authenticate, a0 as buildOAuthErrorUrl, w as changePasswordService, s as checkAccountExistsService, a2 as getEnabledOAuthProviders, a3 as getGoogleAccessToken, a1 as isOAuthProviderEnabled, Y as issueOneTimeTokenService, u as loginService, v as logoutService, $ as oauthCallbackService, _ as oauthStartService, a8 as optionalAuth, M as registerPublicKeyService, t as registerService, Q as revokeKeyService, N as rotateKeyService, E as sendVerificationCodeService, F as verifyCodeService, Z as verifyOneTimeTokenService } from './authenticate-eucncHxN.js';
1
+ import { l as AuthInitOptions, n as KeyAlgorithmType, o as InvitationStatus, g as VerificationPurpose, k as PermissionCategory, q as SocialProvider, r as AuthContext } from './authenticate-D11PAt8l.js';
2
+ export { D as ChangePasswordParams, x as CheckAccountExistsParams, C as CheckAccountExistsResult, a9 as EmailSchema, d as INVITATION_STATUSES, I as IssueOneTimeTokenResult, K as KEY_ALGORITHM, z as LoginParams, L as LoginResult, B as LogoutParams, a5 as OAuthCallbackParams, a6 as OAuthCallbackResult, a4 as OAuthStartParams, O as OAuthStartResult, ab as PasswordSchema, aa as PhoneSchema, y as RegisterParams, T as RegisterPublicKeyParams, a as RegisterResult, X as RevokeKeyParams, W as RotateKeyParams, b as RotateKeyResult, f as SOCIAL_PROVIDERS, G as SendVerificationCodeParams, S as SendVerificationCodeResult, ac as TargetTypeSchema, e as USER_STATUSES, p as UserStatus, i as VERIFICATION_PURPOSES, h as VERIFICATION_TARGET_TYPES, ad as VerificationPurposeSchema, V as VerificationTargetType, H as VerifyCodeParams, J as VerifyCodeResult, m as authRouter, a7 as authenticate, a0 as buildOAuthErrorUrl, w as changePasswordService, s as checkAccountExistsService, a2 as getEnabledOAuthProviders, a3 as getGoogleAccessToken, a1 as isOAuthProviderEnabled, Y as issueOneTimeTokenService, u as loginService, v as logoutService, $ as oauthCallbackService, _ as oauthStartService, a8 as optionalAuth, M as registerPublicKeyService, t as registerService, Q as revokeKeyService, N as rotateKeyService, E as sendVerificationCodeService, F as verifyCodeService, Z as verifyOneTimeTokenService } from './authenticate-D11PAt8l.js';
3
3
  import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
4
4
  import { UserProfile as UserProfile$1, ProfileInfo } from '@spfn/auth';
5
5
  import { BaseRepository } from '@spfn/core/db';
@@ -1337,6 +1337,7 @@ declare function getAuthSessionService(userId: string | number | bigint): Promis
1337
1337
  email: string | null;
1338
1338
  emailVerified: boolean;
1339
1339
  phoneVerified: boolean;
1340
+ hasPassword: boolean;
1340
1341
  }>;
1341
1342
 
1342
1343
  /**
@@ -3191,6 +3192,7 @@ declare class UsersRepository extends BaseRepository {
3191
3192
  username: string | null;
3192
3193
  isEmailVerified: boolean;
3193
3194
  isPhoneVerified: boolean;
3195
+ hasPassword: boolean;
3194
3196
  }>;
3195
3197
  /**
3196
3198
  * Full user data 조회 (user profile용)
package/dist/server.js CHANGED
@@ -5533,7 +5533,8 @@ var init_users_repository = __esm({
5533
5533
  email: users.email,
5534
5534
  username: users.username,
5535
5535
  emailVerifiedAt: users.emailVerifiedAt,
5536
- phoneVerifiedAt: users.phoneVerifiedAt
5536
+ phoneVerifiedAt: users.phoneVerifiedAt,
5537
+ passwordHash: users.passwordHash
5537
5538
  }).from(users).where(eq(users.id, userId)).limit(1).then((rows) => rows[0] ?? null);
5538
5539
  if (!user) {
5539
5540
  throw new NotFoundError({ message: "[@spfn/auth] User not found" });
@@ -5544,7 +5545,8 @@ var init_users_repository = __esm({
5544
5545
  email: user.email,
5545
5546
  username: user.username,
5546
5547
  isEmailVerified: !!user.emailVerifiedAt,
5547
- isPhoneVerified: !!user.phoneVerifiedAt
5548
+ isPhoneVerified: !!user.phoneVerifiedAt,
5549
+ hasPassword: !!user.passwordHash
5548
5550
  };
5549
5551
  }
5550
5552
  /**
@@ -7406,12 +7408,14 @@ async function changePasswordService(params) {
7406
7408
  }
7407
7409
  passwordHash = user.passwordHash;
7408
7410
  }
7409
- if (!passwordHash) {
7410
- throw new ValidationError2({ message: "No password set for this account" });
7411
- }
7412
- const isValid = await verifyPassword(currentPassword, passwordHash);
7413
- if (!isValid) {
7414
- throw new InvalidCredentialsError({ message: "Current password is incorrect" });
7411
+ if (passwordHash) {
7412
+ if (!currentPassword) {
7413
+ throw new ValidationError2({ message: "Current password is required" });
7414
+ }
7415
+ const isValid = await verifyPassword(currentPassword, passwordHash);
7416
+ if (!isValid) {
7417
+ throw new InvalidCredentialsError({ message: "Current password is incorrect" });
7418
+ }
7415
7419
  }
7416
7420
  const newPasswordHash = await hashPassword(newPassword);
7417
7421
  await usersRepository.updatePassword(userId, newPasswordHash, true);
@@ -7895,6 +7899,7 @@ async function getAuthSessionService(userId) {
7895
7899
  email: user.email,
7896
7900
  emailVerified: user.isEmailVerified,
7897
7901
  phoneVerified: user.isPhoneVerified,
7902
+ hasPassword: user.hasPassword,
7898
7903
  ...roleAndPerms
7899
7904
  };
7900
7905
  }
@@ -8483,10 +8488,10 @@ var rotateKey = route.post("/_auth/keys/rotate").interceptor({
8483
8488
  });
8484
8489
  var changePassword = route.put("/_auth/password").input({
8485
8490
  body: Type.Object({
8486
- currentPassword: Type.String({
8491
+ currentPassword: Type.Optional(Type.String({
8487
8492
  minLength: 1,
8488
- description: "Current password for verification"
8489
- }),
8493
+ description: "Current password for verification (required when changing existing password)"
8494
+ })),
8490
8495
  newPassword: PasswordSchema
8491
8496
  })
8492
8497
  }).handler(async (c) => {