@bagelink/auth 1.6.53 → 1.6.61

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.
Files changed (49) hide show
  1. package/README.md +284 -219
  2. package/dist/Callback-BHqVaZZm.cjs +4 -0
  3. package/dist/Callback-C-XghN_z.js +4 -0
  4. package/dist/ForgotPasswordPage-BV9tyhHl.cjs +4 -0
  5. package/dist/ForgotPasswordPage-DvttMGb0.js +4 -0
  6. package/dist/LoginPage-hv1wc54S.cjs +4 -0
  7. package/dist/LoginPage-klj1NV4J.js +4 -0
  8. package/dist/ResetPasswordPage-COPrJmW8.cjs +4 -0
  9. package/dist/ResetPasswordPage-nvQ4uupb.js +4 -0
  10. package/dist/SignupPage-m36w9PLJ.cjs +4 -0
  11. package/dist/SignupPage-oUFYApYW.js +4 -0
  12. package/dist/api.d.ts +115 -0
  13. package/dist/components/auth/ForgotPasswordForm.vue.d.ts +23 -0
  14. package/dist/components/auth/LoginForm.vue.d.ts +58 -0
  15. package/dist/components/auth/ResetPasswordForm.vue.d.ts +28 -0
  16. package/dist/components/auth/SignupForm.vue.d.ts +34 -0
  17. package/dist/components/index.d.ts +4 -0
  18. package/dist/constants.d.ts +34 -0
  19. package/dist/index.cjs +1227 -30
  20. package/dist/index.d.ts +16 -631
  21. package/dist/index.mjs +1242 -24
  22. package/dist/pages/Callback.vue.d.ts +2 -0
  23. package/dist/pages/ForgotPasswordPage.vue.d.ts +13 -0
  24. package/dist/pages/LoginPage.vue.d.ts +38 -0
  25. package/dist/pages/ResetPasswordPage.vue.d.ts +13 -0
  26. package/dist/pages/SignupPage.vue.d.ts +16 -0
  27. package/dist/routes.d.ts +49 -0
  28. package/dist/sso.d.ts +145 -0
  29. package/dist/types/index.d.ts +41 -0
  30. package/dist/types.d.ts +254 -0
  31. package/dist/useAuth.d.ts +112 -0
  32. package/dist/utils.d.ts +11 -0
  33. package/package.json +11 -13
  34. package/src/components/auth/ForgotPasswordForm.vue +97 -0
  35. package/src/components/auth/LoginForm.vue +257 -0
  36. package/src/components/auth/ResetPasswordForm.vue +146 -0
  37. package/src/components/auth/SignupForm.vue +224 -0
  38. package/src/components/index.ts +5 -0
  39. package/src/constants.ts +10 -0
  40. package/src/index.ts +26 -1
  41. package/src/pages/Callback.vue +183 -0
  42. package/src/pages/ForgotPasswordPage.vue +42 -0
  43. package/src/pages/LoginPage.vue +68 -0
  44. package/src/pages/ResetPasswordPage.vue +47 -0
  45. package/src/pages/SignupPage.vue +46 -0
  46. package/src/routes.ts +122 -0
  47. package/src/types/index.ts +45 -0
  48. package/dist/index.d.cts +0 -631
  49. package/dist/index.d.mts +0 -631
package/README.md CHANGED
@@ -1,26 +1,11 @@
1
1
  # @bagelink/auth
2
2
 
3
- A user-centric authentication library with Vue support. Handles both person and entity accounts seamlessly.
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, AuthState } from '@bagelink/auth'
16
+ import { initAuth } from '@bagelink/auth'
32
17
 
