@drmhse/authos-vue 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 +335 -0
- package/package.json +1 -4
package/README.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# @drmhse/authos-vue
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@drmhse/authos-vue)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Vue 3 adapter for [AuthOS](https://authos.dev) - the multi-tenant authentication platform. Provides Vue composables, components, and Nuxt module.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @drmhse/authos-vue
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Peer dependencies:
|
|
15
|
+
```bash
|
|
16
|
+
npm install vue
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
### Vue App
|
|
22
|
+
|
|
23
|
+
Install the plugin and use the composables/components:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
// main.ts
|
|
27
|
+
import { createApp } from 'vue';
|
|
28
|
+
import { createAuthOS } from '@drmhse/authos-vue';
|
|
29
|
+
import App from './App.vue';
|
|
30
|
+
|
|
31
|
+
const app = createApp(App);
|
|
32
|
+
|
|
33
|
+
app.use(createAuthOS({
|
|
34
|
+
baseUrl: 'https://sso.example.com'
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
app.mount('#app');
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Nuxt App
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// nuxt.config.ts
|
|
44
|
+
export default defineNuxtConfig({
|
|
45
|
+
modules: ['@drmhse/authos-vue/nuxt']
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Components
|
|
50
|
+
|
|
51
|
+
### SignIn
|
|
52
|
+
|
|
53
|
+
Pre-built sign-in form with email/password and OAuth provider buttons.
|
|
54
|
+
|
|
55
|
+
```vue
|
|
56
|
+
<script setup lang="ts">
|
|
57
|
+
import { SignIn } from '@drmhse/authos-vue';
|
|
58
|
+
|
|
59
|
+
function handleSuccess() {
|
|
60
|
+
console.log('Logged in!');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function handleError(err: Error) {
|
|
64
|
+
console.error(err);
|
|
65
|
+
}
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<template>
|
|
69
|
+
<SignIn @success="handleSuccess" @error="handleError" />
|
|
70
|
+
</template>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Events:**
|
|
74
|
+
| Event | Payload | Description |
|
|
75
|
+
|-------|---------|-------------|
|
|
76
|
+
| `@success` | - | Fired after successful login |
|
|
77
|
+
| `@error` | `Error` | Fired on login error |
|
|
78
|
+
|
|
79
|
+
### SignUp
|
|
80
|
+
|
|
81
|
+
Registration form for new users.
|
|
82
|
+
|
|
83
|
+
```vue
|
|
84
|
+
<script setup lang="ts">
|
|
85
|
+
import { SignUp } from '@drmhse/authos-vue';
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<template>
|
|
89
|
+
<SignUp />
|
|
90
|
+
</template>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Events:** Same as `SignIn`
|
|
94
|
+
|
|
95
|
+
### UserButton
|
|
96
|
+
|
|
97
|
+
User menu button that shows avatar/name and dropdown with profile/signout.
|
|
98
|
+
|
|
99
|
+
```vue
|
|
100
|
+
<script setup lang="ts">
|
|
101
|
+
import { UserButton } from '@drmhse/authos-vue';
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<template>
|
|
105
|
+
<header>
|
|
106
|
+
<UserButton />
|
|
107
|
+
</header>
|
|
108
|
+
</template>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### OrganizationSwitcher
|
|
112
|
+
|
|
113
|
+
Dropdown to switch between organizations (for multi-tenant users).
|
|
114
|
+
|
|
115
|
+
```vue
|
|
116
|
+
<script setup lang="ts">
|
|
117
|
+
import { OrganizationSwitcher } from '@drmhse/authos-vue';
|
|
118
|
+
</script>
|
|
119
|
+
|
|
120
|
+
<template>
|
|
121
|
+
<aside>
|
|
122
|
+
<OrganizationSwitcher />
|
|
123
|
+
</aside>
|
|
124
|
+
</template>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Protect
|
|
128
|
+
|
|
129
|
+
Conditional rendering based on user permissions.
|
|
130
|
+
|
|
131
|
+
```vue
|
|
132
|
+
<script setup lang="ts">
|
|
133
|
+
import { Protect } from '@drmhse/authos-vue';
|
|
134
|
+
</script>
|
|
135
|
+
|
|
136
|
+
<template>
|
|
137
|
+
<Protect permission="admin:access">
|
|
138
|
+
<template #default>
|
|
139
|
+
<AdminDashboard />
|
|
140
|
+
</template>
|
|
141
|
+
<template #fallback>
|
|
142
|
+
<p>Access denied. Admins only.</p>
|
|
143
|
+
</template>
|
|
144
|
+
</Protect>
|
|
145
|
+
</template>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Props:**
|
|
149
|
+
| Prop | Type | Description |
|
|
150
|
+
|------|------|-------------|
|
|
151
|
+
| `permission` | `string` | Required permission to access content |
|
|
152
|
+
| `fallback` | `slot` | Shown when user lacks permission |
|
|
153
|
+
| `default` | `slot` | Protected content |
|
|
154
|
+
|
|
155
|
+
## Composables
|
|
156
|
+
|
|
157
|
+
### useAuthOS
|
|
158
|
+
|
|
159
|
+
Access the AuthOS client directly.
|
|
160
|
+
|
|
161
|
+
```vue
|
|
162
|
+
<script setup lang="ts">
|
|
163
|
+
import { useAuthOS } from '@drmhse/authos-vue';
|
|
164
|
+
|
|
165
|
+
const { client, isAuthenticated, isLoading } = useAuthOS();
|
|
166
|
+
|
|
167
|
+
async function handleLogout() {
|
|
168
|
+
await client.auth.logout();
|
|
169
|
+
}
|
|
170
|
+
</script>
|
|
171
|
+
|
|
172
|
+
<template>
|
|
173
|
+
<div v-if="isLoading">Loading...</div>
|
|
174
|
+
<div v-else-if="!isAuthenticated">Please log in</div>
|
|
175
|
+
<div v-else>
|
|
176
|
+
<button @click="handleLogout">Logout</button>
|
|
177
|
+
</div>
|
|
178
|
+
</template>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Returns:**
|
|
182
|
+
| Property | Type | Description |
|
|
183
|
+
|----------|------|-------------|
|
|
184
|
+
| `client` | `SsoClient` | The AuthOS SDK client |
|
|
185
|
+
| `isLoading` | `Ref<boolean>` | True while checking auth state |
|
|
186
|
+
| `isAuthenticated` | `Ref<boolean>` | True if user is logged in |
|
|
187
|
+
|
|
188
|
+
### useUser
|
|
189
|
+
|
|
190
|
+
Get the current user's profile.
|
|
191
|
+
|
|
192
|
+
```vue
|
|
193
|
+
<script setup lang="ts">
|
|
194
|
+
import { useUser } from '@drmhse/authos-vue';
|
|
195
|
+
|
|
196
|
+
const { user, isLoading } = useUser();
|
|
197
|
+
</script>
|
|
198
|
+
|
|
199
|
+
<template>
|
|
200
|
+
<div v-if="isLoading">Loading...</div>
|
|
201
|
+
<div v-else>Welcome, {{ user?.email }}</div>
|
|
202
|
+
</template>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Returns:**
|
|
206
|
+
| Property | Type | Description |
|
|
207
|
+
|----------|------|-------------|
|
|
208
|
+
| `user` | `Ref<UserProfile | null>` | Current user profile |
|
|
209
|
+
| `isLoading` | `Ref<boolean>` | True while checking auth state |
|
|
210
|
+
|
|
211
|
+
### useOrganization
|
|
212
|
+
|
|
213
|
+
Get the current organization and list of organizations.
|
|
214
|
+
|
|
215
|
+
```vue
|
|
216
|
+
<script setup lang="ts">
|
|
217
|
+
import { useOrganization } from '@drmhse/authos-vue';
|
|
218
|
+
|
|
219
|
+
const { currentOrganization, organizations, switchOrganization } = useOrganization();
|
|
220
|
+
</script>
|
|
221
|
+
|
|
222
|
+
<template>
|
|
223
|
+
<div>
|
|
224
|
+
<h3>{{ currentOrganization?.name }}</h3>
|
|
225
|
+
<ul>
|
|
226
|
+
<li v-for="org in organizations" :key="org.id">
|
|
227
|
+
{{ org.name }}
|
|
228
|
+
</li>
|
|
229
|
+
</ul>
|
|
230
|
+
</div>
|
|
231
|
+
</template>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Returns:**
|
|
235
|
+
| Property | Type | Description |
|
|
236
|
+
|----------|------|-------------|
|
|
237
|
+
| `currentOrganization` | `Ref<Organization | null>` | Current organization |
|
|
238
|
+
| `organizations` | `Ref<Organization[]>` | All user's organizations |
|
|
239
|
+
| `switchOrganization` | `(slug: string) => Promise<void>` | Switch to a different org |
|
|
240
|
+
| `isSwitching` | `Ref<boolean>` | True while switching |
|
|
241
|
+
|
|
242
|
+
## Nuxt Module
|
|
243
|
+
|
|
244
|
+
When using the Nuxt module, the plugin is auto-installed and provides additional server utilities:
|
|
245
|
+
|
|
246
|
+
```vue
|
|
247
|
+
<!-- app.vue -->
|
|
248
|
+
<script setup lang="ts">
|
|
249
|
+
// Plugin is auto-installed, composables work automatically
|
|
250
|
+
import { useUser } from '@drmhse/authos-vue';
|
|
251
|
+
|
|
252
|
+
const { user } = useUser();
|
|
253
|
+
</script>
|
|
254
|
+
|
|
255
|
+
<template>
|
|
256
|
+
<div v-if="user">
|
|
257
|
+
Welcome, {{ user.email }}
|
|
258
|
+
</div>
|
|
259
|
+
</template>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Nuxt Auth Middleware
|
|
263
|
+
|
|
264
|
+
Protect pages with the auth middleware:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
// middleware/auth.ts
|
|
268
|
+
import { authMiddleware } from '@drmhse/authos-vue/nuxt';
|
|
269
|
+
|
|
270
|
+
export default authMiddleware({
|
|
271
|
+
redirectTo: '/login'
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Then use in your pages:
|
|
276
|
+
|
|
277
|
+
```vue
|
|
278
|
+
<script setup>
|
|
279
|
+
definePageMeta({
|
|
280
|
+
middleware: ['auth']
|
|
281
|
+
});
|
|
282
|
+
</script>
|
|
283
|
+
|
|
284
|
+
<template>
|
|
285
|
+
<div>Protected page</div>
|
|
286
|
+
</template>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Server-Side Usage
|
|
290
|
+
|
|
291
|
+
```ts
|
|
292
|
+
// server/api/user.get.ts
|
|
293
|
+
import { currentUser } from '@drmhse/authos-vue/nuxt';
|
|
294
|
+
|
|
295
|
+
export default defineEventHandler(async (event) => {
|
|
296
|
+
const user = await currentUser(event);
|
|
297
|
+
|
|
298
|
+
if (!user) {
|
|
299
|
+
throw createError({
|
|
300
|
+
statusCode: 401,
|
|
301
|
+
message: 'Unauthorized'
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return user;
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## SsoClient API
|
|
310
|
+
|
|
311
|
+
The underlying client from `@drmhse/sso-sdk`. See [SDK docs](https://www.npmjs.com/package/@drmhse/sso-sdk) for full API.
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
const { client } = useAuthOS();
|
|
315
|
+
|
|
316
|
+
// Authentication
|
|
317
|
+
await client.auth.login({ email, password });
|
|
318
|
+
await client.auth.logout();
|
|
319
|
+
await client.auth.register({ email, password, org_slug });
|
|
320
|
+
|
|
321
|
+
// User
|
|
322
|
+
await client.user.getProfile();
|
|
323
|
+
await client.user.updateProfile({ name });
|
|
324
|
+
await client.user.changePassword({ old, new });
|
|
325
|
+
|
|
326
|
+
// Organizations
|
|
327
|
+
await client.organizations.list();
|
|
328
|
+
await client.organizations.get(slug);
|
|
329
|
+
|
|
330
|
+
// And more...
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## License
|
|
334
|
+
|
|
335
|
+
MIT © DRM HSE
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drmhse/authos-vue",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Vue and Nuxt adapter for AuthOS authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
"dev": "tsup --watch",
|
|
36
36
|
"typecheck": "vue-tsc --noEmit",
|
|
37
37
|
"lint": "eslint src --ext .ts,.vue",
|
|
38
|
-
"test:ct": "playwright test -c playwright-ct.config.ts --reporter=list",
|
|
39
38
|
"prepublishOnly": "npm run build"
|
|
40
39
|
},
|
|
41
40
|
"keywords": [
|
|
@@ -53,8 +52,6 @@
|
|
|
53
52
|
"vue": ">=3.4.0"
|
|
54
53
|
},
|
|
55
54
|
"devDependencies": {
|
|
56
|
-
"@playwright/experimental-ct-vue": "^1.48.0",
|
|
57
|
-
"@playwright/test": "^1.48.0",
|
|
58
55
|
"@types/node": "^25.0.3",
|
|
59
56
|
"nuxt": "^3.14.0",
|
|
60
57
|
"tsup": "^8.3.5",
|