@spfn/auth 0.2.0-beta.14 → 0.2.0-beta.16

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @spfn/auth - Technical Documentation
2
2
 
3
- **Version:** 0.2.0-beta.13
3
+ **Version:** 0.2.0-beta.15
4
4
  **Status:** Alpha - Internal Development
5
5
 
6
6
  > **Note:** This is a technical documentation for developers working on the @spfn/auth package.
@@ -18,6 +18,7 @@
18
18
  - [Module Exports](#module-exports)
19
19
  - [Email & SMS Services](#email--sms-services)
20
20
  - [Server-Side API](#server-side-api)
21
+ - [Events](#events)
21
22
  - [OAuth Authentication](#oauth-authentication)
22
23
  - [Database Schema](#database-schema)
23
24
  - [RBAC System](#rbac-system)
@@ -1037,6 +1038,137 @@ Change password.
1037
1038
 
1038
1039
  ---
1039
1040
 
1041
+ ## Events
1042
+
1043
+ `@spfn/auth`는 `@spfn/core/event`를 사용하여 인증 관련 이벤트를 발행합니다. 이를 통해 로그인/회원가입 시 추가 로직(환영 이메일, 분석, 알림 등)을 디커플링된 방식으로 처리할 수 있습니다.
1044
+
1045
+ ### Available Events
1046
+
1047
+ | Event | Description | Trigger |
1048
+ |-------|-------------|---------|
1049
+ | `auth.login` | 로그인 성공 | 이메일/전화 로그인, OAuth 기존 사용자 |
1050
+ | `auth.register` | 회원가입 성공 | 이메일/전화 회원가입, OAuth 신규 사용자 |
1051
+
1052
+ ---
1053
+
1054
+ ### Event Payloads
1055
+
1056
+ #### `auth.login`
1057
+
1058
+ ```typescript
1059
+ {
1060
+ userId: string;
1061
+ provider: 'email' | 'phone' | 'google';
1062
+ email?: string;
1063
+ phone?: string;
1064
+ }
1065
+ ```
1066
+
1067
+ #### `auth.register`
1068
+
1069
+ ```typescript
1070
+ {
1071
+ userId: string;
1072
+ provider: 'email' | 'phone' | 'google';
1073
+ email?: string;
1074
+ phone?: string;
1075
+ }
1076
+ ```
1077
+
1078
+ ---
1079
+
1080
+ ### Subscribing to Events
1081
+
1082
+ ```typescript
1083
+ import { authLoginEvent, authRegisterEvent } from '@spfn/auth/server';
1084
+
1085
+ // 로그인 이벤트 구독
1086
+ authLoginEvent.subscribe(async (payload) => {
1087
+ console.log('User logged in:', payload.userId, payload.provider);
1088
+ await analytics.trackLogin(payload.userId);
1089
+ });
1090
+
1091
+ // 회원가입 이벤트 구독
1092
+ authRegisterEvent.subscribe(async (payload) => {
1093
+ console.log('New user registered:', payload.userId);
1094
+ if (payload.email) {
1095
+ await emailService.sendWelcome(payload.email);
1096
+ }
1097
+ });
1098
+ ```
1099
+
1100
+ ---
1101
+
1102
+ ### Job Integration
1103
+
1104
+ `@spfn/core/job`과 연동하여 백그라운드 작업을 실행할 수 있습니다.
1105
+
1106
+ ```typescript
1107
+ import { job, defineJobRouter } from '@spfn/core/job';
1108
+ import { authRegisterEvent } from '@spfn/auth/server';
1109
+
1110
+ // 회원가입 시 환영 이메일 발송 Job
1111
+ const sendWelcomeEmailJob = job('send-welcome-email')
1112
+ .on(authRegisterEvent)
1113
+ .handler(async ({ userId, email }) => {
1114
+ if (email) {
1115
+ await emailService.sendWelcome(email);
1116
+ }
1117
+ });
1118
+
1119
+ // 회원가입 시 기본 설정 생성 Job
1120
+ const createDefaultSettingsJob = job('create-default-settings')
1121
+ .on(authRegisterEvent)
1122
+ .handler(async ({ userId }) => {
1123
+ await settingsService.createDefaults(userId);
1124
+ });
1125
+
1126
+ export const jobRouter = defineJobRouter({
1127
+ sendWelcomeEmailJob,
1128
+ createDefaultSettingsJob,
1129
+ });
1130
+ ```
1131
+
1132
+ ---
1133
+
1134
+ ### Event Flow
1135
+
1136
+ ```
1137
+ ┌─────────────────────────────────────────────────────────────────┐
1138
+ │ loginService() / registerService() │
1139
+ │ oauthCallbackService() │
1140
+ └─────────────────────────────────────────────────────────────────┘
1141
+
1142
+
1143
+ authLoginEvent.emit()
1144
+ authRegisterEvent.emit()
1145
+
1146
+ ┌───────────────────┼───────────────────┐
1147
+ ▼ ▼ ▼
1148
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
1149
+ │ Backend │ │ Job │ │ SSE │
1150
+ │ Handler │ │ Queue │ │ Stream │
1151
+ └──────────┘ └──────────┘ └──────────┘
1152
+ .subscribe() .on(event) (optional)
1153
+ │ │
1154
+ ▼ ▼
1155
+ [Analytics, [Background
1156
+ Logging] Processing]
1157
+ ```
1158
+
1159
+ ---
1160
+
1161
+ ### Type Exports
1162
+
1163
+ ```typescript
1164
+ import type {
1165
+ AuthLoginPayload,
1166
+ AuthRegisterPayload,
1167
+ } from '@spfn/auth/server';
1168
+ ```
1169
+
1170
+ ---
1171
+
1040
1172
  ## OAuth Authentication
1041
1173
 
1042
1174
  ### Overview
@@ -2288,6 +2420,6 @@ MIT License - See LICENSE file for details.
2288
2420
 
2289
2421
  ---
2290
2422
 
2291
- **Last Updated:** 2026-01-27
2292
- **Document Version:** 2.4.0 (Technical Documentation)
2293
- **Package Version:** 0.2.0-beta.13
2423
+ **Last Updated:** 2026-01-29
2424
+ **Document Version:** 2.5.0 (Technical Documentation)
2425
+ **Package Version:** 0.2.0-beta.15
@@ -540,7 +540,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
540
540
  id: number;
541
541
  name: string;
542
542
  displayName: string;
543
- category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
543
+ category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
544
544
  }[];
545
545
  userId: number;
546
546
  email: string | null;
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, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-CriFdelv.js';
3
- export { k as AuthInitOptions, A as AuthSession, I as INVITATION_STATUSES, n as InvitationStatus, K as KEY_ALGORITHM, l as KeyAlgorithmType, i as PERMISSION_CATEGORIES, j as PermissionCategory, e as SOCIAL_PROVIDERS, p as SocialProvider, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, f as VerificationPurpose, V as VerificationTargetType } from './authenticate-CriFdelv.js';
2
+ import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-Cz2FjLdB.js';
3
+ export { k as AuthInitOptions, A as AuthSession, I as INVITATION_STATUSES, n as InvitationStatus, K as KEY_ALGORITHM, l as KeyAlgorithmType, i as PERMISSION_CATEGORIES, j as PermissionCategory, e as SOCIAL_PROVIDERS, p as SocialProvider, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, f as VerificationPurpose, V as VerificationTargetType } from './authenticate-Cz2FjLdB.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';
@@ -168,7 +168,7 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
168
168
  id: number;
169
169
  name: string;
170
170
  displayName: string;
171
- category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
171
+ category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
172
172
  }[];
173
173
  userId: number;
174
174
  email: string | null;
package/dist/index.js CHANGED
@@ -160,7 +160,13 @@ var routeMap = {
160
160
  resendInvitation: { method: "POST", path: "/_auth/invitations/resend" },
161
161
  deleteInvitation: { method: "POST", path: "/_auth/invitations/delete" },
162
162
  getUserProfile: { method: "GET", path: "/_auth/users/profile" },
163
- updateUserProfile: { method: "PATCH", path: "/_auth/users/profile" }
163
+ updateUserProfile: { method: "PATCH", path: "/_auth/users/profile" },
164
+ oauthGoogleStart: { method: "GET", path: "/_auth/oauth/google" },
165
+ oauthGoogleCallback: { method: "GET", path: "/_auth/oauth/google/callback" },
166
+ oauthStart: { method: "POST", path: "/_auth/oauth/start" },
167
+ oauthProviders: { method: "GET", path: "/_auth/oauth/providers" },
168
+ getGoogleOAuthUrl: { method: "POST", path: "/_auth/oauth/google/url" },
169
+ oauthFinalize: { method: "POST", path: "/_auth/oauth/finalize" }
164
170
  };
165
171
 
166
172
  // src/lib/types.ts