@bagelink/auth 1.4.171 → 1.4.174
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 +254 -110
- package/dist/index.cjs +83 -32
- package/dist/index.d.cts +60 -12
- package/dist/index.d.mts +60 -12
- package/dist/index.d.ts +60 -12
- package/dist/index.mjs +84 -34
- package/package.json +1 -1
- package/src/types.ts +94 -8
- package/src/useAuth.ts +48 -36
package/src/types.ts
CHANGED
|
@@ -83,6 +83,14 @@ export interface AccountInfo {
|
|
|
83
83
|
last_login?: string
|
|
84
84
|
authentication_methods: AuthMethodInfo[]
|
|
85
85
|
person?: PersonInfo
|
|
86
|
+
entity?: EntityInfo
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface EntityInfo {
|
|
90
|
+
id: string
|
|
91
|
+
name: string
|
|
92
|
+
type?: string
|
|
93
|
+
metadata?: Record<string, any>
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
export interface SessionInfo {
|
|
@@ -94,6 +102,39 @@ export interface SessionInfo {
|
|
|
94
102
|
is_current?: boolean
|
|
95
103
|
}
|
|
96
104
|
|
|
105
|
+
// ============================================
|
|
106
|
+
// Unified User Type (Person or Entity)
|
|
107
|
+
// ============================================
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Unified user representation that works for both person and entity accounts
|
|
111
|
+
* This is the primary interface for accessing user data in the application
|
|
112
|
+
*/
|
|
113
|
+
export interface User {
|
|
114
|
+
/** Unique identifier (person_id or entity_id) */
|
|
115
|
+
id: string
|
|
116
|
+
/** Account ID */
|
|
117
|
+
accountId: string
|
|
118
|
+
/** Display name */
|
|
119
|
+
name: string
|
|
120
|
+
/** Email address (from person or authentication methods) */
|
|
121
|
+
email?: string
|
|
122
|
+
/** Account type: 'person', 'entity', or 'service' */
|
|
123
|
+
type: AuthenticationAccountType
|
|
124
|
+
/** User roles (only for person accounts) */
|
|
125
|
+
roles?: string[]
|
|
126
|
+
/** Is the account active */
|
|
127
|
+
isActive: boolean
|
|
128
|
+
/** Is the account verified */
|
|
129
|
+
isVerified: boolean
|
|
130
|
+
/** Last login timestamp */
|
|
131
|
+
lastLogin?: string
|
|
132
|
+
/** Entity-specific info (only for entity accounts) */
|
|
133
|
+
entityType?: string
|
|
134
|
+
/** Additional metadata */
|
|
135
|
+
metadata?: Record<string, any>
|
|
136
|
+
}
|
|
137
|
+
|
|
97
138
|
// ============================================
|
|
98
139
|
// Request Types
|
|
99
140
|
// ============================================
|
|
@@ -224,14 +265,59 @@ export type CleanupSessionsResponse = AxiosResponse<MessageResponse>
|
|
|
224
265
|
export type GetMethodsResponse = AxiosResponse<AvailableMethodsResponse>
|
|
225
266
|
|
|
226
267
|
// ============================================
|
|
227
|
-
//
|
|
268
|
+
// Helper Functions (exported for convenience)
|
|
228
269
|
// ============================================
|
|
229
270
|
|
|
230
|
-
/**
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Extract unified user from account info
|
|
273
|
+
*/
|
|
274
|
+
export function accountToUser(account: AccountInfo | null): User | null {
|
|
275
|
+
if (account === null) return null
|
|
276
|
+
|
|
277
|
+
// Person account - most common case
|
|
278
|
+
if (account.person !== undefined) {
|
|
279
|
+
return {
|
|
280
|
+
id: account.person.id,
|
|
281
|
+
accountId: account.id,
|
|
282
|
+
name: account.person.name,
|
|
283
|
+
email: account.person.email,
|
|
284
|
+
type: account.account_type as AuthenticationAccountType,
|
|
285
|
+
roles: account.person.roles,
|
|
286
|
+
isActive: account.is_active,
|
|
287
|
+
isVerified: account.is_verified,
|
|
288
|
+
lastLogin: account.last_login,
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Entity account
|
|
293
|
+
if (account.entity !== undefined) {
|
|
294
|
+
return {
|
|
295
|
+
id: account.entity.id,
|
|
296
|
+
accountId: account.id,
|
|
297
|
+
name: account.entity.name,
|
|
298
|
+
type: account.account_type as AuthenticationAccountType,
|
|
299
|
+
isActive: account.is_active,
|
|
300
|
+
isVerified: account.is_verified,
|
|
301
|
+
lastLogin: account.last_login,
|
|
302
|
+
entityType: account.entity.type,
|
|
303
|
+
metadata: account.entity.metadata,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Fallback - use account info directly
|
|
308
|
+
// Extract email from authentication methods
|
|
309
|
+
const emailMethod = account.authentication_methods?.find(
|
|
310
|
+
m => m.type === 'password' || m.type === 'email_token',
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
id: account.id,
|
|
315
|
+
accountId: account.id,
|
|
316
|
+
name: account.display_name,
|
|
317
|
+
email: emailMethod?.identifier,
|
|
318
|
+
type: account.account_type as AuthenticationAccountType,
|
|
319
|
+
isActive: account.is_active,
|
|
320
|
+
isVerified: account.is_verified,
|
|
321
|
+
lastLogin: account.last_login,
|
|
322
|
+
}
|
|
237
323
|
}
|
package/src/useAuth.ts
CHANGED
|
@@ -2,20 +2,21 @@ import type { AxiosInstance } from 'axios'
|
|
|
2
2
|
import type { App } from 'vue'
|
|
3
3
|
import type {
|
|
4
4
|
AccountInfo,
|
|
5
|
+
User,
|
|
5
6
|
NewUser,
|
|
6
7
|
UpdatePasswordForm,
|
|
7
8
|
UpdateAccountRequest,
|
|
8
9
|
AuthEventMap,
|
|
9
10
|
} from './types'
|
|
10
|
-
import { ref } from 'vue'
|
|
11
|
+
import { ref, computed } from 'vue'
|
|
11
12
|
import { AuthApi } from './api'
|
|
12
|
-
import { AuthState } from './types'
|
|
13
|
+
import { AuthState, accountToUser } from './types'
|
|
13
14
|
import { EventEmitter } from './utils'
|
|
14
15
|
|
|
15
16
|
// Global state
|
|
16
17
|
let authApi: AuthApi | null = null
|
|
17
18
|
let eventEmitter: EventEmitter | null = null
|
|
18
|
-
const
|
|
19
|
+
const accountInfo = ref<AccountInfo | null>(null)
|
|
19
20
|
|
|
20
21
|
// Initialize auth
|
|
21
22
|
export function initAuth({
|
|
@@ -73,33 +74,36 @@ export function useAuth() {
|
|
|
73
74
|
const api = authApi
|
|
74
75
|
const emitter = eventEmitter
|
|
75
76
|
|
|
77
|
+
// Computed user - the primary interface for accessing user data
|
|
78
|
+
const user = computed<User | null>(() => accountToUser(accountInfo.value))
|
|
79
|
+
|
|
76
80
|
// Getters
|
|
77
81
|
const getFullName = () => {
|
|
78
|
-
|
|
79
|
-
if (user === null) return ''
|
|
80
|
-
if (user.person !== undefined) return user.person.name
|
|
81
|
-
return user.display_name ?? ''
|
|
82
|
+
return user.value?.name ?? ''
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
const getIsLoggedIn = () => {
|
|
85
|
-
|
|
86
|
-
return user !== null && user.id.length > 0
|
|
86
|
+
return user.value !== null
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
const getEmail = () => {
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
return user.value?.email ?? ''
|
|
91
|
+
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
93
|
+
const getRoles = () => {
|
|
94
|
+
return user.value?.roles ?? []
|
|
95
|
+
}
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
const getAccountType = () => {
|
|
98
|
+
return user.value?.type ?? 'person'
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const isPersonAccount = () => {
|
|
102
|
+
return user.value?.type === 'person'
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const isEntityAccount = () => {
|
|
106
|
+
return user.value?.type === 'entity'
|
|
103
107
|
}
|
|
104
108
|
|
|
105
109
|
// Actions
|
|
@@ -110,7 +114,7 @@ export function useAuth() {
|
|
|
110
114
|
// Ignore logout errors
|
|
111
115
|
})
|
|
112
116
|
// Clear local state regardless of API result
|
|
113
|
-
|
|
117
|
+
accountInfo.value = null
|
|
114
118
|
// Emit logout event
|
|
115
119
|
emitter.emit(AuthState.LOGOUT)
|
|
116
120
|
}
|
|
@@ -133,29 +137,30 @@ export function useAuth() {
|
|
|
133
137
|
async function checkAuth(): Promise<boolean> {
|
|
134
138
|
try {
|
|
135
139
|
const { data } = await api.getCurrentUser()
|
|
136
|
-
|
|
140
|
+
accountInfo.value = data
|
|
137
141
|
if (getIsLoggedIn()) {
|
|
138
142
|
emitter.emit(AuthState.AUTH_CHECK)
|
|
139
143
|
}
|
|
140
144
|
return true
|
|
141
145
|
} catch {
|
|
142
|
-
|
|
146
|
+
accountInfo.value = null
|
|
143
147
|
return false
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
150
|
|
|
147
|
-
async function signup(
|
|
151
|
+
async function signup(newUser: NewUser) {
|
|
148
152
|
// Check password match if password is provided
|
|
149
|
-
|
|
153
|
+
const hasPassword = newUser.password !== undefined && newUser.password.length > 0
|
|
154
|
+
if (hasPassword && newUser.password !== newUser.confirmPassword) {
|
|
150
155
|
throw new Error('Passwords do not match')
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
const { data } = await api.register({
|
|
154
|
-
email:
|
|
155
|
-
first_name:
|
|
156
|
-
last_name:
|
|
157
|
-
phone_number:
|
|
158
|
-
password:
|
|
159
|
+
email: newUser.email,
|
|
160
|
+
first_name: newUser.first_name,
|
|
161
|
+
last_name: newUser.last_name,
|
|
162
|
+
phone_number: newUser.phone_number,
|
|
163
|
+
password: newUser.password,
|
|
159
164
|
})
|
|
160
165
|
|
|
161
166
|
// If successful and not requiring verification, fetch user data
|
|
@@ -193,7 +198,7 @@ export function useAuth() {
|
|
|
193
198
|
|
|
194
199
|
async function updateProfile(updates: UpdateAccountRequest) {
|
|
195
200
|
const { data } = await api.updateCurrentUser(updates)
|
|
196
|
-
|
|
201
|
+
accountInfo.value = data
|
|
197
202
|
emitter.emit(AuthState.PROFILE_UPDATE)
|
|
198
203
|
}
|
|
199
204
|
|
|
@@ -211,7 +216,7 @@ export function useAuth() {
|
|
|
211
216
|
|
|
212
217
|
async function deleteCurrentUser() {
|
|
213
218
|
await api.deleteCurrentUser()
|
|
214
|
-
|
|
219
|
+
accountInfo.value = null
|
|
215
220
|
}
|
|
216
221
|
|
|
217
222
|
async function sendVerification(email?: string) {
|
|
@@ -231,7 +236,7 @@ export function useAuth() {
|
|
|
231
236
|
}
|
|
232
237
|
|
|
233
238
|
async function getSessions(accountId?: string) {
|
|
234
|
-
const id = accountId ??
|
|
239
|
+
const id = accountId ?? user.value?.accountId
|
|
235
240
|
if (id === undefined || id === '') {
|
|
236
241
|
throw new Error('No account ID available')
|
|
237
242
|
}
|
|
@@ -243,7 +248,7 @@ export function useAuth() {
|
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
async function revokeAllSessions(accountId?: string) {
|
|
246
|
-
const id = accountId ??
|
|
251
|
+
const id = accountId ?? user.value?.accountId
|
|
247
252
|
if (id === undefined || id === '') {
|
|
248
253
|
throw new Error('No account ID available')
|
|
249
254
|
}
|
|
@@ -251,13 +256,20 @@ export function useAuth() {
|
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
return {
|
|
254
|
-
// State
|
|
255
|
-
|
|
259
|
+
// Primary State (use this!)
|
|
260
|
+
user,
|
|
261
|
+
|
|
262
|
+
// Full account info (for advanced use cases)
|
|
263
|
+
accountInfo,
|
|
256
264
|
|
|
257
265
|
// Getters
|
|
258
266
|
getFullName,
|
|
259
267
|
getIsLoggedIn,
|
|
260
268
|
getEmail,
|
|
269
|
+
getRoles,
|
|
270
|
+
getAccountType,
|
|
271
|
+
isPersonAccount,
|
|
272
|
+
isEntityAccount,
|
|
261
273
|
|
|
262
274
|
// Authentication Actions
|
|
263
275
|
login,
|