@bagelink/auth 1.6.53 → 1.6.57
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 +284 -219
- package/dist/Callback-BHqVaZZm.cjs +4 -0
- package/dist/Callback-C-XghN_z.js +4 -0
- package/dist/ForgotPasswordPage-BV9tyhHl.cjs +4 -0
- package/dist/ForgotPasswordPage-DvttMGb0.js +4 -0
- package/dist/LoginPage-hv1wc54S.cjs +4 -0
- package/dist/LoginPage-klj1NV4J.js +4 -0
- package/dist/ResetPasswordPage-COPrJmW8.cjs +4 -0
- package/dist/ResetPasswordPage-nvQ4uupb.js +4 -0
- package/dist/SignupPage-m36w9PLJ.cjs +4 -0
- package/dist/SignupPage-oUFYApYW.js +4 -0
- package/dist/api.d.ts +115 -0
- package/dist/components/auth/ForgotPasswordForm.vue.d.ts +23 -0
- package/dist/components/auth/LoginForm.vue.d.ts +58 -0
- package/dist/components/auth/ResetPasswordForm.vue.d.ts +28 -0
- package/dist/components/auth/SignupForm.vue.d.ts +34 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/constants.d.ts +34 -0
- package/dist/index.cjs +1227 -30
- package/dist/index.d.ts +16 -631
- package/dist/index.mjs +1242 -24
- package/dist/pages/Callback.vue.d.ts +2 -0
- package/dist/pages/ForgotPasswordPage.vue.d.ts +13 -0
- package/dist/pages/LoginPage.vue.d.ts +38 -0
- package/dist/pages/ResetPasswordPage.vue.d.ts +13 -0
- package/dist/pages/SignupPage.vue.d.ts +16 -0
- package/dist/routes.d.ts +49 -0
- package/dist/sso.d.ts +145 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/types.d.ts +254 -0
- package/dist/useAuth.d.ts +112 -0
- package/dist/utils.d.ts +11 -0
- package/package.json +11 -13
- package/src/components/auth/ForgotPasswordForm.vue +97 -0
- package/src/components/auth/LoginForm.vue +257 -0
- package/src/components/auth/ResetPasswordForm.vue +146 -0
- package/src/components/auth/SignupForm.vue +224 -0
- package/src/components/index.ts +5 -0
- package/src/constants.ts +10 -0
- package/src/index.ts +26 -1
- package/src/pages/Callback.vue +183 -0
- package/src/pages/ForgotPasswordPage.vue +42 -0
- package/src/pages/LoginPage.vue +68 -0
- package/src/pages/ResetPasswordPage.vue +47 -0
- package/src/pages/SignupPage.vue +46 -0
- package/src/routes.ts +122 -0
- package/src/types/index.ts +45 -0
- package/dist/index.d.cts +0 -631
- package/dist/index.d.mts +0 -631
package/README.md
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
# @bagelink/auth
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🎯 **User-Centric Design** - Access user data directly, not buried in account objects
|
|
8
|
-
- 🔄 **Multi-Account Support** - Works with person, entity, and service accounts
|
|
9
|
-
- 🛡️ **Type-Safe** - Full TypeScript support
|
|
10
|
-
- ⚡ **Vue Integration** - Reactive refs with Vue 3 composables
|
|
11
|
-
- 🔐 **Complete Auth Flow** - Login, signup, password management, email verification
|
|
12
|
-
- 📡 **Session Management** - View, refresh, and revoke sessions
|
|
13
|
-
- 🎪 **Event System** - Listen to authentication state changes
|
|
14
|
-
- 🌐 **Framework Agnostic** - Core auth logic works anywhere
|
|
3
|
+
Authentication library for Bagelink applications with built-in SSO support, route management, and Vue components.
|
|
15
4
|
|
|
16
5
|
## Installation
|
|
17
6
|
|
|
18
7
|
```bash
|
|
19
|
-
pnpm add @bagelink/auth
|
|
20
|
-
# or
|
|
21
8
|
npm install @bagelink/auth
|
|
22
|
-
# or
|
|
23
|
-
bun add @bagelink/auth
|
|
24
9
|
```
|
|
25
10
|
|
|
26
11
|
## Quick Start
|
|
@@ -28,282 +13,368 @@ bun add @bagelink/auth
|
|
|
28
13
|
### 1. Initialize Auth
|
|
29
14
|
|
|
30
15
|
```typescript
|
|
31
|
-
import { initAuth
|
|
16
|
+
import { initAuth } from '@bagelink/auth'
|
|
32
17
|
|
|
33
|
-
|
|
34
|
-
|
|
18
|
+
initAuth({
|
|
19
|
+
apiEndpoint: 'https://api.your-app.com',
|
|
20
|
+
storageKey: 'auth_token',
|
|
21
|
+
// Optional: custom storage
|
|
22
|
+
storage: localStorage
|
|
35
23
|
})
|
|
24
|
+
```
|
|
36
25
|
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
### 2. Add Routes
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { createRouter } from 'vue-router'
|
|
30
|
+
import { createAuthRoutes, createAuthGuard } from '@bagelink/auth'
|
|
31
|
+
|
|
32
|
+
const router = createRouter({
|
|
33
|
+
history: createWebHistory(),
|
|
34
|
+
routes: [
|
|
35
|
+
// Add auth routes
|
|
36
|
+
...createAuthRoutes({
|
|
37
|
+
basePath: '/auth',
|
|
38
|
+
redirectTo: '/dashboard'
|
|
39
|
+
}),
|
|
40
|
+
|
|
41
|
+
// Your app routes
|
|
42
|
+
{
|
|
43
|
+
path: '/dashboard',
|
|
44
|
+
component: Dashboard,
|
|
45
|
+
meta: { requiresAuth: true }
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// Add auth guard to redirect authenticated users
|
|
51
|
+
router.beforeEach(createAuthGuard({ redirectTo: '/dashboard' }))
|
|
52
|
+
|
|
53
|
+
export default router
|
|
39
54
|
```
|
|
40
55
|
|
|
41
|
-
###
|
|
56
|
+
### 3. Use in Components
|
|
42
57
|
|
|
43
58
|
```vue
|
|
44
|
-
<script setup
|
|
59
|
+
<script setup>
|
|
45
60
|
import { useAuth } from '@bagelink/auth'
|
|
46
61
|
|
|
47
|
-
const {
|
|
48
|
-
user, // Primary state - use this!
|
|
49
|
-
sso, // SSO providers
|
|
50
|
-
getIsLoggedIn,
|
|
51
|
-
login,
|
|
52
|
-
logout
|
|
53
|
-
} = useAuth()
|
|
54
|
-
|
|
55
|
-
const handlePasswordLogin = async () => {
|
|
56
|
-
await login({
|
|
57
|
-
email: 'user@example.com',
|
|
58
|
-
password: 'password'
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const handleSSOLogin = async () => {
|
|
63
|
-
// SSO is just this simple!
|
|
64
|
-
await sso.google.redirect()
|
|
65
|
-
}
|
|
62
|
+
const { user, logout, isAuthenticated } = useAuth()
|
|
66
63
|
</script>
|
|
67
64
|
|
|
68
65
|
<template>
|
|
69
|
-
<div v-if="
|
|
70
|
-
<
|
|
71
|
-
<p>Email: {{ user.email }}</p>
|
|
66
|
+
<div v-if="isAuthenticated">
|
|
67
|
+
<p>Welcome, {{ user.name }}</p>
|
|
72
68
|
<button @click="logout">Logout</button>
|
|
73
69
|
</div>
|
|
74
|
-
<div v-else>
|
|
75
|
-
<button @click="handlePasswordLogin">Login with Password</button>
|
|
76
|
-
<button @click="handleSSOLogin">Login with Google</button>
|
|
77
|
-
</div>
|
|
78
70
|
</template>
|
|
79
71
|
```
|
|
80
72
|
|
|
81
|
-
##
|
|
82
|
-
|
|
83
|
-
### The `user` Object
|
|
73
|
+
## Route Configuration
|
|
84
74
|
|
|
85
|
-
|
|
75
|
+
### Basic Setup
|
|
86
76
|
|
|
87
77
|
```typescript
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// Available for all account types
|
|
91
|
-
user.value?.id // Person ID or Entity ID
|
|
92
|
-
user.value?.name // Display name
|
|
93
|
-
user.value?.email // Email address
|
|
94
|
-
user.value?.type // 'person', 'entity', or 'service'
|
|
95
|
-
user.value?.isActive // Is account active
|
|
96
|
-
user.value?.isVerified // Is account verified
|
|
97
|
-
|
|
98
|
-
// Person-specific
|
|
99
|
-
user.value?.roles // User roles (e.g., ['admin', 'user'])
|
|
100
|
-
|
|
101
|
-
// Entity-specific
|
|
102
|
-
user.value?.entityType // Entity type (e.g., 'company', 'organization')
|
|
103
|
-
user.value?.metadata // Additional entity metadata
|
|
78
|
+
createAuthRoutes()
|
|
79
|
+
// Creates routes: /login, /signup, /forgot-password, /reset-password, /callback
|
|
104
80
|
```
|
|
105
81
|
|
|
106
|
-
###
|
|
107
|
-
|
|
108
|
-
For authentication-specific data, use `accountInfo`:
|
|
82
|
+
### Custom Base Path
|
|
109
83
|
|
|
110
84
|
```typescript
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
accountInfo.value?.person // Raw person data
|
|
116
|
-
accountInfo.value?.entity // Raw entity data
|
|
85
|
+
createAuthRoutes({
|
|
86
|
+
basePath: '/auth'
|
|
87
|
+
})
|
|
88
|
+
// Creates routes: /auth/login, /auth/signup, etc.
|
|
117
89
|
```
|
|
118
90
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
### State
|
|
91
|
+
### Custom Route Names
|
|
122
92
|
|
|
123
93
|
```typescript
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
94
|
+
createAuthRoutes({
|
|
95
|
+
routeNames: {
|
|
96
|
+
login: 'UserLogin',
|
|
97
|
+
signup: 'UserRegister',
|
|
98
|
+
callback: 'OAuthCallback'
|
|
99
|
+
}
|
|
100
|
+
})
|
|
128
101
|
```
|
|
129
102
|
|
|
130
|
-
###
|
|
103
|
+
### With Layout Component
|
|
131
104
|
|
|
132
105
|
```typescript
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
getAccountType, // () => 'person' | 'entity' | 'service'
|
|
139
|
-
isPersonAccount, // () => boolean
|
|
140
|
-
isEntityAccount, // () => boolean
|
|
141
|
-
} = useAuth()
|
|
106
|
+
import AuthLayout from './layouts/AuthLayout.vue'
|
|
107
|
+
|
|
108
|
+
createAuthRoutes({
|
|
109
|
+
layout: AuthLayout
|
|
110
|
+
})
|
|
142
111
|
```
|
|
143
112
|
|
|
144
|
-
|
|
113
|
+
## Components
|
|
145
114
|
|
|
146
|
-
|
|
147
|
-
// Login
|
|
148
|
-
await login({ email: 'user@example.com', password: 'password' })
|
|
149
|
-
|
|
150
|
-
// Signup
|
|
151
|
-
await signup({
|
|
152
|
-
email: 'user@example.com',
|
|
153
|
-
first_name: 'John',
|
|
154
|
-
last_name: 'Doe',
|
|
155
|
-
password: 'password',
|
|
156
|
-
confirmPassword: 'password'
|
|
157
|
-
})
|
|
115
|
+
### Form Components
|
|
158
116
|
|
|
159
|
-
|
|
160
|
-
await logout()
|
|
117
|
+
Use these if you want to build custom pages:
|
|
161
118
|
|
|
162
|
-
|
|
163
|
-
|
|
119
|
+
```vue
|
|
120
|
+
<script setup>
|
|
121
|
+
import { LoginForm, SignupForm } from '@bagelink/auth'
|
|
122
|
+
</script>
|
|
164
123
|
|
|
165
|
-
|
|
166
|
-
|
|
124
|
+
<template>
|
|
125
|
+
<LoginForm
|
|
126
|
+
:texts="{ title: 'Welcome Back' }"
|
|
127
|
+
:show-github="true"
|
|
128
|
+
:show-google="true"
|
|
129
|
+
@switch-form="handleFormSwitch"
|
|
130
|
+
/>
|
|
131
|
+
</template>
|
|
167
132
|
```
|
|
168
133
|
|
|
169
|
-
###
|
|
134
|
+
### Page Components
|
|
170
135
|
|
|
171
|
-
|
|
172
|
-
// Change password (requires current password)
|
|
173
|
-
await changePassword({
|
|
174
|
-
current_password: 'oldPassword',
|
|
175
|
-
new_password: 'newPassword',
|
|
176
|
-
confirmNewPassword: 'newPassword'
|
|
177
|
-
})
|
|
136
|
+
Pre-built page components with layout:
|
|
178
137
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
await verifyResetToken(token)
|
|
138
|
+
```vue
|
|
139
|
+
<script setup>
|
|
140
|
+
import { LoginPage } from '@bagelink/auth'
|
|
141
|
+
</script>
|
|
184
142
|
|
|
185
|
-
|
|
186
|
-
|
|
143
|
+
<template>
|
|
144
|
+
<LoginPage
|
|
145
|
+
:texts="{ title: 'Sign In' }"
|
|
146
|
+
card-width="500px"
|
|
147
|
+
/>
|
|
148
|
+
</template>
|
|
187
149
|
```
|
|
188
150
|
|
|
189
|
-
|
|
151
|
+
## SSO Configuration
|
|
190
152
|
|
|
191
|
-
|
|
192
|
-
// Send verification email
|
|
193
|
-
await sendVerification('user@example.com')
|
|
153
|
+
### Available Providers
|
|
194
154
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
155
|
+
- GitHub
|
|
156
|
+
- Google
|
|
157
|
+
- Microsoft
|
|
158
|
+
- Apple
|
|
159
|
+
- Okta
|
|
160
|
+
- Facebook
|
|
198
161
|
|
|
199
|
-
###
|
|
162
|
+
### Usage
|
|
200
163
|
|
|
201
164
|
```typescript
|
|
202
|
-
|
|
203
|
-
await updateProfile({
|
|
204
|
-
first_name: 'Jane',
|
|
205
|
-
last_name: 'Smith',
|
|
206
|
-
email: 'jane@example.com'
|
|
207
|
-
})
|
|
165
|
+
const { sso } = useAuth()
|
|
208
166
|
|
|
209
|
-
//
|
|
210
|
-
await
|
|
211
|
-
```
|
|
167
|
+
// Initiate SSO login
|
|
168
|
+
await sso.login('github')
|
|
212
169
|
|
|
213
|
-
|
|
170
|
+
// Handle callback (automatically handled in /callback route)
|
|
171
|
+
await sso.handleCallback()
|
|
214
172
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const sessions = data.sessions
|
|
173
|
+
// Link additional account
|
|
174
|
+
await sso.linkAccount('google')
|
|
175
|
+
```
|
|
219
176
|
|
|
220
|
-
|
|
221
|
-
await revokeSession(sessionToken)
|
|
177
|
+
### Customizing SSO Buttons
|
|
222
178
|
|
|
223
|
-
|
|
224
|
-
|
|
179
|
+
```vue
|
|
180
|
+
<LoginForm
|
|
181
|
+
:show-github="true"
|
|
182
|
+
:show-google="true"
|
|
183
|
+
:show-microsoft="false"
|
|
184
|
+
:sso-outline="true"
|
|
185
|
+
:sso-show-value="true"
|
|
186
|
+
:sso-brand-background="true"
|
|
187
|
+
/>
|
|
225
188
|
```
|
|
226
189
|
|
|
227
|
-
|
|
190
|
+
## API
|
|
228
191
|
|
|
229
|
-
|
|
230
|
-
// Activate/deactivate accounts
|
|
231
|
-
await activateAccount(accountId)
|
|
232
|
-
await deactivateAccount(accountId)
|
|
192
|
+
### `useAuth()`
|
|
233
193
|
|
|
234
|
-
|
|
235
|
-
await deleteAccount(accountId)
|
|
236
|
-
```
|
|
194
|
+
Returns the authentication composable with:
|
|
237
195
|
|
|
238
|
-
|
|
196
|
+
- `user` - Current user object (reactive)
|
|
197
|
+
- `isAuthenticated` - Boolean indicating auth status (computed)
|
|
198
|
+
- `accountInfo` - Extended account information (reactive)
|
|
199
|
+
- `login(email, password)` - Login with credentials
|
|
200
|
+
- `signup(data)` - Create new account
|
|
201
|
+
- `logout()` - Logout current user
|
|
202
|
+
- `forgotPassword(email)` - Request password reset
|
|
203
|
+
- `resetPassword(token, password)` - Reset password with token
|
|
204
|
+
- `sso` - SSO methods object
|
|
239
205
|
|
|
240
|
-
|
|
206
|
+
### `initAuth(config)`
|
|
207
|
+
|
|
208
|
+
Initialize the auth module:
|
|
241
209
|
|
|
242
210
|
```typescript
|
|
243
|
-
|
|
211
|
+
initAuth({
|
|
212
|
+
apiEndpoint: string // Required: Your API endpoint
|
|
213
|
+
storageKey?: string // Optional: Storage key (default: 'auth_token')
|
|
214
|
+
storage?: Storage // Optional: Storage mechanism (default: localStorage)
|
|
215
|
+
})
|
|
216
|
+
```
|
|
244
217
|
|
|
245
|
-
|
|
218
|
+
### `createAuthRoutes(config)`
|
|
246
219
|
|
|
247
|
-
|
|
248
|
-
auth.on(AuthState.LOGIN, () => {
|
|
249
|
-
console.log('User logged in')
|
|
250
|
-
})
|
|
220
|
+
Create auth routes for Vue Router:
|
|
251
221
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
222
|
+
```typescript
|
|
223
|
+
createAuthRoutes({
|
|
224
|
+
basePath?: string // Base path for routes (default: '')
|
|
225
|
+
namePrefix?: string // Prefix for route names (default: '')
|
|
226
|
+
routeNames?: { // Custom route names
|
|
227
|
+
login?: string
|
|
228
|
+
signup?: string
|
|
229
|
+
forgotPassword?: string
|
|
230
|
+
resetPassword?: string
|
|
231
|
+
callback?: string
|
|
232
|
+
}
|
|
233
|
+
redirectTo?: string // Redirect after auth (default: '/')
|
|
234
|
+
layout?: Component // Wrapper layout component
|
|
255
235
|
})
|
|
236
|
+
```
|
|
256
237
|
|
|
257
|
-
|
|
258
|
-
auth.on(AuthState.SIGNUP, () => {
|
|
259
|
-
console.log('User signed up')
|
|
260
|
-
})
|
|
238
|
+
### `createAuthGuard(config)`
|
|
261
239
|
|
|
262
|
-
|
|
263
|
-
auth.on(AuthState.PASSWORD_CHANGE, () => {
|
|
264
|
-
console.log('Password changed')
|
|
265
|
-
})
|
|
240
|
+
Create a navigation guard:
|
|
266
241
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
242
|
+
```typescript
|
|
243
|
+
createAuthGuard({
|
|
244
|
+
redirectTo?: string // Where to redirect authenticated users (default: '/')
|
|
270
245
|
})
|
|
246
|
+
```
|
|
271
247
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
248
|
+
## Customization
|
|
249
|
+
|
|
250
|
+
### Text Customization
|
|
251
|
+
|
|
252
|
+
All forms support custom text via the `texts` prop:
|
|
276
253
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
254
|
+
```vue
|
|
255
|
+
<LoginForm
|
|
256
|
+
:texts="{
|
|
257
|
+
title: 'Sign In',
|
|
258
|
+
emailLabel: 'Email Address',
|
|
259
|
+
passwordLabel: 'Password',
|
|
260
|
+
loginButton: 'Continue',
|
|
261
|
+
githubButton: 'Continue with GitHub'
|
|
262
|
+
}"
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Multi-language Support
|
|
267
|
+
|
|
268
|
+
```vue
|
|
269
|
+
<script setup>
|
|
270
|
+
import { ref, computed } from 'vue'
|
|
271
|
+
import { LoginForm } from '@bagelink/auth'
|
|
272
|
+
|
|
273
|
+
const locale = ref('en')
|
|
274
|
+
|
|
275
|
+
const texts = computed(() => {
|
|
276
|
+
if (locale.value === 'he') {
|
|
277
|
+
return {
|
|
278
|
+
title: 'התחברות',
|
|
279
|
+
emailLabel: 'אימייל',
|
|
280
|
+
passwordLabel: 'סיסמה',
|
|
281
|
+
loginButton: 'התחברות'
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
title: 'Login',
|
|
286
|
+
emailLabel: 'Email',
|
|
287
|
+
passwordLabel: 'Password',
|
|
288
|
+
loginButton: 'Login'
|
|
289
|
+
}
|
|
280
290
|
})
|
|
291
|
+
</script>
|
|
292
|
+
|
|
293
|
+
<template>
|
|
294
|
+
<LoginForm :texts="texts" />
|
|
295
|
+
</template>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Custom Layout
|
|
281
299
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
300
|
+
Create a layout wrapper:
|
|
301
|
+
|
|
302
|
+
```vue
|
|
303
|
+
<!-- AuthLayout.vue -->
|
|
304
|
+
<template>
|
|
305
|
+
<div class="auth-layout">
|
|
306
|
+
<header>
|
|
307
|
+
<img src="/logo.png" alt="Logo">
|
|
308
|
+
</header>
|
|
309
|
+
<main>
|
|
310
|
+
<router-view />
|
|
311
|
+
</main>
|
|
312
|
+
<footer>
|
|
313
|
+
© 2024 Your Company
|
|
314
|
+
</footer>
|
|
315
|
+
</div>
|
|
316
|
+
</template>
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Then use it:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import AuthLayout from './AuthLayout.vue'
|
|
323
|
+
|
|
324
|
+
createAuthRoutes({
|
|
325
|
+
layout: AuthLayout
|
|
285
326
|
})
|
|
327
|
+
```
|
|
286
328
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
329
|
+
## Advanced Usage
|
|
330
|
+
|
|
331
|
+
### Protected Routes
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
router.beforeEach(async (to, from, next) => {
|
|
335
|
+
const { isAuthenticated } = useAuth()
|
|
336
|
+
|
|
337
|
+
if (to.meta.requiresAuth && !isAuthenticated.value) {
|
|
338
|
+
next('/login')
|
|
339
|
+
} else {
|
|
340
|
+
next()
|
|
341
|
+
}
|
|
290
342
|
})
|
|
291
343
|
```
|
|
292
344
|
|
|
293
|
-
###
|
|
345
|
+
### Programmatic Navigation
|
|
294
346
|
|
|
295
347
|
```typescript
|
|
296
|
-
|
|
297
|
-
auth
|
|
348
|
+
import { useRouter } from 'vue-router'
|
|
349
|
+
import { useAuth } from '@bagelink/auth'
|
|
298
350
|
|
|
299
|
-
|
|
300
|
-
|
|
351
|
+
const router = useRouter()
|
|
352
|
+
const { login } = useAuth()
|
|
301
353
|
|
|
302
|
-
|
|
303
|
-
|
|
354
|
+
async function handleLogin() {
|
|
355
|
+
try {
|
|
356
|
+
await login(email, password)
|
|
357
|
+
router.push('/dashboard')
|
|
358
|
+
} catch (error) {
|
|
359
|
+
console.error('Login failed:', error)
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
```
|
|
304
363
|
|
|
305
|
-
|
|
306
|
-
|
|
364
|
+
### Custom Error Handling
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
const { login } = useAuth()
|
|
368
|
+
|
|
369
|
+
try {
|
|
370
|
+
await login(email, password)
|
|
371
|
+
} catch (error) {
|
|
372
|
+
if (error.code === 'INVALID_CREDENTIALS') {
|
|
373
|
+
// Handle invalid credentials
|
|
374
|
+
} else if (error.code === 'NETWORK_ERROR') {
|
|
375
|
+
// Handle network error
|
|
376
|
+
}
|
|
377
|
+
}
|
|
307
378
|
```
|
|
308
379
|
|
|
309
380
|
## TypeScript Support
|
|
@@ -311,23 +382,17 @@ auth.removeAllListeners()
|
|
|
311
382
|
Full TypeScript support with exported types:
|
|
312
383
|
|
|
313
384
|
```typescript
|
|
314
|
-
import type {
|
|
385
|
+
import type {
|
|
386
|
+
AuthState,
|
|
315
387
|
User,
|
|
316
388
|
AccountInfo,
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
AuthenticationResponse,
|
|
322
|
-
SessionInfo,
|
|
323
|
-
// ... and more
|
|
389
|
+
SSOProvider,
|
|
390
|
+
LoginTexts,
|
|
391
|
+
SignupTexts,
|
|
392
|
+
AuthRouteConfig
|
|
324
393
|
} from '@bagelink/auth'
|
|
325
394
|
```
|
|
326
395
|
|
|
327
|
-
## Migration
|
|
328
|
-
|
|
329
|
-
Upgrading from an older version? See [MIGRATION.md](./MIGRATION.md) for detailed migration instructions.
|
|
330
|
-
|
|
331
396
|
## License
|
|
332
397
|
|
|
333
398
|
MIT
|