@meistrari/auth-nuxt 0.1.0 → 1.0.0-beta.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 +272 -124
- package/dist/core.d.mts +1 -0
- package/dist/core.mjs +1 -0
- package/dist/module.d.mts +1 -3
- package/dist/module.json +3 -3
- package/dist/module.mjs +20 -26
- package/dist/runtime/composables/api-key.d.ts +13 -0
- package/dist/runtime/composables/api-key.js +29 -0
- package/dist/runtime/composables/organization.d.ts +28 -0
- package/dist/runtime/composables/organization.js +164 -0
- package/dist/runtime/composables/session.d.ts +18 -0
- package/dist/runtime/composables/session.js +88 -0
- package/dist/runtime/composables/state.d.ts +22 -0
- package/dist/runtime/composables/state.js +17 -0
- package/dist/runtime/plugin.d.ts +1 -14
- package/dist/runtime/plugin.js +69 -84
- package/dist/runtime/server/middleware/auth.js +11 -16
- package/dist/runtime/server/tsconfig.json +4 -1
- package/dist/runtime/server/types/h3.d.ts +5 -5
- package/dist/runtime/shared.d.ts +1 -0
- package/dist/runtime/shared.js +19 -0
- package/package.json +51 -48
- package/dist/runtime/composable.d.ts +0 -5
- package/dist/runtime/composable.js +0 -29
- package/dist/runtime/server/api/sign-out.d.ts +0 -2
- package/dist/runtime/server/api/sign-out.js +0 -16
- package/dist/runtime/server/middleware/set-cookies.d.ts +0 -2
- package/dist/runtime/server/middleware/set-cookies.js +0 -42
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# @meistrari/auth-
|
|
1
|
+
# @meistrari/auth-nuxt
|
|
2
2
|
|
|
3
|
-
A Nuxt module that provides authentication
|
|
3
|
+
A Nuxt module that provides comprehensive authentication, organization management, and API key capabilities.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @meistrari/auth-
|
|
8
|
+
npm install @meistrari/auth-nuxt
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Setup
|
|
@@ -14,13 +14,11 @@ Add the module to your `nuxt.config.ts`:
|
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
export default defineNuxtConfig({
|
|
17
|
-
modules: ['@meistrari/auth-
|
|
18
|
-
|
|
17
|
+
modules: ['@meistrari/auth-nuxt'],
|
|
18
|
+
telaAuth: {
|
|
19
19
|
apiUrl: 'https://your-auth-api.com',
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
skipServerMiddleware: false, // Skip automatic server middleware
|
|
23
|
-
isDevelopment: false, // Development mode settings
|
|
20
|
+
jwtCookieName: 'tela-jwt', // Optional: custom JWT cookie name
|
|
21
|
+
skipServerMiddleware: false, // Optional: skip automatic server middleware
|
|
24
22
|
}
|
|
25
23
|
})
|
|
26
24
|
```
|
|
@@ -30,20 +28,20 @@ export default defineNuxtConfig({
|
|
|
30
28
|
| Option | Type | Default | Description |
|
|
31
29
|
|--------|------|---------|-------------|
|
|
32
30
|
| `apiUrl` | `string` | **Required** | Base URL of your authentication API |
|
|
33
|
-
| `
|
|
34
|
-
| `jwtCookieName` | `string` | `'auth-jwt'` | Name of the JWT cookie |
|
|
31
|
+
| `jwtCookieName` | `string` | `'tela-jwt'` | Name of the JWT cookie |
|
|
35
32
|
| `skipServerMiddleware` | `boolean` | `false` | Skip automatic server-side auth context setup |
|
|
36
|
-
| `isDevelopment` | `boolean` | `false` | Enable development-specific features |
|
|
37
33
|
|
|
38
|
-
##
|
|
34
|
+
## Composables
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
The SDK provides three main composables for different aspects of authentication and organization management:
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
### useTelaSession
|
|
39
|
+
|
|
40
|
+
Manages user sessions, authentication, and sign-in/sign-out operations.
|
|
43
41
|
|
|
44
42
|
```vue
|
|
45
43
|
<script setup>
|
|
46
|
-
const { user, session, signOut } =
|
|
44
|
+
const { user, session, signOut, getToken } = useTelaSession()
|
|
47
45
|
|
|
48
46
|
// Access current user
|
|
49
47
|
console.log(user.value) // User object or null
|
|
@@ -51,9 +49,11 @@ console.log(user.value) // User object or null
|
|
|
51
49
|
// Access current session
|
|
52
50
|
console.log(session.value) // Session object or null
|
|
53
51
|
|
|
52
|
+
// Get a valid JWT token
|
|
53
|
+
const token = await getToken()
|
|
54
|
+
|
|
54
55
|
// Sign out
|
|
55
56
|
await signOut(() => {
|
|
56
|
-
// Optional callback after sign out
|
|
57
57
|
console.log('User signed out')
|
|
58
58
|
})
|
|
59
59
|
</script>
|
|
@@ -69,36 +69,202 @@ await signOut(() => {
|
|
|
69
69
|
</template>
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
#### Available Methods
|
|
73
|
+
|
|
74
|
+
**Session Management:**
|
|
75
|
+
- `getSession()` - Retrieves the current user session
|
|
76
|
+
- `getToken()` - Retrieves a valid JWT token (refreshes if needed)
|
|
77
|
+
- `signOut(callback?)` - Signs out the user
|
|
78
|
+
|
|
79
|
+
**Authentication Methods:**
|
|
80
|
+
- `signInWithEmailAndPassword(options)` - Email/password authentication
|
|
81
|
+
- `signInWithSocialProvider(options)` - Social authentication (Google, Microsoft)
|
|
82
|
+
- `signInWithSaml(options)` - SAML-based SSO authentication
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
**Password Management:**
|
|
85
|
+
- `requestPasswordReset(email, callbackURL)` - Initiates password reset
|
|
86
|
+
- `resetPassword(token, password)` - Completes password reset
|
|
75
87
|
|
|
88
|
+
#### Sign-In Examples
|
|
89
|
+
|
|
90
|
+
**Email and Password:**
|
|
76
91
|
```typescript
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
await signInWithEmailAndPassword({
|
|
93
|
+
email: 'user@example.com',
|
|
94
|
+
password: 'secure-password',
|
|
95
|
+
callbackURL: '/dashboard',
|
|
96
|
+
errorCallbackURL: '/login?error=true'
|
|
97
|
+
})
|
|
98
|
+
```
|
|
79
99
|
|
|
80
|
-
|
|
81
|
-
|
|
100
|
+
**Social Authentication:**
|
|
101
|
+
```typescript
|
|
102
|
+
await signInWithSocialProvider({
|
|
103
|
+
provider: 'google', // or 'microsoft'
|
|
104
|
+
callbackURL: '/dashboard',
|
|
105
|
+
errorCallbackURL: '/login?error=true'
|
|
106
|
+
})
|
|
107
|
+
```
|
|
82
108
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
109
|
+
**SAML SSO:**
|
|
110
|
+
```typescript
|
|
111
|
+
await signInWithSaml({
|
|
112
|
+
email: 'user@example.com',
|
|
113
|
+
callbackURL: '/dashboard',
|
|
114
|
+
errorCallbackURL: '/login?error=true'
|
|
87
115
|
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### useTelaOrganization
|
|
119
|
+
|
|
120
|
+
Manages organizations, members, invitations, and teams.
|
|
121
|
+
|
|
122
|
+
```vue
|
|
123
|
+
<script setup>
|
|
124
|
+
const {
|
|
125
|
+
activeOrganization,
|
|
126
|
+
activeMember,
|
|
127
|
+
getActiveOrganization,
|
|
128
|
+
setActiveOrganization,
|
|
129
|
+
inviteUserToOrganization
|
|
130
|
+
} = useTelaOrganization()
|
|
131
|
+
|
|
132
|
+
// Get the active organization
|
|
133
|
+
await getActiveOrganization()
|
|
134
|
+
|
|
135
|
+
// Switch organizations
|
|
136
|
+
await setActiveOrganization('org-id')
|
|
137
|
+
|
|
138
|
+
// Invite a user
|
|
139
|
+
await inviteUserToOrganization({
|
|
140
|
+
userEmail: 'user@example.com',
|
|
141
|
+
role: 'member'
|
|
142
|
+
})
|
|
143
|
+
</script>
|
|
88
144
|
|
|
89
|
-
|
|
90
|
-
|
|
145
|
+
<template>
|
|
146
|
+
<div v-if="activeOrganization">
|
|
147
|
+
<h2>{{ activeOrganization.name }}</h2>
|
|
148
|
+
<p>{{ activeOrganization.members.length }} members</p>
|
|
149
|
+
</div>
|
|
150
|
+
</template>
|
|
91
151
|
```
|
|
92
152
|
|
|
93
|
-
|
|
153
|
+
#### Available Methods
|
|
154
|
+
|
|
155
|
+
**Organization Management:**
|
|
156
|
+
- `getActiveOrganization()` - Gets the current active organization with members, invitations, and teams
|
|
157
|
+
- `listOrganizations()` - Lists all organizations for the user
|
|
158
|
+
- `setActiveOrganization(id)` - Sets the active organization
|
|
159
|
+
- `updateOrganization(payload)` - Updates organization details (name, logo, settings)
|
|
160
|
+
|
|
161
|
+
**Member Management:**
|
|
162
|
+
- `listMembers(options?)` - Lists organization members with pagination
|
|
163
|
+
- `getActiveMember()` - Gets the current user's member record
|
|
164
|
+
- `inviteUserToOrganization(options)` - Invites a user to the organization
|
|
165
|
+
- `removeUserFromOrganization(options)` - Removes a user from the organization
|
|
166
|
+
- `updateMemberRole(options)` - Updates a member's role
|
|
167
|
+
- `acceptInvitation(id)` - Accepts an organization invitation
|
|
168
|
+
- `cancelInvitation(id)` - Cancels a pending invitation
|
|
169
|
+
|
|
170
|
+
**Team Management:**
|
|
171
|
+
- `createTeam(payload)` - Creates a new team
|
|
172
|
+
- `updateTeam(id, payload)` - Updates team details
|
|
173
|
+
- `deleteTeam(id)` - Deletes a team
|
|
174
|
+
- `listTeams()` - Lists all teams
|
|
175
|
+
- `listTeamMembers(id)` - Lists members of a specific team
|
|
176
|
+
- `addTeamMember(teamId, userId)` - Adds a user to a team
|
|
177
|
+
- `removeTeamMember(teamId, userId)` - Removes a user from a team
|
|
178
|
+
|
|
179
|
+
#### Organization Examples
|
|
180
|
+
|
|
181
|
+
**Update Organization:**
|
|
182
|
+
```typescript
|
|
183
|
+
await updateOrganization({
|
|
184
|
+
name: 'New Organization Name',
|
|
185
|
+
logo: 'https://example.com/logo.png',
|
|
186
|
+
settings: { /* custom settings */ }
|
|
187
|
+
})
|
|
188
|
+
```
|
|
94
189
|
|
|
95
|
-
|
|
190
|
+
**Invite Member:**
|
|
191
|
+
```typescript
|
|
192
|
+
await inviteUserToOrganization({
|
|
193
|
+
userEmail: 'user@example.com',
|
|
194
|
+
role: 'admin', // or 'member', 'reviewer'
|
|
195
|
+
teamId: 'team-id', // optional
|
|
196
|
+
resend: false // optional: resend if invitation exists
|
|
197
|
+
})
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Create and Manage Teams:**
|
|
201
|
+
```typescript
|
|
202
|
+
// Create team
|
|
203
|
+
const team = await createTeam({
|
|
204
|
+
name: 'Development Team'
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
// Add member to team
|
|
208
|
+
await addTeamMember(team.id, 'user-id')
|
|
209
|
+
|
|
210
|
+
// List team members
|
|
211
|
+
const members = await listTeamMembers(team.id)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### useTelaApiKey
|
|
215
|
+
|
|
216
|
+
Manages API keys for programmatic access.
|
|
217
|
+
|
|
218
|
+
```vue
|
|
219
|
+
<script setup>
|
|
220
|
+
const {
|
|
221
|
+
listApiKeys,
|
|
222
|
+
createApiKey,
|
|
223
|
+
deleteApiKey
|
|
224
|
+
} = useTelaApiKey()
|
|
225
|
+
|
|
226
|
+
// List all API keys
|
|
227
|
+
const apiKeys = await listApiKeys()
|
|
228
|
+
|
|
229
|
+
// Create a new API key
|
|
230
|
+
const newKey = await createApiKey({
|
|
231
|
+
name: 'Production API Key',
|
|
232
|
+
expiresIn: '90d',
|
|
233
|
+
prefix: 'prod',
|
|
234
|
+
metadata: { environment: 'production' }
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
// Delete an API key
|
|
238
|
+
await deleteApiKey('key-id')
|
|
239
|
+
</script>
|
|
240
|
+
|
|
241
|
+
<template>
|
|
242
|
+
<div v-for="key in apiKeys" :key="key.id">
|
|
243
|
+
<span>{{ key.name }}</span>
|
|
244
|
+
<button @click="deleteApiKey(key.id)">Delete</button>
|
|
245
|
+
</div>
|
|
246
|
+
</template>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### Available Methods
|
|
250
|
+
|
|
251
|
+
- `listApiKeys()` - Lists all API keys for the current user
|
|
252
|
+
- `getApiKey(id)` - Retrieves a specific API key
|
|
253
|
+
- `createApiKey(payload)` - Creates a new API key
|
|
254
|
+
- `updateApiKey(payload)` - Updates an API key (name)
|
|
255
|
+
- `deleteApiKey(id)` - Deletes an API key
|
|
256
|
+
|
|
257
|
+
## Server-Side Usage
|
|
258
|
+
|
|
259
|
+
The SDK automatically sets up server-side authentication context for API routes.
|
|
260
|
+
|
|
261
|
+
### Using Authentication Context
|
|
96
262
|
|
|
97
263
|
```typescript
|
|
98
264
|
// server/api/protected.ts
|
|
99
265
|
export default defineEventHandler(async (event) => {
|
|
100
266
|
// Authentication context is automatically available
|
|
101
|
-
const { user,
|
|
267
|
+
const { user, workspace } = event.context.auth
|
|
102
268
|
|
|
103
269
|
if (!user) {
|
|
104
270
|
throw createError({
|
|
@@ -108,7 +274,7 @@ export default defineEventHandler(async (event) => {
|
|
|
108
274
|
}
|
|
109
275
|
|
|
110
276
|
return {
|
|
111
|
-
message: `Hello, ${user.
|
|
277
|
+
message: `Hello, ${user.email}!`,
|
|
112
278
|
userId: user.id
|
|
113
279
|
}
|
|
114
280
|
})
|
|
@@ -116,113 +282,82 @@ export default defineEventHandler(async (event) => {
|
|
|
116
282
|
|
|
117
283
|
### Custom Middleware
|
|
118
284
|
|
|
119
|
-
|
|
285
|
+
Create custom server middleware using the provided helper:
|
|
120
286
|
|
|
121
287
|
```typescript
|
|
122
288
|
// server/middleware/custom.ts
|
|
123
|
-
import { meistrariAuthMiddleware } from '@meistrari/auth-
|
|
289
|
+
import { meistrariAuthMiddleware } from '@meistrari/auth-nuxt/server/middleware/auth'
|
|
124
290
|
|
|
125
291
|
export default meistrariAuthMiddleware(async (event) => {
|
|
292
|
+
// event.context.auth contains user and workspace
|
|
293
|
+
const { user, workspace } = event.context.auth
|
|
294
|
+
|
|
126
295
|
// Your custom logic here
|
|
127
|
-
|
|
296
|
+
if (user) {
|
|
297
|
+
console.log(`Authenticated user: ${user.email}`)
|
|
298
|
+
}
|
|
128
299
|
})
|
|
129
300
|
```
|
|
130
301
|
|
|
131
|
-
### JWT Token Management
|
|
132
|
-
|
|
133
|
-
When `useJwt` is enabled, the SDK automatically:
|
|
134
|
-
|
|
135
|
-
- Manages JWT tokens in cookies
|
|
136
|
-
- Refreshes tokens before expiration (every 60 seconds)
|
|
137
|
-
- Validates token expiry client-side
|
|
138
|
-
- Provides `getToken()` method for accessing valid tokens
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
const { $auth } = useNuxtApp()
|
|
142
|
-
|
|
143
|
-
// Get a valid JWT token (refreshes if needed)
|
|
144
|
-
const token = await $auth.getToken()
|
|
145
|
-
```
|
|
146
|
-
|
|
147
302
|
## Types
|
|
148
303
|
|
|
149
|
-
The SDK exports comprehensive TypeScript types:
|
|
304
|
+
The SDK exports comprehensive TypeScript types from the core package:
|
|
150
305
|
|
|
151
306
|
```typescript
|
|
152
307
|
import type {
|
|
153
308
|
User,
|
|
154
309
|
Session,
|
|
155
310
|
Organization,
|
|
156
|
-
|
|
311
|
+
FullOrganization,
|
|
157
312
|
Member,
|
|
158
313
|
Invitation,
|
|
159
314
|
Team,
|
|
160
|
-
TeamMember
|
|
161
|
-
|
|
315
|
+
TeamMember,
|
|
316
|
+
ApiKey,
|
|
317
|
+
CreateApiKeyPayload,
|
|
318
|
+
UpdateApiKeyPayload,
|
|
319
|
+
CreateTeamPayload,
|
|
320
|
+
UpdateTeamPayload,
|
|
321
|
+
InviteUserToOrganizationOptions,
|
|
322
|
+
RemoveUserFromOrganizationOptions,
|
|
323
|
+
UpdateMemberRoleOptions,
|
|
324
|
+
UpdateOrganizationPayload
|
|
325
|
+
} from '@meistrari/auth-nuxt/core'
|
|
162
326
|
```
|
|
163
327
|
|
|
164
328
|
### Key Types
|
|
165
329
|
|
|
166
330
|
- **User**: User account information including email, name, and verification status
|
|
167
|
-
- **Session**: Active session data with expiration and
|
|
168
|
-
- **Organization**:
|
|
169
|
-
- **
|
|
331
|
+
- **Session**: Active session data with expiration and organization info
|
|
332
|
+
- **Organization**: Basic organization entity
|
|
333
|
+
- **FullOrganization**: Organization with members, invitations, and teams
|
|
170
334
|
- **Member**: Organization member with role and team assignments
|
|
171
335
|
- **Team**: Team entity within an organization
|
|
172
336
|
- **Invitation**: Pending organization invitations
|
|
337
|
+
- **ApiKey**: API key entity with metadata
|
|
173
338
|
|
|
174
|
-
##
|
|
175
|
-
|
|
176
|
-
The SDK includes full organization and team management capabilities:
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
const { $auth } = useNuxtApp()
|
|
180
|
-
|
|
181
|
-
// Create organization
|
|
182
|
-
await $auth.client.organization.create({
|
|
183
|
-
name: 'Acme Corp',
|
|
184
|
-
slug: 'acme-corp'
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
// Invite members
|
|
188
|
-
await $auth.client.organization.inviteMember({
|
|
189
|
-
email: 'user@example.com',
|
|
190
|
-
role: 'org:member',
|
|
191
|
-
organizationId: 'org-id'
|
|
192
|
-
})
|
|
339
|
+
## JWT Token Management
|
|
193
340
|
|
|
194
|
-
|
|
195
|
-
await $auth.client.organization.createTeam({
|
|
196
|
-
name: 'Development Team',
|
|
197
|
-
organizationId: 'org-id'
|
|
198
|
-
})
|
|
341
|
+
The SDK automatically manages JWT tokens:
|
|
199
342
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
})
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Role-based Access Control
|
|
208
|
-
|
|
209
|
-
The SDK implements role-based access control with three built-in roles:
|
|
343
|
+
- Stores JWT tokens in cookies (configurable name)
|
|
344
|
+
- Refreshes tokens before expiration (every 60 seconds)
|
|
345
|
+
- Validates tokens client-side and server-side
|
|
346
|
+
- Provides `getToken()` method for accessing valid tokens
|
|
210
347
|
|
|
211
|
-
|
|
212
|
-
- **org:reviewer**: Review-only access
|
|
213
|
-
- **org:member**: Basic member access
|
|
348
|
+
The handshake flow ensures secure authentication:
|
|
214
349
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
350
|
+
1. On initial visit without a token, redirects to auth API for handshake
|
|
351
|
+
2. Auth API validates the session and redirects back with a nonce
|
|
352
|
+
3. SDK exchanges the nonce for a JWT token
|
|
353
|
+
4. Token is stored in a cookie and used for subsequent requests
|
|
219
354
|
|
|
220
355
|
## Utilities
|
|
221
356
|
|
|
222
357
|
### Token Validation
|
|
223
358
|
|
|
224
359
|
```typescript
|
|
225
|
-
import { isTokenExpired, validateToken } from '@meistrari/auth-
|
|
360
|
+
import { isTokenExpired, validateToken, extractTokenPayload } from '@meistrari/auth-nuxt/core'
|
|
226
361
|
|
|
227
362
|
// Check if token is expired
|
|
228
363
|
if (isTokenExpired(jwtToken)) {
|
|
@@ -231,41 +366,54 @@ if (isTokenExpired(jwtToken)) {
|
|
|
231
366
|
|
|
232
367
|
// Validate token against JWKS endpoint
|
|
233
368
|
const isValid = await validateToken(jwtToken, 'https://your-api.com')
|
|
369
|
+
|
|
370
|
+
// Extract token payload (without validation)
|
|
371
|
+
const payload = extractTokenPayload(jwtToken)
|
|
372
|
+
console.log(payload.user, payload.workspace)
|
|
234
373
|
```
|
|
235
374
|
|
|
375
|
+
## Security Features
|
|
376
|
+
|
|
377
|
+
- **JWT Validation**: Cryptographic validation using JWKS
|
|
378
|
+
- **Secure Cookies**: HTTP-only, secure cookies in production
|
|
379
|
+
- **Token Refresh**: Automatic token rotation every 60 seconds
|
|
380
|
+
- **Session Management**: Secure session handling with handshake flow
|
|
381
|
+
- **Server-Side Validation**: Middleware validates tokens on every API request
|
|
382
|
+
|
|
236
383
|
## Error Handling
|
|
237
384
|
|
|
238
385
|
The SDK handles common authentication errors automatically:
|
|
239
386
|
|
|
240
|
-
- Expired tokens
|
|
241
|
-
- Invalid
|
|
242
|
-
- Network errors are gracefully
|
|
243
|
-
-
|
|
387
|
+
- Expired tokens trigger sign-out when refresh fails
|
|
388
|
+
- Invalid tokens result in `null` user/session values
|
|
389
|
+
- Network errors are handled gracefully
|
|
390
|
+
- API errors can be caught and handled in your code
|
|
244
391
|
|
|
245
392
|
```typescript
|
|
393
|
+
import { APIError } from '@meistrari/auth-nuxt/core'
|
|
394
|
+
|
|
246
395
|
try {
|
|
247
|
-
await
|
|
396
|
+
await signInWithEmailAndPassword({
|
|
397
|
+
email: 'user@example.com',
|
|
398
|
+
password: 'wrong-password',
|
|
399
|
+
callbackURL: '/dashboard'
|
|
400
|
+
})
|
|
248
401
|
} catch (error) {
|
|
249
|
-
|
|
402
|
+
if (error instanceof APIError) {
|
|
403
|
+
console.error('Authentication failed:', error.message, error.status)
|
|
404
|
+
}
|
|
250
405
|
}
|
|
251
406
|
```
|
|
252
407
|
|
|
253
|
-
## Development
|
|
254
|
-
|
|
255
|
-
Set `isDevelopment: true` in your config to enable:
|
|
256
|
-
|
|
257
|
-
- Additional debugging logs
|
|
258
|
-
- Development-specific cookie handling
|
|
259
|
-
- Relaxed security policies for local development
|
|
260
|
-
|
|
261
|
-
## Security Features
|
|
262
|
-
|
|
263
|
-
- **CSRF Protection**: Built into all API calls
|
|
264
|
-
- **JWT Validation**: Cryptographic validation using JWKS
|
|
265
|
-
- **Secure Cookies**: HTTP-only, secure cookies in production
|
|
266
|
-
- **Token Refresh**: Automatic token rotation
|
|
267
|
-
- **Session Management**: Secure session handling
|
|
268
|
-
|
|
269
408
|
## Migration
|
|
270
409
|
|
|
271
|
-
If upgrading from a previous version
|
|
410
|
+
If upgrading from a previous version:
|
|
411
|
+
|
|
412
|
+
1. Update package name to `@meistrari/auth-nuxt`
|
|
413
|
+
2. Change config key from `authSdk` to `telaAuth`
|
|
414
|
+
3. Replace `useMeistrariAuth()` with appropriate composable:
|
|
415
|
+
- `useTelaSession()` for authentication
|
|
416
|
+
- `useTelaOrganization()` for organization management
|
|
417
|
+
- `useTelaApiKey()` for API key management
|
|
418
|
+
4. Update cookie name if using custom value (default is now `tela-jwt`)
|
|
419
|
+
5. Remove `useJwt` and `isDevelopment` options (no longer needed)
|
package/dist/core.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@meistrari/auth-core';
|
package/dist/core.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@meistrari/auth-core';
|
package/dist/module.d.mts
CHANGED
|
@@ -3,12 +3,10 @@ import * as _nuxt_schema from '@nuxt/schema';
|
|
|
3
3
|
interface ModuleOptions {
|
|
4
4
|
/** Auth API base URL */
|
|
5
5
|
apiUrl: string;
|
|
6
|
-
/** Set JWT cookie and start token refresh cycle */
|
|
7
|
-
useJwt: boolean;
|
|
8
6
|
/** Cookie name for authentication token */
|
|
9
7
|
jwtCookieName: string;
|
|
8
|
+
/** Skip default server middleware */
|
|
10
9
|
skipServerMiddleware: boolean;
|
|
11
|
-
isDevelopment: boolean;
|
|
12
10
|
}
|
|
13
11
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
14
12
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,46 +1,40 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addServerHandler, addImports, addPlugin } from '@nuxt/kit';
|
|
2
2
|
|
|
3
|
-
const module = defineNuxtModule({
|
|
3
|
+
const module$1 = defineNuxtModule({
|
|
4
4
|
meta: {
|
|
5
|
-
name: "@meistrari/auth-
|
|
6
|
-
configKey: "
|
|
5
|
+
name: "@meistrari/auth-nuxt",
|
|
6
|
+
configKey: "telaAuth"
|
|
7
7
|
},
|
|
8
8
|
defaults: {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
jwtCookieName: "auth-jwt",
|
|
12
|
-
skipServerMiddleware: false,
|
|
13
|
-
isDevelopment: false
|
|
9
|
+
jwtCookieName: "tela-jwt",
|
|
10
|
+
skipServerMiddleware: false
|
|
14
11
|
},
|
|
15
12
|
setup(options, nuxt) {
|
|
16
|
-
if (!options.apiUrl) {
|
|
17
|
-
console.error("[@meistrari/auth-sdk] error: apiUrl is required in module config");
|
|
18
|
-
}
|
|
19
13
|
const resolver = createResolver(import.meta.url);
|
|
20
|
-
nuxt.options.runtimeConfig.public.
|
|
14
|
+
nuxt.options.runtimeConfig.public.telaAuth = options;
|
|
21
15
|
if (!options.skipServerMiddleware) {
|
|
22
16
|
addServerHandler({
|
|
23
17
|
route: "",
|
|
24
18
|
handler: resolver.resolve("./runtime/server/middleware/auth")
|
|
25
19
|
});
|
|
26
20
|
}
|
|
27
|
-
if (options.isDevelopment) {
|
|
28
|
-
addServerHandler({
|
|
29
|
-
route: "",
|
|
30
|
-
handler: resolver.resolve("./runtime/server/middleware/set-cookies")
|
|
31
|
-
});
|
|
32
|
-
addServerHandler({
|
|
33
|
-
route: "/api/meistrari-auth/sign-out",
|
|
34
|
-
handler: resolver.resolve("./runtime/server/api/sign-out")
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
21
|
addImports({
|
|
38
|
-
name: "
|
|
39
|
-
as: "
|
|
40
|
-
from: resolver.resolve("runtime/
|
|
22
|
+
name: "useTelaSession",
|
|
23
|
+
as: "useTelaSession",
|
|
24
|
+
from: resolver.resolve("runtime/composables/session")
|
|
25
|
+
});
|
|
26
|
+
addImports({
|
|
27
|
+
name: "useTelaOrganization",
|
|
28
|
+
as: "useTelaOrganization",
|
|
29
|
+
from: resolver.resolve("runtime/composables/organization")
|
|
30
|
+
});
|
|
31
|
+
addImports({
|
|
32
|
+
name: "useTelaApiKey",
|
|
33
|
+
as: "useTelaApiKey",
|
|
34
|
+
from: resolver.resolve("runtime/composables/api-key")
|
|
41
35
|
});
|
|
42
36
|
addPlugin(resolver.resolve("./runtime/plugin"));
|
|
43
37
|
}
|
|
44
38
|
});
|
|
45
39
|
|
|
46
|
-
export { module as default };
|
|
40
|
+
export { module$1 as default };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CreateApiKeyPayload, UpdateApiKeyPayload } from '@meistrari/auth-core';
|
|
2
|
+
/**
|
|
3
|
+
* Composable for managing API keys.
|
|
4
|
+
*
|
|
5
|
+
* @returns An object containing API key management functions.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useTelaApiKey(): {
|
|
8
|
+
createApiKey: (payload: CreateApiKeyPayload) => Promise<any>;
|
|
9
|
+
updateApiKey: (payload: UpdateApiKeyPayload) => Promise<any>;
|
|
10
|
+
deleteApiKey: (id: string) => Promise<any>;
|
|
11
|
+
listApiKeys: () => Promise<any>;
|
|
12
|
+
getApiKey: (id: string) => Promise<any>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useCookie, useRuntimeConfig } from "#app";
|
|
2
|
+
import { createNuxtAuthClient } from "../shared.js";
|
|
3
|
+
export function useTelaApiKey() {
|
|
4
|
+
const { jwtCookieName, apiUrl } = useRuntimeConfig().public.telaAuth;
|
|
5
|
+
const tokenCookie = useCookie(jwtCookieName);
|
|
6
|
+
const authClient = createNuxtAuthClient(apiUrl, () => tokenCookie.value ?? null);
|
|
7
|
+
async function createApiKey(payload) {
|
|
8
|
+
return authClient.apiKey.createApiKey(payload);
|
|
9
|
+
}
|
|
10
|
+
async function updateApiKey(payload) {
|
|
11
|
+
return authClient.apiKey.updateApiKey(payload);
|
|
12
|
+
}
|
|
13
|
+
async function deleteApiKey(id) {
|
|
14
|
+
return authClient.apiKey.deleteApiKey(id);
|
|
15
|
+
}
|
|
16
|
+
async function listApiKeys() {
|
|
17
|
+
return authClient.apiKey.listApiKeys();
|
|
18
|
+
}
|
|
19
|
+
async function getApiKey(id) {
|
|
20
|
+
return authClient.apiKey.getApiKey(id);
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
createApiKey,
|
|
24
|
+
updateApiKey,
|
|
25
|
+
deleteApiKey,
|
|
26
|
+
listApiKeys,
|
|
27
|
+
getApiKey
|
|
28
|
+
};
|
|
29
|
+
}
|