33
- const auth = initAuth({
34
- baseURL: 'https://api.example.com'
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
- // Listen to auth events
38
- auth.on(AuthState.LOGIN, () => console.log('User logged in!'))
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
- ### 2. Use in Vue Components
56
+ ### 3. Use in Components
42
57
 
43
58
  ```vue
44
- <script setup lang="ts">
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="user">
70
- <h1>Welcome, {{ user.name }}!</h1>
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
- ## Core Concepts
82
-
83
- ### The `user` Object
73
+ ## Route Configuration
84
74
 
85
- The `user` is a **computed ref** that provides a unified interface for both person and entity accounts:
75
+ ### Basic Setup
86
76
 
87
77
  ```typescript
88
- const { user } = useAuth()
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
- ### Account Info (Advanced)
107
-
108
- For authentication-specific data, use `accountInfo`:
82
+ ### Custom Base Path
109
83
 
110
84
  ```typescript
111
- const { accountInfo } = useAuth()
112
-
113
- accountInfo.value?.authentication_methods // Auth methods
114
- accountInfo.value?.last_login // Last login timestamp
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
- ## API Reference
120
-
121
- ### State
91
+ ### Custom Route Names
122
92
 
123
93
  ```typescript
124
- const {
125
- user, // Computed<User | null> - Primary state
126
- accountInfo, // Ref<AccountInfo | null> - Full account data
127
- } = useAuth()
94
+ createAuthRoutes({
95
+ routeNames: {
96
+ login: 'UserLogin',
97
+ signup: 'UserRegister',
98
+ callback: 'OAuthCallback'
99
+ }
100
+ })
128
101
  ```
129
102
 
130
- ### Getters
103
+ ### With Layout Component
131
104
 
132
105
  ```typescript
133
- const {
134
- getFullName, // () => string
135
- getIsLoggedIn, // () => boolean
136
- getEmail, // () => string
137
- getRoles, // () => string[]
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
- ### Authentication
113
+ ## Components
145
114
 
146
- ```typescript
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
- // Logout
160
- await logout()
117
+ Use these if you want to build custom pages:
161
118
 
162
- // Check auth status
163
- const isAuthenticated = await checkAuth()
119
+ ```vue
120
+ <script setup>
121
+ import { LoginForm, SignupForm } from '@bagelink/auth'
122
+ </script>
164
123
 
165
- // Refresh session
166
- await refreshSession()
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
- ### Password Management
134
+ ### Page Components
170
135
 
171
- ```typescript
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
- // Forgot password
180
- await forgotPassword('user@example.com')
181
-
182
- // Verify reset token
183
- await verifyResetToken(token)
138
+ ```vue
139
+ <script setup>
140
+ import { LoginPage } from '@bagelink/auth'
141
+ </script>
184
142
 
185
- // Reset password with token
186
- await resetPassword(token, 'newPassword')
143
+ <template>
144
+ <LoginPage
145
+ :texts="{ title: 'Sign In' }"
146
+ card-width="500px"
147
+ />
148
+ </template>
187
149
  ```
188
150
 
189
- ### Email Verification
151
+ ## SSO Configuration
190
152
 
191
- ```typescript
192
- // Send verification email
193
- await sendVerification('user@example.com')
153
+ ### Available Providers
194
154
 
195
- // Verify email with token
196
- await verifyEmail(token)
197
- ```
155
+ - GitHub
156
+ - Google
157
+ - Microsoft
158
+ - Apple
159
+ - Okta
160
+ - Facebook
198
161
 
199
- ### Profile Management
162
+ ### Usage
200
163
 
201
164
  ```typescript
202
- // Update profile
203
- await updateProfile({
204
- first_name: 'Jane',
205
- last_name: 'Smith',
206
- email: 'jane@example.com'
207
- })
165
+ const { sso } = useAuth()
208
166
 
209
- // Delete current user account
210
- await deleteCurrentUser()
211
- ```
167
+ // Initiate SSO login
168
+ await sso.login('github')
212
169
 
213
- ### Session Management
170
+ // Handle callback (automatically handled in /callback route)
171
+ await sso.handleCallback()
214
172
 
215
- ```typescript
216
- // Get active sessions
217
- const { data } = await getSessions()
218
- const sessions = data.sessions
173
+ // Link additional account
174
+ await sso.linkAccount('google')
175
+ ```
219
176
 
220
- // Revoke specific session
221
- await revokeSession(sessionToken)
177
+ ### Customizing SSO Buttons
222
178
 
223
- // Revoke all sessions
224
- await revokeAllSessions()
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
- ### Admin Actions
190
+ ## API
228
191
 
229
- ```typescript
230
- // Activate/deactivate accounts
231
- await activateAccount(accountId)
232
- await deactivateAccount(accountId)
192
+ ### `useAuth()`
233
193
 
234
- // Delete account
235
- await deleteAccount(accountId)
236
- ```
194
+ Returns the authentication composable with:
237
195
 
238
- ## Event System
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
- Listen to authentication state changes:
206
+ ### `initAuth(config)`
207
+
208
+ Initialize the auth module:
241
209
 
242
210
  ```typescript
243
- import { initAuth, AuthState } from '@bagelink/auth'
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
- const auth = initAuth({ axios })
218
+ ### `createAuthRoutes(config)`
246
219
 
247
- // Login
248
- auth.on(AuthState.LOGIN, () => {
249
- console.log('User logged in')
250
- })
220
+ Create auth routes for Vue Router:
251
221
 
252
- // Logout
253
- auth.on(AuthState.LOGOUT, () => {
254
- console.log('User logged out')
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
- // Signup
258
- auth.on(AuthState.SIGNUP, () => {
259
- console.log('User signed up')
260
- })
238
+ ### `createAuthGuard(config)`
261
239
 
262
- // Password changed
263
- auth.on(AuthState.PASSWORD_CHANGE, () => {
264
- console.log('Password changed')
265
- })
240
+ Create a navigation guard:
266
241
 
267
- // Password reset
268
- auth.on(AuthState.PASSWORD_RESET, () => {
269
- console.log('Password reset')
242
+ ```typescript
243
+ createAuthGuard({
244
+ redirectTo?: string // Where to redirect authenticated users (default: '/')
270
245
  })
246
+ ```
271
247
 
272
- // Profile updated
273
- auth.on(AuthState.PROFILE_UPDATE, () => {
274
- console.log('Profile updated')
275
- })
248
+ ## Customization
249
+
250
+ ### Text Customization
251
+
252
+ All forms support custom text via the `texts` prop:
276
253
 
277
- // Auth check completed
278
- auth.on(AuthState.AUTH_CHECK, () => {
279
- console.log('Auth verified')
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
- // Email verified
283
- auth.on(AuthState.EMAIL_VERIFIED, () => {
284
- console.log('Email verified')
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
- // Session refreshed
288
- auth.on(AuthState.SESSION_REFRESH, () => {
289
- console.log('Session refreshed')
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
- ### Event Methods
345
+ ### Programmatic Navigation
294
346
 
295
347
  ```typescript
296
- // Add listener
297
- auth.on(AuthState.LOGIN, handler)
348
+ import { useRouter } from 'vue-router'
349
+ import { useAuth } from '@bagelink/auth'
298
350
 
299
- // Remove listener
300
- auth.off(AuthState.LOGIN, handler)
351
+ const router = useRouter()
352
+ const { login } = useAuth()
301
353
 
302
- // Remove all listeners for an event
303
- auth.removeAllListeners(AuthState.LOGIN)
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
- // Remove all listeners
306
- auth.removeAllListeners()
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
- PersonInfo,
318
- EntityInfo,
319
- RegisterRequest,
320
- UpdateAccountRequest,
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
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const index = require("./index.cjs");
4
+ exports.default = index.Callback;
@@ -0,0 +1,4 @@
1
+ import { Callback as _sfc_main } from "./index.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const index = require("./index.cjs");
4
+ exports.default = index.ForgotPasswordPage;
@@ -0,0 +1,4 @@
1
+ import { ForgotPasswordPage as _sfc_main } from "./index.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const index = require("./index.cjs");
4
+ exports.default = index.LoginPage;
@@ -0,0 +1,4 @@
1
+ import { LoginPage as _sfc_main } from "./index.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const index = require("./index.cjs");
4
+ exports.default = index.ResetPasswordPage;
@@ -0,0 +1,4 @@
1
+ import { ResetPasswordPage as _sfc_main } from "./index.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const index = require("./index.cjs");
4
+ exports.default = index.SignupPage;
@@ -0,0 +1,4 @@
1
+ import { SignupPage as _sfc_main } from "./index.mjs";
2
+ export {
3
+ _sfc_main as default
4
+ };