vuethenticate 0.1.0 → 0.1.1
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 +296 -0
- package/package.json +1 -1
package/README.md
ADDED
@@ -0,0 +1,296 @@
|
|
1
|
+
# Vuethenticate
|
2
|
+
|
3
|
+
A Vue 3 authentication state management library using oidc-client-ts.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- 🔐 OIDC/OAuth2 authentication with automatic token management
|
8
|
+
- ⚡ Vue 3 Composition API with reactive state
|
9
|
+
- 🔄 Automatic token renewal
|
10
|
+
- 📦 TypeScript support
|
11
|
+
- 🎯 Minimal configuration required
|
12
|
+
- 🎨 Customizable callback component
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
```bash
|
17
|
+
npm install vuethenticate
|
18
|
+
```
|
19
|
+
|
20
|
+
## Quick Start
|
21
|
+
|
22
|
+
> **Important Setup Order**: Make sure to initialize `useAuth()` in your main App component or a parent component before any callback routes are accessible. The callback components depend on this initialization.
|
23
|
+
|
24
|
+
### 1. Configure Authentication
|
25
|
+
|
26
|
+
```vue
|
27
|
+
<!-- App.vue - Main Application Component -->
|
28
|
+
<script setup>
|
29
|
+
import { useAuth } from 'vuethenticate'
|
30
|
+
import { RouterView } from 'vue-router'
|
31
|
+
|
32
|
+
// Initialize authentication in your main app component
|
33
|
+
const { user, isAuthenticated, signIn, signOut } = useAuth({
|
34
|
+
authority: 'https://your-oidc-provider.com',
|
35
|
+
clientId: 'your-client-id'
|
36
|
+
})
|
37
|
+
</script>
|
38
|
+
|
39
|
+
<template>
|
40
|
+
<div id="app">
|
41
|
+
<nav>
|
42
|
+
<div v-if="isAuthenticated">
|
43
|
+
<p>Welcome, {{ user.profile.name }}!</p>
|
44
|
+
<button @click="signOut">Sign Out</button>
|
45
|
+
</div>
|
46
|
+
<div v-else>
|
47
|
+
<button @click="signIn">Sign In</button>
|
48
|
+
</div>
|
49
|
+
</nav>
|
50
|
+
|
51
|
+
<!-- Router outlet - callback routes will work properly now -->
|
52
|
+
<RouterView />
|
53
|
+
</div>
|
54
|
+
</template>
|
55
|
+
```
|
56
|
+
|
57
|
+
### 2. Setup Callback Route
|
58
|
+
|
59
|
+
```vue
|
60
|
+
<!-- CallbackPage.vue -->
|
61
|
+
<script setup>
|
62
|
+
import { AuthCallback } from 'vuethenticate'
|
63
|
+
|
64
|
+
function onSuccess(user, state) {
|
65
|
+
console.log('Authentication successful:', user)
|
66
|
+
console.log('State:', state)
|
67
|
+
// Redirect to app or show success message
|
68
|
+
window.location.href = '/dashboard'
|
69
|
+
}
|
70
|
+
|
71
|
+
function onError(error) {
|
72
|
+
console.error('Authentication failed:', error)
|
73
|
+
// Handle error - redirect to login or show error
|
74
|
+
window.location.href = '/login'
|
75
|
+
}
|
76
|
+
</script>
|
77
|
+
|
78
|
+
<template>
|
79
|
+
<AuthCallback
|
80
|
+
:onSuccess="onSuccess"
|
81
|
+
:onError="onError"
|
82
|
+
>
|
83
|
+
<div>Signing you in...</div>
|
84
|
+
|
85
|
+
<template #error="{ error }">
|
86
|
+
<div>
|
87
|
+
<h2>Authentication Failed</h2>
|
88
|
+
<p>{{ error.message }}</p>
|
89
|
+
</div>
|
90
|
+
</template>
|
91
|
+
</AuthCallback>
|
92
|
+
</template>
|
93
|
+
```
|
94
|
+
|
95
|
+
### 3. Add Route Configuration
|
96
|
+
|
97
|
+
```javascript
|
98
|
+
// router.js
|
99
|
+
import { createRouter, createWebHistory } from 'vue-router'
|
100
|
+
import CallbackPage from './CallbackPage.vue'
|
101
|
+
import SilentCallbackPage from './SilentCallbackPage.vue'
|
102
|
+
|
103
|
+
const routes = [
|
104
|
+
{
|
105
|
+
path: '/auth/callback',
|
106
|
+
component: CallbackPage
|
107
|
+
},
|
108
|
+
{
|
109
|
+
path: '/auth/silent-callback',
|
110
|
+
component: SilentCallbackPage
|
111
|
+
},
|
112
|
+
// ... other routes
|
113
|
+
]
|
114
|
+
|
115
|
+
export default createRouter({
|
116
|
+
history: createWebHistory(),
|
117
|
+
routes
|
118
|
+
})
|
119
|
+
```
|
120
|
+
|
121
|
+
### 4. Setup Silent Callback (for Token Renewal)
|
122
|
+
|
123
|
+
```vue
|
124
|
+
<!-- SilentCallbackPage.vue -->
|
125
|
+
<script setup>
|
126
|
+
import { SilentCallback } from 'vuethenticate'
|
127
|
+
|
128
|
+
function onError(error) {
|
129
|
+
console.error('Silent renewal failed:', error)
|
130
|
+
}
|
131
|
+
</script>
|
132
|
+
|
133
|
+
<template>
|
134
|
+
<SilentCallback :onError="onError" />
|
135
|
+
</template>
|
136
|
+
```
|
137
|
+
|
138
|
+
## URL State Support
|
139
|
+
|
140
|
+
You can pass state through the authentication flow with full TypeScript support:
|
141
|
+
|
142
|
+
```typescript
|
143
|
+
// Define your state type
|
144
|
+
interface MyAppState {
|
145
|
+
returnUrl: string;
|
146
|
+
theme: 'light' | 'dark';
|
147
|
+
userId?: string;
|
148
|
+
}
|
149
|
+
|
150
|
+
// Use with generic type parameter
|
151
|
+
const auth = useAuth<MyAppState>(config);
|
152
|
+
|
153
|
+
// Pass state during sign in
|
154
|
+
await auth.signIn({
|
155
|
+
returnUrl: '/dashboard',
|
156
|
+
theme: 'dark'
|
157
|
+
});
|
158
|
+
|
159
|
+
// Pass state during sign out
|
160
|
+
await auth.signOut({
|
161
|
+
returnUrl: '/goodbye',
|
162
|
+
theme: 'light'
|
163
|
+
});
|
164
|
+
```
|
165
|
+
|
166
|
+
### Receiving State in Callback
|
167
|
+
|
168
|
+
```vue
|
169
|
+
<script setup lang="ts">
|
170
|
+
import { AuthCallback } from 'vuethenticate';
|
171
|
+
|
172
|
+
interface MyAppState {
|
173
|
+
returnUrl: string;
|
174
|
+
theme: 'light' | 'dark';
|
175
|
+
}
|
176
|
+
|
177
|
+
const handleSuccess = (user: User, state?: MyAppState) => {
|
178
|
+
if (state?.returnUrl) {
|
179
|
+
router.push(state.returnUrl);
|
180
|
+
}
|
181
|
+
if (state?.theme) {
|
182
|
+
setTheme(state.theme);
|
183
|
+
}
|
184
|
+
};
|
185
|
+
</script>
|
186
|
+
|
187
|
+
<template>
|
188
|
+
<AuthCallback<MyAppState>
|
189
|
+
@success="handleSuccess"
|
190
|
+
/>
|
191
|
+
</template>
|
192
|
+
```
|
193
|
+
|
194
|
+
> **Important**: Make sure to call `useAuth()` in your main App component or a parent component before rendering any callback components. The callback components rely on the authentication being initialized first.
|
195
|
+
|
196
|
+
## API Reference
|
197
|
+
|
198
|
+
### `useAuth(config)`
|
199
|
+
|
200
|
+
The main composable for authentication state management.
|
201
|
+
|
202
|
+
#### Configuration
|
203
|
+
|
204
|
+
| Property | Type | Required | Default | Description |
|
205
|
+
|----------|------|----------|---------|-------------|
|
206
|
+
| `authority` | `string` | ✓ | - | OIDC provider URL |
|
207
|
+
| `clientId` | `string` | ✓ | - | Application client ID |
|
208
|
+
| `redirectUri` | `string` | | `${origin}/auth/callback` | Callback URL |
|
209
|
+
| `scope` | `string` | | `'openid profile'` | OIDC scopes |
|
210
|
+
| `responseType` | `string` | | `'code'` | OAuth response type |
|
211
|
+
| `storage` | `'localStorage' \| 'sessionStorage' \| 'memory'` | | `'localStorage'` | Storage type |
|
212
|
+
| `automaticSilentRenew` | `boolean` | | `true` | Enable automatic token refresh |
|
213
|
+
| `silentRedirectUri` | `string` | | `${origin}/auth/silent-callback` | Silent refresh callback URL |
|
214
|
+
| `postLogoutRedirectUri` | `string` | | `${origin}` | Post-logout redirect URL |
|
215
|
+
|
216
|
+
#### Event Callbacks
|
217
|
+
|
218
|
+
| Property | Type | Description |
|
219
|
+
|----------|------|-------------|
|
220
|
+
| `onError` | `(error: Error) => void` | Called when an error occurs |
|
221
|
+
| `onUserLoaded` | `(user: User) => void` | Called when user is loaded |
|
222
|
+
| `onUserUnloaded` | `() => void` | Called when user is unloaded |
|
223
|
+
| `onAccessTokenExpired` | `() => void` | Called when access token expires |
|
224
|
+
| `onAccessTokenExpiring` | `() => void` | Called before access token expires |
|
225
|
+
|
226
|
+
#### Returns
|
227
|
+
|
228
|
+
| Property | Type | Description |
|
229
|
+
|----------|------|-------------|
|
230
|
+
| `user` | `Ref<User \| null>` | Current user object |
|
231
|
+
| `isAuthenticated` | `Ref<boolean>` | Authentication status |
|
232
|
+
| `isLoading` | `Ref<boolean>` | Loading state |
|
233
|
+
| `error` | `Ref<Error \| null>` | Current error |
|
234
|
+
| `accessToken` | `Ref<string \| null>` | Current access token |
|
235
|
+
| `isExpired` | `Ref<boolean>` | Token expiration status |
|
236
|
+
| `signIn` | `(state?: TState) => Promise<void>` | Initiate sign in with optional state |
|
237
|
+
| `signOut` | `(state?: TState) => Promise<void>` | Sign out user with optional state |
|
238
|
+
| `silentRenew` | `() => Promise<void>` | Manually renew token |
|
239
|
+
| `clearError` | `() => void` | Clear current error |
|
240
|
+
|
241
|
+
### `<AuthCallback>`
|
242
|
+
|
243
|
+
Component for handling OAuth callback. **Note**: This component requires `useAuth()` to be called in a parent component first.
|
244
|
+
|
245
|
+
#### Props
|
246
|
+
|
247
|
+
| Property | Type | Required | Description |
|
248
|
+
|----------|------|----------|-------------|
|
249
|
+
| `onSuccess` | `(user: User, state?: TState) => void` | | Success callback with typed state |
|
250
|
+
| `onError` | `(error: Error) => void` | | Error callback |
|
251
|
+
|
252
|
+
#### Slots
|
253
|
+
|
254
|
+
| Slot | Props | Description |
|
255
|
+
|------|-------|-------------|
|
256
|
+
| `default` | - | Loading content |
|
257
|
+
| `error` | `{ error: Error }` | Error content |
|
258
|
+
|
259
|
+
#### Events
|
260
|
+
|
261
|
+
| Event | Payload | Description |
|
262
|
+
|-------|---------|-------------|
|
263
|
+
| `success` | `User, state?: TState` | Emitted on successful authentication with typed state |
|
264
|
+
| `error` | `Error` | Emitted on authentication error |
|
265
|
+
|
266
|
+
### `<SilentCallback>`
|
267
|
+
|
268
|
+
Component for handling silent token renewal callbacks. This component should be mounted on a separate route (typically `/auth/silent-callback`) and is used internally by the library for automatic token refresh. **Note**: This component requires `useAuth()` to be called in a parent component first.
|
269
|
+
|
270
|
+
#### Props
|
271
|
+
|
272
|
+
| Property | Type | Required | Description |
|
273
|
+
|----------|------|----------|-------------|
|
274
|
+
| `onError` | `(error: Error) => void` | | Error callback for silent renewal failures |
|
275
|
+
|
276
|
+
#### Usage
|
277
|
+
|
278
|
+
```vue
|
279
|
+
<template>
|
280
|
+
<SilentCallback :onError="handleSilentError" />
|
281
|
+
</template>
|
282
|
+
|
283
|
+
<script setup>
|
284
|
+
import { SilentCallback } from 'vuethenticate'
|
285
|
+
|
286
|
+
function handleSilentError(error) {
|
287
|
+
console.error('Silent renewal failed:', error)
|
288
|
+
}
|
289
|
+
</script>
|
290
|
+
```
|
291
|
+
|
292
|
+
> **Note**: This component is primarily used in an iframe or popup for silent token renewal. It should be placed on a minimal page with no other content.
|
293
|
+
|
294
|
+
## License
|
295
|
+
|
296
|
+
MIT
|