@bagelink/auth 1.9.61 → 1.9.65
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/dist/api.d.ts +36 -32
- package/dist/index.cjs +101 -127
- package/dist/index.mjs +101 -127
- package/dist/sso.d.ts +2 -2
- package/dist/types.d.ts +70 -24
- package/dist/useAuth.d.ts +19 -20
- package/package.json +1 -1
- package/src/api.ts +81 -82
- package/src/sso.ts +26 -24
- package/src/types.ts +77 -28
- package/src/useAuth.ts +19 -51
package/dist/useAuth.d.ts
CHANGED
|
@@ -37,7 +37,8 @@ export declare function useAuth(): {
|
|
|
37
37
|
display_name: string;
|
|
38
38
|
is_active: boolean;
|
|
39
39
|
is_verified: boolean;
|
|
40
|
-
last_login?: string |
|
|
40
|
+
last_login?: string | undefined;
|
|
41
|
+
roles: string[];
|
|
41
42
|
authentication_methods: {
|
|
42
43
|
id: string;
|
|
43
44
|
type: string;
|
|
@@ -45,7 +46,7 @@ export declare function useAuth(): {
|
|
|
45
46
|
is_verified: boolean;
|
|
46
47
|
last_used?: string | undefined;
|
|
47
48
|
use_count: number;
|
|
48
|
-
provider?:
|
|
49
|
+
provider?: string | undefined;
|
|
49
50
|
provider_user_id?: string | undefined;
|
|
50
51
|
}[];
|
|
51
52
|
person?: {
|
|
@@ -53,17 +54,18 @@ export declare function useAuth(): {
|
|
|
53
54
|
name: string;
|
|
54
55
|
first_name: string;
|
|
55
56
|
last_name: string;
|
|
56
|
-
email?: string |
|
|
57
|
-
phone_number?: string |
|
|
58
|
-
|
|
59
|
-
} |
|
|
57
|
+
email?: string | undefined;
|
|
58
|
+
phone_number?: string | undefined;
|
|
59
|
+
tags: string[];
|
|
60
|
+
} | undefined;
|
|
60
61
|
} | null, AccountInfo | {
|
|
61
62
|
id: string;
|
|
62
63
|
account_type: string;
|
|
63
64
|
display_name: string;
|
|
64
65
|
is_active: boolean;
|
|
65
66
|
is_verified: boolean;
|
|
66
|
-
last_login?: string |
|
|
67
|
+
last_login?: string | undefined;
|
|
68
|
+
roles: string[];
|
|
67
69
|
authentication_methods: {
|
|
68
70
|
id: string;
|
|
69
71
|
type: string;
|
|
@@ -71,7 +73,7 @@ export declare function useAuth(): {
|
|
|
71
73
|
is_verified: boolean;
|
|
72
74
|
last_used?: string | undefined;
|
|
73
75
|
use_count: number;
|
|
74
|
-
provider?:
|
|
76
|
+
provider?: string | undefined;
|
|
75
77
|
provider_user_id?: string | undefined;
|
|
76
78
|
}[];
|
|
77
79
|
person?: {
|
|
@@ -79,10 +81,10 @@ export declare function useAuth(): {
|
|
|
79
81
|
name: string;
|
|
80
82
|
first_name: string;
|
|
81
83
|
last_name: string;
|
|
82
|
-
email?: string |
|
|
83
|
-
phone_number?: string |
|
|
84
|
-
|
|
85
|
-
} |
|
|
84
|
+
email?: string | undefined;
|
|
85
|
+
phone_number?: string | undefined;
|
|
86
|
+
tags: string[];
|
|
87
|
+
} | undefined;
|
|
86
88
|
} | null>;
|
|
87
89
|
sso: import('./sso').SSOObject;
|
|
88
90
|
tenants: import('vue').Ref<{
|
|
@@ -169,9 +171,9 @@ export declare function useAuth(): {
|
|
|
169
171
|
signup: (newUser: NewUser) => Promise<import('./types').AuthenticationResponse>;
|
|
170
172
|
checkAuth: () => Promise<boolean>;
|
|
171
173
|
refreshSession: () => Promise<void>;
|
|
172
|
-
initiateSSO: (params: SSOInitiateRequest) => Promise<string>;
|
|
173
|
-
loginWithSSO: (params: SSOCallbackRequest) => Promise<import('./types').
|
|
174
|
-
linkSSOProvider: (params: SSOLinkRequest) => Promise<void>;
|
|
174
|
+
initiateSSO: (provider: SSOProvider, params: SSOInitiateRequest) => Promise<string>;
|
|
175
|
+
loginWithSSO: (provider: SSOProvider, params: SSOCallbackRequest) => Promise<import('./types').SSOCallbackResponse>;
|
|
176
|
+
linkSSOProvider: (provider: SSOProvider, params: SSOLinkRequest) => Promise<void>;
|
|
175
177
|
unlinkSSOProvider: (provider: SSOProvider) => Promise<void>;
|
|
176
178
|
updateProfile: (updates: UpdateAccountRequest) => Promise<void>;
|
|
177
179
|
deleteCurrentUser: () => Promise<void>;
|
|
@@ -181,12 +183,9 @@ export declare function useAuth(): {
|
|
|
181
183
|
resetPassword: (token: string, newPassword: string) => Promise<void>;
|
|
182
184
|
sendVerification: (email?: string) => Promise<void>;
|
|
183
185
|
verifyEmail: (token: string) => Promise<void>;
|
|
184
|
-
|
|
185
|
-
deactivateAccount: (accountId: string) => Promise<void>;
|
|
186
|
-
deleteAccount: (accountId: string) => Promise<void>;
|
|
187
|
-
getSessions: (accountId?: string) => Promise<import('./types').GetSessionsResponse>;
|
|
186
|
+
getSessions: () => Promise<import('./types').GetSessionsResponse>;
|
|
188
187
|
revokeSession: (sessionToken: string) => Promise<void>;
|
|
189
|
-
revokeAllSessions: (
|
|
188
|
+
revokeAllSessions: () => Promise<void>;
|
|
190
189
|
loadTenants: () => Promise<TenantInfo[]>;
|
|
191
190
|
setTenant: (tenantId: string | null) => void;
|
|
192
191
|
switchTenant: (tenantId: string) => void;
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -3,20 +3,23 @@ import type {
|
|
|
3
3
|
RegisterRequest,
|
|
4
4
|
UpdateAccountRequest,
|
|
5
5
|
ChangePasswordRequest,
|
|
6
|
+
ForgotPasswordRequest,
|
|
6
7
|
ResetPasswordRequest,
|
|
7
8
|
SendVerificationRequest,
|
|
9
|
+
VerifyEmailRequest,
|
|
8
10
|
AuthenticationAccount,
|
|
11
|
+
PasswordLoginRequest,
|
|
12
|
+
EmailTokenSendRequest,
|
|
13
|
+
EmailTokenVerifyRequest,
|
|
14
|
+
OTPSendRequest,
|
|
15
|
+
OTPVerifyRequest,
|
|
16
|
+
SSOLoginRequest,
|
|
9
17
|
LoginResponse,
|
|
10
18
|
RegisterResponse,
|
|
11
19
|
LogoutResponse,
|
|
12
20
|
GetMeResponse,
|
|
13
21
|
UpdateMeResponse,
|
|
14
22
|
DeleteMeResponse,
|
|
15
|
-
GetAccountResponse,
|
|
16
|
-
UpdateAccountResponse,
|
|
17
|
-
DeleteAccountResponse,
|
|
18
|
-
ActivateAccountResponse,
|
|
19
|
-
DeactivateAccountResponse,
|
|
20
23
|
ChangePasswordResponse,
|
|
21
24
|
ForgotPasswordResponse,
|
|
22
25
|
ResetPasswordResponse,
|
|
@@ -29,14 +32,20 @@ import type {
|
|
|
29
32
|
DeleteAllSessionsResponse,
|
|
30
33
|
CleanupSessionsResponse,
|
|
31
34
|
GetMethodsResponse,
|
|
35
|
+
GetAuthStatusResponse,
|
|
36
|
+
SendEmailTokenResponse,
|
|
37
|
+
VerifyEmailTokenResponse,
|
|
38
|
+
SendOTPResponse,
|
|
39
|
+
VerifyOTPResponse,
|
|
40
|
+
LegacySSOLoginResponse,
|
|
32
41
|
SSOProvider,
|
|
33
42
|
SSOInitiateRequest,
|
|
34
43
|
SSOCallbackRequest,
|
|
35
44
|
SSOLinkRequest,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
InitiateSSOResponse,
|
|
46
|
+
CallbackSSOResponse,
|
|
47
|
+
LinkSSOResponse,
|
|
48
|
+
UnlinkSSOResponse,
|
|
40
49
|
GetTenantsResponse,
|
|
41
50
|
} from './types'
|
|
42
51
|
import { createAxiosInstance } from './utils'
|
|
@@ -86,6 +95,13 @@ export class AuthApi {
|
|
|
86
95
|
// Authentication Methods
|
|
87
96
|
// ============================================
|
|
88
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Get authentication status
|
|
100
|
+
*/
|
|
101
|
+
async getAuthStatus(): Promise<GetAuthStatusResponse> {
|
|
102
|
+
return this.api.get('authentication/status')
|
|
103
|
+
}
|
|
104
|
+
|
|
89
105
|
/**
|
|
90
106
|
* Get available authentication methods
|
|
91
107
|
*/
|
|
@@ -106,13 +122,48 @@ export class AuthApi {
|
|
|
106
122
|
/**
|
|
107
123
|
* Login with password
|
|
108
124
|
*/
|
|
109
|
-
async login(
|
|
125
|
+
async login(data: PasswordLoginRequest): Promise<LoginResponse> {
|
|
110
126
|
return this.api.post('authentication/login/password', {
|
|
111
|
-
|
|
112
|
-
|
|
127
|
+
...data,
|
|
128
|
+
email: data.email.toLowerCase(),
|
|
113
129
|
})
|
|
114
130
|
}
|
|
115
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Send email token to user
|
|
134
|
+
*/
|
|
135
|
+
async sendEmailToken(data: EmailTokenSendRequest): Promise<SendEmailTokenResponse> {
|
|
136
|
+
return this.api.post('authentication/login/email-token/send', data)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Verify email token and login
|
|
141
|
+
*/
|
|
142
|
+
async verifyEmailToken(data: EmailTokenVerifyRequest): Promise<VerifyEmailTokenResponse> {
|
|
143
|
+
return this.api.post('authentication/login/email-token/verify', data)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Send OTP code to phone number
|
|
148
|
+
*/
|
|
149
|
+
async sendOTP(data: OTPSendRequest): Promise<SendOTPResponse> {
|
|
150
|
+
return this.api.post('authentication/login/otp/send', data)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Verify OTP code and login
|
|
155
|
+
*/
|
|
156
|
+
async verifyOTP(data: OTPVerifyRequest): Promise<VerifyOTPResponse> {
|
|
157
|
+
return this.api.post('authentication/login/otp/verify', data)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Login with SSO provider (legacy endpoint without PKCE)
|
|
162
|
+
*/
|
|
163
|
+
async loginWithSSO(provider: SSOProvider, data: SSOLoginRequest): Promise<LegacySSOLoginResponse> {
|
|
164
|
+
return this.api.post(`authentication/login/sso/${provider}`, data)
|
|
165
|
+
}
|
|
166
|
+
|
|
116
167
|
/**
|
|
117
168
|
* Logout and clear session
|
|
118
169
|
*/
|
|
@@ -135,37 +186,28 @@ export class AuthApi {
|
|
|
135
186
|
* Initiate SSO login flow
|
|
136
187
|
* Returns authorization URL to redirect user to
|
|
137
188
|
*/
|
|
138
|
-
async initiateSSO(data: SSOInitiateRequest): Promise<
|
|
139
|
-
return this.api.post(`authentication/sso/${
|
|
140
|
-
redirect_uri: data.redirect_uri,
|
|
141
|
-
state: data.state,
|
|
142
|
-
})
|
|
189
|
+
async initiateSSO(provider: SSOProvider, data: SSOInitiateRequest): Promise<InitiateSSOResponse> {
|
|
190
|
+
return this.api.post(`authentication/sso/${provider}/initiate`, data)
|
|
143
191
|
}
|
|
144
192
|
|
|
145
193
|
/**
|
|
146
194
|
* Complete SSO login after callback from provider
|
|
147
195
|
*/
|
|
148
|
-
async ssoCallback(data: SSOCallbackRequest): Promise<
|
|
149
|
-
return this.api.post(`authentication/sso/${
|
|
150
|
-
code: data.code,
|
|
151
|
-
state: data.state,
|
|
152
|
-
})
|
|
196
|
+
async ssoCallback(provider: SSOProvider, data: SSOCallbackRequest): Promise<CallbackSSOResponse> {
|
|
197
|
+
return this.api.post(`authentication/sso/${provider}/callback`, data)
|
|
153
198
|
}
|
|
154
199
|
|
|
155
200
|
/**
|
|
156
201
|
* Link an SSO provider to existing account
|
|
157
202
|
*/
|
|
158
|
-
async linkSSOProvider(data: SSOLinkRequest): Promise<
|
|
159
|
-
return this.api.post(`authentication/sso/${
|
|
160
|
-
code: data.code,
|
|
161
|
-
state: data.state,
|
|
162
|
-
})
|
|
203
|
+
async linkSSOProvider(provider: SSOProvider, data: SSOLinkRequest): Promise<LinkSSOResponse> {
|
|
204
|
+
return this.api.post(`authentication/sso/${provider}/link`, data)
|
|
163
205
|
}
|
|
164
206
|
|
|
165
207
|
/**
|
|
166
208
|
* Unlink an SSO provider from account
|
|
167
209
|
*/
|
|
168
|
-
async unlinkSSOProvider(provider: SSOProvider): Promise<
|
|
210
|
+
async unlinkSSOProvider(provider: SSOProvider): Promise<UnlinkSSOResponse> {
|
|
169
211
|
return this.api.delete(`authentication/sso/${provider}/unlink`)
|
|
170
212
|
}
|
|
171
213
|
|
|
@@ -194,50 +236,6 @@ export class AuthApi {
|
|
|
194
236
|
return this.api.delete('authentication/me')
|
|
195
237
|
}
|
|
196
238
|
|
|
197
|
-
// ============================================
|
|
198
|
-
// Account Management (Admin)
|
|
199
|
-
// ============================================
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Get account information by ID
|
|
203
|
-
*/
|
|
204
|
-
async getAccount(accountId: string): Promise<GetAccountResponse> {
|
|
205
|
-
return this.api.get(`authentication/account/${accountId}`)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Update account by ID
|
|
210
|
-
*/
|
|
211
|
-
async updateAccount(
|
|
212
|
-
accountId: string,
|
|
213
|
-
data: UpdateAccountRequest
|
|
214
|
-
): Promise<UpdateAccountResponse> {
|
|
215
|
-
return this.api.patch(`authentication/account/${accountId}`, data)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Delete account by ID
|
|
220
|
-
*/
|
|
221
|
-
async deleteAccount(accountId: string): Promise<DeleteAccountResponse> {
|
|
222
|
-
return this.api.delete(`authentication/account/${accountId}`)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Activate account by ID
|
|
227
|
-
*/
|
|
228
|
-
async activateAccount(accountId: string): Promise<ActivateAccountResponse> {
|
|
229
|
-
return this.api.post(`authentication/account/${accountId}/activate`, {})
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Deactivate account by ID
|
|
234
|
-
*/
|
|
235
|
-
async deactivateAccount(
|
|
236
|
-
accountId: string
|
|
237
|
-
): Promise<DeactivateAccountResponse> {
|
|
238
|
-
return this.api.post(`authentication/account/${accountId}/deactivate`, {})
|
|
239
|
-
}
|
|
240
|
-
|
|
241
239
|
// ============================================
|
|
242
240
|
// Password Management
|
|
243
241
|
// ============================================
|
|
@@ -252,9 +250,10 @@ export class AuthApi {
|
|
|
252
250
|
/**
|
|
253
251
|
* Initiate forgot password flow
|
|
254
252
|
*/
|
|
255
|
-
async forgotPassword(
|
|
253
|
+
async forgotPassword(data: ForgotPasswordRequest): Promise<ForgotPasswordResponse> {
|
|
256
254
|
return this.api.post('authentication/password/forgot', {
|
|
257
|
-
|
|
255
|
+
...data,
|
|
256
|
+
email: data.email.toLowerCase(),
|
|
258
257
|
})
|
|
259
258
|
}
|
|
260
259
|
|
|
@@ -291,8 +290,8 @@ export class AuthApi {
|
|
|
291
290
|
/**
|
|
292
291
|
* Verify email with token
|
|
293
292
|
*/
|
|
294
|
-
async verifyEmail(
|
|
295
|
-
return this.api.post('authentication/verify/email',
|
|
293
|
+
async verifyEmail(data: VerifyEmailRequest): Promise<VerifyEmailResponse> {
|
|
294
|
+
return this.api.post('authentication/verify/email', data)
|
|
296
295
|
}
|
|
297
296
|
|
|
298
297
|
// ============================================
|
|
@@ -300,10 +299,10 @@ export class AuthApi {
|
|
|
300
299
|
// ============================================
|
|
301
300
|
|
|
302
301
|
/**
|
|
303
|
-
* Get sessions for
|
|
302
|
+
* Get active sessions for current identity
|
|
304
303
|
*/
|
|
305
|
-
async getSessions(
|
|
306
|
-
return this.api.get(
|
|
304
|
+
async getSessions(): Promise<GetSessionsResponse> {
|
|
305
|
+
return this.api.get('authentication/sessions')
|
|
307
306
|
}
|
|
308
307
|
|
|
309
308
|
/**
|
|
@@ -314,10 +313,10 @@ export class AuthApi {
|
|
|
314
313
|
}
|
|
315
314
|
|
|
316
315
|
/**
|
|
317
|
-
* Revoke all sessions for
|
|
316
|
+
* Revoke all sessions for current identity
|
|
318
317
|
*/
|
|
319
|
-
async revokeAllSessions(
|
|
320
|
-
return this.api.delete(
|
|
318
|
+
async revokeAllSessions(): Promise<DeleteAllSessionsResponse> {
|
|
319
|
+
return this.api.delete('authentication/sessions')
|
|
321
320
|
}
|
|
322
321
|
|
|
323
322
|
/**
|
package/src/sso.ts
CHANGED
|
@@ -132,13 +132,13 @@ export interface SSOProviderInstance extends SSOProviderConfig {
|
|
|
132
132
|
* Complete OAuth flow after callback
|
|
133
133
|
* Call this on your callback page
|
|
134
134
|
*/
|
|
135
|
-
callback: (code: string, state
|
|
135
|
+
callback: (code: string, state: string) => Promise<AuthenticationResponse>
|
|
136
136
|
|
|
137
137
|
/**
|
|
138
138
|
* Link this provider to the current logged-in user
|
|
139
139
|
* Call this after OAuth redirect completes on link callback page
|
|
140
140
|
*/
|
|
141
|
-
link: (code: string, state
|
|
141
|
+
link: (code: string, state: string) => Promise<void>
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
144
|
* Unlink this provider from the current user
|
|
@@ -334,8 +334,7 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
334
334
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id)
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
const authUrl = await auth.initiateSSO({
|
|
338
|
-
provider: config.id,
|
|
337
|
+
const authUrl = await auth.initiateSSO(config.id, {
|
|
339
338
|
redirect_uri: redirectUri,
|
|
340
339
|
state,
|
|
341
340
|
scopes: options.scopes ?? config.defaultScopes,
|
|
@@ -368,8 +367,7 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
368
367
|
sessionStorage.setItem(`oauth_provider:${state}`, config.id)
|
|
369
368
|
}
|
|
370
369
|
|
|
371
|
-
const authUrl = await auth.initiateSSO({
|
|
372
|
-
provider: config.id,
|
|
370
|
+
const authUrl = await auth.initiateSSO(config.id, {
|
|
373
371
|
redirect_uri: redirectUri,
|
|
374
372
|
state,
|
|
375
373
|
scopes: options.scopes ?? config.defaultScopes,
|
|
@@ -385,21 +383,19 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
385
383
|
|
|
386
384
|
const result = await waitForPopupCallback(popupWindow, config.id, timeout)
|
|
387
385
|
|
|
388
|
-
return auth.loginWithSSO({
|
|
389
|
-
provider: config.id,
|
|
386
|
+
return auth.loginWithSSO(config.id, {
|
|
390
387
|
code: result.code,
|
|
391
|
-
state: result.state,
|
|
388
|
+
state: result.state ?? generateState(),
|
|
392
389
|
})
|
|
393
390
|
},
|
|
394
391
|
|
|
395
|
-
async callback(code: string, state
|
|
392
|
+
async callback(code: string, state: string) {
|
|
396
393
|
const auth = getAuthApi()
|
|
397
394
|
|
|
398
395
|
// Verify state if it was stored (per-provider key)
|
|
399
|
-
if (typeof sessionStorage !== 'undefined'
|
|
396
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
400
397
|
const storedState = sessionStorage.getItem(getStateKey())
|
|
401
398
|
sessionStorage.removeItem(getStateKey())
|
|
402
|
-
// Clean up provider mapping
|
|
403
399
|
sessionStorage.removeItem(`oauth_provider:${state}`)
|
|
404
400
|
|
|
405
401
|
if (storedState !== null && storedState !== state) {
|
|
@@ -407,21 +403,19 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
407
403
|
}
|
|
408
404
|
}
|
|
409
405
|
|
|
410
|
-
return auth.loginWithSSO({
|
|
411
|
-
provider: config.id,
|
|
406
|
+
return auth.loginWithSSO(config.id, {
|
|
412
407
|
code,
|
|
413
|
-
state,
|
|
408
|
+
state: state ?? generateState(),
|
|
414
409
|
})
|
|
415
410
|
},
|
|
416
411
|
|
|
417
|
-
async link(code: string, state
|
|
412
|
+
async link(code: string, state: string) {
|
|
418
413
|
const auth = getAuthApi()
|
|
419
414
|
|
|
420
415
|
// Verify state if it was stored (per-provider key)
|
|
421
|
-
if (typeof sessionStorage !== 'undefined'
|
|
416
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
422
417
|
const storedState = sessionStorage.getItem(getStateKey())
|
|
423
418
|
sessionStorage.removeItem(getStateKey())
|
|
424
|
-
// Clean up provider mapping
|
|
425
419
|
sessionStorage.removeItem(`oauth_provider:${state}`)
|
|
426
420
|
|
|
427
421
|
if (storedState !== null && storedState !== state) {
|
|
@@ -429,10 +423,9 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
429
423
|
}
|
|
430
424
|
}
|
|
431
425
|
|
|
432
|
-
await auth.linkSSOProvider({
|
|
433
|
-
provider: config.id,
|
|
426
|
+
await auth.linkSSOProvider(config.id, {
|
|
434
427
|
code,
|
|
435
|
-
state,
|
|
428
|
+
state: state ?? generateState(),
|
|
436
429
|
})
|
|
437
430
|
},
|
|
438
431
|
|
|
@@ -446,8 +439,7 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
446
439
|
const redirectUri = options.redirectUri ?? getDefaultRedirectUri()
|
|
447
440
|
const state = options.state ?? generateState()
|
|
448
441
|
|
|
449
|
-
return auth.initiateSSO({
|
|
450
|
-
provider: config.id,
|
|
442
|
+
return auth.initiateSSO(config.id, {
|
|
451
443
|
redirect_uri: redirectUri,
|
|
452
444
|
state,
|
|
453
445
|
scopes: options.scopes ?? config.defaultScopes,
|
|
@@ -462,7 +454,7 @@ function createSSOProvider(config: SSOProviderConfig): SSOProviderInstance {
|
|
|
462
454
|
/**
|
|
463
455
|
* SSO Provider Implementations with global helpers
|
|
464
456
|
*/
|
|
465
|
-
const ssoProviders = {
|
|
457
|
+
const ssoProviders: Record<SSOProvider, SSOProviderInstance> = {
|
|
466
458
|
/**
|
|
467
459
|
* Google OAuth Provider
|
|
468
460
|
* https://developers.google.com/identity/protocols/oauth2
|
|
@@ -565,6 +557,16 @@ const ssoProviders = {
|
|
|
565
557
|
buttonText: 'Continue with Facebook',
|
|
566
558
|
},
|
|
567
559
|
}),
|
|
560
|
+
custom: createSSOProvider({
|
|
561
|
+
id: 'custom',
|
|
562
|
+
name: 'Custom',
|
|
563
|
+
color: '#000000',
|
|
564
|
+
icon: 'custom',
|
|
565
|
+
defaultScopes: [],
|
|
566
|
+
metadata: {
|
|
567
|
+
buttonText: 'Continue with Custom',
|
|
568
|
+
},
|
|
569
|
+
}),
|
|
568
570
|
}
|
|
569
571
|
|
|
570
572
|
/**
|
package/src/types.ts
CHANGED
|
@@ -62,7 +62,7 @@ export type AuthenticationMethodType
|
|
|
62
62
|
| 'sso'
|
|
63
63
|
| 'otp'
|
|
64
64
|
|
|
65
|
-
export type SSOProvider = 'google' | 'microsoft' | 'github' | 'okta' | 'apple' | 'facebook'
|
|
65
|
+
export type SSOProvider = 'google' | 'microsoft' | 'github' | 'okta' | 'apple' | 'facebook' | 'custom'
|
|
66
66
|
|
|
67
67
|
export interface AuthenticationAccount {
|
|
68
68
|
created_at?: string
|
|
@@ -85,9 +85,9 @@ export interface PersonInfo {
|
|
|
85
85
|
name: string
|
|
86
86
|
first_name: string
|
|
87
87
|
last_name: string
|
|
88
|
-
email?: string
|
|
89
|
-
phone_number?: string
|
|
90
|
-
|
|
88
|
+
email?: string
|
|
89
|
+
phone_number?: string
|
|
90
|
+
tags: string[]
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export interface AuthMethodInfo {
|
|
@@ -97,7 +97,7 @@ export interface AuthMethodInfo {
|
|
|
97
97
|
is_verified: boolean
|
|
98
98
|
last_used?: string
|
|
99
99
|
use_count: number
|
|
100
|
-
provider?:
|
|
100
|
+
provider?: string
|
|
101
101
|
provider_user_id?: string
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -107,9 +107,10 @@ export interface AccountInfo {
|
|
|
107
107
|
display_name: string
|
|
108
108
|
is_active: boolean
|
|
109
109
|
is_verified: boolean
|
|
110
|
-
last_login?: string
|
|
110
|
+
last_login?: string
|
|
111
|
+
roles: string[]
|
|
111
112
|
authentication_methods: AuthMethodInfo[]
|
|
112
|
-
person?: PersonInfo
|
|
113
|
+
person?: PersonInfo
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
// Note: EntityInfo kept for backward compatibility
|
|
@@ -209,6 +210,34 @@ export interface VerifyEmailRequest {
|
|
|
209
210
|
token: string
|
|
210
211
|
}
|
|
211
212
|
|
|
213
|
+
export interface EmailTokenSendRequest {
|
|
214
|
+
email: string
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface EmailTokenVerifyRequest {
|
|
218
|
+
email: string
|
|
219
|
+
token: string
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface OTPSendRequest {
|
|
223
|
+
phone_number: string
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export interface OTPVerifyRequest {
|
|
227
|
+
phone_number: string
|
|
228
|
+
otp_code: string
|
|
229
|
+
nonce: string
|
|
230
|
+
verification_hash: string
|
|
231
|
+
timestamp: number
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface SSOLoginRequest {
|
|
235
|
+
provider: SSOProvider
|
|
236
|
+
authorization_code?: string
|
|
237
|
+
id_token?: string
|
|
238
|
+
access_token?: string
|
|
239
|
+
}
|
|
240
|
+
|
|
212
241
|
// Client-side helper types
|
|
213
242
|
export interface NewUser extends RegisterRequest {
|
|
214
243
|
confirmPassword: string
|
|
@@ -244,37 +273,28 @@ export interface OTPMetadata {
|
|
|
244
273
|
}
|
|
245
274
|
|
|
246
275
|
export interface SSOMetadata {
|
|
247
|
-
provider:
|
|
276
|
+
provider: string
|
|
248
277
|
sso_user_info: { [key: string]: any }
|
|
249
278
|
can_create_account?: boolean
|
|
250
279
|
}
|
|
251
280
|
|
|
252
281
|
export interface SSOInitiateRequest {
|
|
253
|
-
provider: SSOProvider
|
|
254
282
|
redirect_uri?: string
|
|
255
|
-
state
|
|
283
|
+
state: string
|
|
256
284
|
scopes?: string[]
|
|
257
|
-
params?:
|
|
258
|
-
code_challenge?: string // For PKCE flow
|
|
259
|
-
code_challenge_method?: 'S256' | 'plain'
|
|
285
|
+
params?: { [key: string]: any }
|
|
260
286
|
}
|
|
261
287
|
|
|
262
288
|
export interface SSOCallbackRequest {
|
|
263
|
-
provider: SSOProvider
|
|
264
289
|
code: string
|
|
265
|
-
state
|
|
290
|
+
state: string
|
|
266
291
|
}
|
|
267
292
|
|
|
268
293
|
export interface SSOLinkRequest {
|
|
269
|
-
provider: SSOProvider
|
|
270
294
|
code: string
|
|
271
295
|
state: string
|
|
272
296
|
}
|
|
273
297
|
|
|
274
|
-
export interface SSOUnlinkRequest {
|
|
275
|
-
provider: SSOProvider
|
|
276
|
-
}
|
|
277
|
-
|
|
278
298
|
export interface AuthenticationResponse {
|
|
279
299
|
success: boolean
|
|
280
300
|
account_id?: string
|
|
@@ -317,11 +337,39 @@ export type DeleteSessionResponse = AxiosResponse<MessageResponse>
|
|
|
317
337
|
export type DeleteAllSessionsResponse = AxiosResponse<MessageResponse>
|
|
318
338
|
export type CleanupSessionsResponse = AxiosResponse<MessageResponse>
|
|
319
339
|
export type GetMethodsResponse = AxiosResponse<AvailableMethodsResponse>
|
|
320
|
-
export
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
export
|
|
340
|
+
export interface SSOInitiateResponse {
|
|
341
|
+
authorization_url: string
|
|
342
|
+
}
|
|
343
|
+
export interface SSOCallbackResponse {
|
|
344
|
+
success: boolean
|
|
345
|
+
account_id?: string
|
|
346
|
+
session_token?: string
|
|
347
|
+
requires_verification?: boolean
|
|
348
|
+
metadata?: { [key: string]: any }
|
|
349
|
+
message?: string
|
|
350
|
+
}
|
|
351
|
+
export interface SSOLinkResponse {
|
|
352
|
+
success?: boolean
|
|
353
|
+
message?: string
|
|
354
|
+
provider?: string
|
|
355
|
+
provider_user_id?: string
|
|
356
|
+
email?: string
|
|
357
|
+
}
|
|
358
|
+
export interface SSOUnlinkResponse {
|
|
359
|
+
success?: boolean
|
|
360
|
+
message?: string
|
|
361
|
+
}
|
|
362
|
+
export type InitiateSSOResponse = AxiosResponse<SSOInitiateResponse>
|
|
363
|
+
export type CallbackSSOResponse = AxiosResponse<SSOCallbackResponse>
|
|
364
|
+
export type LinkSSOResponse = AxiosResponse<SSOLinkResponse>
|
|
365
|
+
export type UnlinkSSOResponse = AxiosResponse<SSOUnlinkResponse>
|
|
324
366
|
export type GetTenantsResponse = AxiosResponse<TenantInfo[]>
|
|
367
|
+
export type GetAuthStatusResponse = AxiosResponse<AuthStatusResponse>
|
|
368
|
+
export type SendEmailTokenResponse = AxiosResponse<AuthenticationResponse>
|
|
369
|
+
export type VerifyEmailTokenResponse = AxiosResponse<AuthenticationResponse>
|
|
370
|
+
export type SendOTPResponse = AxiosResponse<AuthenticationResponse>
|
|
371
|
+
export type VerifyOTPResponse = AxiosResponse<AuthenticationResponse>
|
|
372
|
+
export type LegacySSOLoginResponse = AxiosResponse<AuthenticationResponse>
|
|
325
373
|
|
|
326
374
|
// ============================================
|
|
327
375
|
// Helper Functions (exported for convenience)
|
|
@@ -342,13 +390,13 @@ export function accountToUser(account: AccountInfo | null): User | null {
|
|
|
342
390
|
id: account.person!.id,
|
|
343
391
|
accountId: account.id,
|
|
344
392
|
name: account.person!.name,
|
|
345
|
-
email: account.person!.email
|
|
393
|
+
email: account.person!.email,
|
|
346
394
|
type: account.account_type as AuthenticationAccountType,
|
|
347
|
-
roles: account.
|
|
395
|
+
roles: account.roles,
|
|
348
396
|
isActive: account.is_active,
|
|
349
397
|
isVerified: account.is_verified,
|
|
350
398
|
person: account.person!,
|
|
351
|
-
lastLogin: account.last_login
|
|
399
|
+
lastLogin: account.last_login,
|
|
352
400
|
hasPersonLinked: true,
|
|
353
401
|
}
|
|
354
402
|
}
|
|
@@ -364,9 +412,10 @@ export function accountToUser(account: AccountInfo | null): User | null {
|
|
|
364
412
|
name: account.display_name,
|
|
365
413
|
email: emailMethod?.identifier,
|
|
366
414
|
type: account.account_type as AuthenticationAccountType,
|
|
415
|
+
roles: account.roles,
|
|
367
416
|
isActive: account.is_active,
|
|
368
417
|
isVerified: account.is_verified,
|
|
369
|
-
lastLogin: account.last_login
|
|
418
|
+
lastLogin: account.last_login,
|
|
370
419
|
hasPersonLinked: false,
|
|
371
420
|
}
|
|
372
421
|
}
|