@bagelink/auth 1.1.39 → 1.1.43
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/index.cjs +140 -179
- package/dist/index.d.cts +94 -34
- package/dist/index.d.mts +94 -34
- package/dist/index.d.ts +94 -34
- package/dist/index.mjs +136 -170
- package/package.json +13 -3
- package/src/api/auth.ts +104 -64
- package/src/composable/useAuth.ts +60 -123
- package/src/types.ts +79 -8
- package/src/api/api.ts +0 -24
|
@@ -1,121 +1,72 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { User, NewUser, UpdatePasswordForm
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
import type { User, NewUser, UpdatePasswordForm } from '../types'
|
|
3
|
+
import { AuthApi } from '../api/auth'
|
|
4
|
+
|
|
5
|
+
// Global state
|
|
6
|
+
let authApi: AuthApi | null = null
|
|
7
|
+
const currentUser = {
|
|
8
|
+
value: {
|
|
9
|
+
id: '',
|
|
10
|
+
email: '',
|
|
11
|
+
first_name: '',
|
|
12
|
+
last_name: '',
|
|
13
|
+
is_superuser: false,
|
|
14
|
+
is_active: false,
|
|
15
|
+
} as User,
|
|
16
|
+
set: (newValue: User) => {
|
|
17
|
+
currentUser.value = newValue
|
|
14
18
|
}
|
|
15
19
|
}
|
|
16
20
|
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// Create Vue reactive factory
|
|
23
|
-
function createVueReactiveFactory(app: any): ReactiveFactory {
|
|
24
|
-
return <T>(initial: T) => {
|
|
25
|
-
const refValue = app.ref(initial)
|
|
26
|
-
return {
|
|
27
|
-
get value() { return refValue.value },
|
|
28
|
-
set: (v: T) => { refValue.value = v }
|
|
29
|
-
}
|
|
21
|
+
// Initialize auth
|
|
22
|
+
export function initAuth(baseURL?: string) {
|
|
23
|
+
if (!authApi) {
|
|
24
|
+
authApi = new AuthApi(baseURL)
|
|
30
25
|
}
|
|
31
|
-
}
|
|
32
26
|
|
|
33
|
-
// Create plugin instance
|
|
34
|
-
export function initAuth({
|
|
35
|
-
axios,
|
|
36
|
-
errorHandler,
|
|
37
|
-
reactive = defaultReactiveFactory
|
|
38
|
-
}: {
|
|
39
|
-
axios?: AxiosInstance
|
|
40
|
-
errorHandler?: (error: any) => void
|
|
41
|
-
reactive?: ReactiveFactory
|
|
42
|
-
} = {}) {
|
|
43
|
-
api = axios || null
|
|
44
|
-
onError = errorHandler || null
|
|
45
|
-
createRef = reactive
|
|
46
|
-
|
|
47
|
-
// Return plugin interface
|
|
48
27
|
return {
|
|
49
|
-
install(app:
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
useAuth
|
|
28
|
+
install(app: App) {
|
|
29
|
+
// Make auth available globally
|
|
30
|
+
app.config.globalProperties.$auth = useAuth()
|
|
31
|
+
}
|
|
56
32
|
}
|
|
57
33
|
}
|
|
58
34
|
|
|
35
|
+
// Composable
|
|
59
36
|
export function useAuth() {
|
|
60
|
-
if (!
|
|
61
|
-
throw new Error('Auth
|
|
37
|
+
if (!authApi) {
|
|
38
|
+
throw new Error('Auth not initialized. Call initAuth first.')
|
|
62
39
|
}
|
|
63
40
|
|
|
64
|
-
// State
|
|
65
|
-
const currentUser = createRef<User>({
|
|
66
|
-
id: '',
|
|
67
|
-
email: '',
|
|
68
|
-
first_name: '',
|
|
69
|
-
last_name: '',
|
|
70
|
-
is_superuser: false,
|
|
71
|
-
is_active: false,
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
const passwordForm = createRef<UpdatePasswordForm>({
|
|
75
|
-
current_password: '',
|
|
76
|
-
new_password: '',
|
|
77
|
-
confirmNewPassword: '',
|
|
78
|
-
})
|
|
79
|
-
|
|
80
41
|
// Getters
|
|
81
42
|
const getFullName = () => `${currentUser.value.first_name} ${currentUser.value.last_name}`
|
|
82
43
|
const getIsLoggedIn = () => currentUser.value.id.length > 0
|
|
83
44
|
|
|
84
|
-
// Error handling
|
|
85
|
-
function handleError(error: any) {
|
|
86
|
-
if (onError) {
|
|
87
|
-
onError(error)
|
|
88
|
-
}
|
|
89
|
-
throw error
|
|
90
|
-
}
|
|
91
|
-
|
|
92
45
|
// Actions
|
|
93
46
|
async function logout() {
|
|
94
47
|
try {
|
|
95
|
-
await authApi
|
|
96
|
-
} catch (error
|
|
97
|
-
|
|
48
|
+
await authApi!.logout()
|
|
49
|
+
} catch (error) {
|
|
50
|
+
throw error
|
|
98
51
|
}
|
|
99
52
|
}
|
|
100
53
|
|
|
101
54
|
async function login(credentials: { email: string, password: string }) {
|
|
102
|
-
const email = credentials.email.toLowerCase()
|
|
103
|
-
const { password } = credentials
|
|
104
55
|
try {
|
|
105
|
-
await authApi
|
|
56
|
+
await authApi!.login(credentials.email.toLowerCase(), credentials.password)
|
|
106
57
|
await checkAuth()
|
|
107
|
-
} catch (error
|
|
108
|
-
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw error
|
|
109
60
|
}
|
|
110
61
|
}
|
|
111
62
|
|
|
112
63
|
async function checkAuth(): Promise<boolean> {
|
|
113
64
|
try {
|
|
114
65
|
if (!getIsLoggedIn()) {
|
|
115
|
-
const { data } = await authApi
|
|
66
|
+
const { data } = await authApi!.getCurrentUser()
|
|
116
67
|
currentUser.set(data)
|
|
117
68
|
}
|
|
118
|
-
} catch (error
|
|
69
|
+
} catch (error) {
|
|
119
70
|
return false
|
|
120
71
|
}
|
|
121
72
|
return getIsLoggedIn()
|
|
@@ -126,82 +77,68 @@ export function useAuth() {
|
|
|
126
77
|
if (user.password !== user.confirmPassword) {
|
|
127
78
|
throw new Error('Passwords do not match')
|
|
128
79
|
}
|
|
129
|
-
const { data } = await authApi
|
|
80
|
+
const { data } = await authApi!.signup(user)
|
|
130
81
|
currentUser.set(data)
|
|
131
|
-
} catch (error
|
|
132
|
-
|
|
82
|
+
} catch (error) {
|
|
83
|
+
throw error
|
|
133
84
|
}
|
|
134
85
|
}
|
|
135
86
|
|
|
136
87
|
async function recoverPassword(email: string) {
|
|
137
88
|
try {
|
|
138
|
-
await authApi
|
|
139
|
-
} catch (error
|
|
140
|
-
|
|
89
|
+
await authApi!.passwordRecovery(email)
|
|
90
|
+
} catch (error) {
|
|
91
|
+
throw error
|
|
141
92
|
}
|
|
142
93
|
}
|
|
143
94
|
|
|
144
|
-
async function resetPassword(
|
|
95
|
+
async function resetPassword(newPassword: string) {
|
|
145
96
|
try {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
await authApi.resetPassword(form.new_password)
|
|
150
|
-
form = {
|
|
151
|
-
current_password: '',
|
|
152
|
-
new_password: '',
|
|
153
|
-
confirmNewPassword: '',
|
|
154
|
-
}
|
|
155
|
-
} catch (error: any) {
|
|
156
|
-
handleError(error)
|
|
97
|
+
await authApi!.resetPassword(newPassword)
|
|
98
|
+
} catch (error) {
|
|
99
|
+
throw error
|
|
157
100
|
}
|
|
158
101
|
}
|
|
159
102
|
|
|
160
|
-
async function updatePassword() {
|
|
103
|
+
async function updatePassword(form: UpdatePasswordForm) {
|
|
161
104
|
try {
|
|
162
|
-
if (
|
|
105
|
+
if (form.new_password !== form.confirmNewPassword) {
|
|
163
106
|
throw new Error('Passwords do not match')
|
|
164
107
|
}
|
|
165
|
-
await authApi
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
new_password: '',
|
|
169
|
-
confirmNewPassword: '',
|
|
170
|
-
})
|
|
171
|
-
} catch (error: any) {
|
|
172
|
-
handleError(error)
|
|
108
|
+
await authApi!.updatePassword(form)
|
|
109
|
+
} catch (error) {
|
|
110
|
+
throw error
|
|
173
111
|
}
|
|
174
112
|
}
|
|
175
113
|
|
|
176
114
|
async function updateProfile(user: Partial<User>) {
|
|
177
115
|
try {
|
|
178
|
-
const { data } = await authApi
|
|
116
|
+
const { data } = await authApi!.updateUserProfile(user)
|
|
179
117
|
currentUser.set({ ...currentUser.value, ...data })
|
|
180
|
-
} catch (error
|
|
181
|
-
|
|
118
|
+
} catch (error) {
|
|
119
|
+
throw error
|
|
182
120
|
}
|
|
183
121
|
}
|
|
184
122
|
|
|
185
123
|
async function toggleUserStatus(userId: string, isActive: boolean) {
|
|
186
124
|
try {
|
|
187
|
-
await authApi
|
|
188
|
-
} catch (error
|
|
189
|
-
|
|
125
|
+
await authApi!.setUserStatus(userId, isActive)
|
|
126
|
+
} catch (error) {
|
|
127
|
+
throw error
|
|
190
128
|
}
|
|
191
129
|
}
|
|
192
130
|
|
|
193
131
|
async function deleteUser(userId: string) {
|
|
194
132
|
try {
|
|
195
|
-
await authApi
|
|
196
|
-
} catch (error
|
|
197
|
-
|
|
133
|
+
await authApi!.deleteUser(userId)
|
|
134
|
+
} catch (error) {
|
|
135
|
+
throw error
|
|
198
136
|
}
|
|
199
137
|
}
|
|
200
138
|
|
|
201
139
|
return {
|
|
202
140
|
// State
|
|
203
141
|
currentUser,
|
|
204
|
-
passwordForm,
|
|
205
142
|
|
|
206
143
|
// Getters
|
|
207
144
|
getFullName,
|
package/src/types.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type { AxiosResponse } from 'axios'
|
|
2
|
+
|
|
1
3
|
export interface User {
|
|
2
4
|
id: string
|
|
3
5
|
email: string
|
|
4
|
-
first_name
|
|
5
|
-
last_name
|
|
6
|
-
is_superuser
|
|
7
|
-
is_active
|
|
6
|
+
first_name?: string
|
|
7
|
+
last_name?: string
|
|
8
|
+
is_superuser?: boolean
|
|
9
|
+
is_active?: boolean
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
export interface UserRegister {
|
|
@@ -24,9 +26,78 @@ export interface UpdatePasswordForm {
|
|
|
24
26
|
confirmNewPassword: string
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
export interface
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
export interface ReactiveFactory {
|
|
30
|
+
<T>(initial: T): {
|
|
31
|
+
value: T
|
|
32
|
+
set: (newValue: T) => void
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// API Response Types
|
|
37
|
+
export interface Token {
|
|
38
|
+
access_token: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface PasswordRecovery {
|
|
42
|
+
email: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface NewPassword {
|
|
46
|
+
new_password: string
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface UserUpdate {
|
|
50
|
+
email?: string
|
|
51
|
+
is_active?: boolean
|
|
52
|
+
is_superuser?: boolean
|
|
53
|
+
first_name?: string
|
|
54
|
+
last_name?: string
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface UserUpdateMe {
|
|
58
|
+
email?: string
|
|
59
|
+
first_name?: string
|
|
60
|
+
last_name?: string
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface UpdatePassword {
|
|
64
|
+
current_password: string
|
|
65
|
+
new_password: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface UserCreate {
|
|
69
|
+
email: string
|
|
70
|
+
password: string
|
|
71
|
+
first_name?: string
|
|
72
|
+
last_name?: string
|
|
73
|
+
is_active?: boolean
|
|
74
|
+
is_superuser?: boolean
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface SanitizedUserOut {
|
|
78
|
+
email: string
|
|
79
|
+
is_active?: boolean
|
|
80
|
+
is_superuser?: boolean
|
|
81
|
+
first_name?: string
|
|
82
|
+
last_name?: string
|
|
83
|
+
id: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface SanitizedUserList {
|
|
87
|
+
data: SanitizedUserOut[]
|
|
88
|
+
count: number
|
|
30
89
|
}
|
|
31
90
|
|
|
32
|
-
|
|
91
|
+
// API Response Types
|
|
92
|
+
export type LoginResponse = AxiosResponse<Token>
|
|
93
|
+
export type PasswordRecoveryResponse = AxiosResponse
|
|
94
|
+
export type ResetPasswordResponse = AxiosResponse
|
|
95
|
+
export type GetUserResponse = AxiosResponse<SanitizedUserOut>
|
|
96
|
+
export type UpdateUserResponse = AxiosResponse<SanitizedUserOut>
|
|
97
|
+
export type DeleteUserResponse = AxiosResponse
|
|
98
|
+
export type GetUsersResponse = AxiosResponse<SanitizedUserList>
|
|
99
|
+
export type CreateUserResponse = AxiosResponse<SanitizedUserOut>
|
|
100
|
+
export type GetMeResponse = AxiosResponse<SanitizedUserOut>
|
|
101
|
+
export type UpdateMeResponse = AxiosResponse<SanitizedUserOut>
|
|
102
|
+
export type UpdatePasswordResponse = AxiosResponse
|
|
103
|
+
export type SignupResponse = AxiosResponse<SanitizedUserOut>
|
package/src/api/api.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { AxiosInstance } from 'axios'
|
|
2
|
-
import axios from 'axios'
|
|
3
|
-
|
|
4
|
-
let api: AxiosInstance | null = null
|
|
5
|
-
|
|
6
|
-
export function initApi(axiosInstance?: AxiosInstance) {
|
|
7
|
-
if (axiosInstance) {
|
|
8
|
-
api = axiosInstance
|
|
9
|
-
} else {
|
|
10
|
-
api = axios.create({
|
|
11
|
-
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8000',
|
|
12
|
-
headers: {
|
|
13
|
-
'Content-Type': 'application/json',
|
|
14
|
-
},
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function getApi(): AxiosInstance {
|
|
20
|
-
if (!api) {
|
|
21
|
-
throw new Error('API not initialized. Call initApi first.')
|
|
22
|
-
}
|
|
23
|
-
return api
|
|
24
|
-
}
|