@openape/nuxt-auth-sp 0.1.0 → 0.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @openape/nuxt-auth-sp
2
2
 
3
- OpenAPE Service Provider Nuxt module adds OIDC login via DNS-based IdP discovery.
3
+ Nuxt module that adds **DDISA-based login** to your application. Users enter their email, the module discovers their Identity Provider via DNS, and handles the full authorization flow — no pre-configured IdP list needed.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,6 +8,115 @@ OpenAPE Service Provider Nuxt module — adds OIDC login via DNS-based IdP disco
8
8
  npm install @openape/nuxt-auth-sp
9
9
  ```
10
10
 
11
+ ```typescript
12
+ // nuxt.config.ts
13
+ export default defineNuxtConfig({
14
+ modules: ['@openape/nuxt-auth-sp'],
15
+
16
+ openapeSp: {
17
+ spId: 'sp.example.com',
18
+ spName: 'My Service',
19
+ sessionSecret: 'your-secret-min-32-chars...',
20
+ },
21
+ })
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ | Option | Type | Default | Description |
27
+ |--------|------|---------|-------------|
28
+ | `spId` | `string` | — | **Required.** Service Provider identifier (typically your domain) |
29
+ | `spName` | `string` | `'OpenApe Service Provider'` | Display name shown during authorization |
30
+ | `sessionSecret` | `string` | `'change-me-sp-secret-...'` | Session encryption key |
31
+ | `openapeUrl` | `string` | — | Override IdP URL (bypasses DNS discovery) |
32
+
33
+ ## Routes
34
+
35
+ | Method | Path | Description |
36
+ |--------|------|-------------|
37
+ | `POST` | `/api/login` | Start login — `{ email }` → `{ redirectUrl }` |
38
+ | `GET` | `/api/callback` | Handle callback from IdP |
39
+ | `POST` | `/api/logout` | End session |
40
+ | `GET` | `/api/me` | Get current user (`DDISAAssertionClaims`) |
41
+ | `GET` | `/.well-known/sp-manifest.json` | SP manifest for IdP discovery |
42
+
43
+ ## Composables
44
+
45
+ ### `useOpenApeAuth()`
46
+
47
+ ```typescript
48
+ const { user, loading, fetchUser, login, logout } = useOpenApeAuth()
49
+
50
+ // user: Ref<DDISAAssertionClaims | null>
51
+ // DDISAAssertionClaims: { sub, iss, aud, act, iat, exp, nonce, ... }
52
+
53
+ await login('user@example.com') // Redirects to user's IdP
54
+ await logout() // Clears session, navigates to /
55
+ ```
56
+
57
+ ## Middleware
58
+
59
+ The module provides an `openape-auth` middleware that protects pages from unauthenticated access.
60
+
61
+ ```typescript
62
+ // pages/dashboard.vue
63
+ definePageMeta({
64
+ middleware: 'openape-auth',
65
+ })
66
+ ```
67
+
68
+ Unauthenticated users are redirected to the login page.
69
+
70
+ ## DNS Discovery
71
+
72
+ When a user logs in with `user@example.com`, the module:
73
+
74
+ 1. Extracts the domain (`example.com`)
75
+ 2. Looks up the `_ddisa.example.com` TXT record
76
+ 3. Parses the DDISA record to find the IdP URL
77
+ 4. Redirects the user to the IdP's authorization endpoint with PKCE
78
+ 5. Handles the callback and validates the signed assertion
79
+
80
+ This means any domain with a DDISA DNS record can authenticate — no pre-registration needed.
81
+
82
+ For details on DNS resolution, see [`@openape/core`](../core).
83
+
84
+ ## Quick Start
85
+
86
+ ```typescript
87
+ // nuxt.config.ts
88
+ export default defineNuxtConfig({
89
+ modules: ['@openape/nuxt-auth-sp'],
90
+
91
+ openapeSp: {
92
+ spId: 'localhost:3001',
93
+ spName: 'My App',
94
+ sessionSecret: 'at-least-32-characters-long-secret-here',
95
+ },
96
+ })
97
+ ```
98
+
99
+ ```vue
100
+ <!-- pages/index.vue -->
101
+ <script setup>
102
+ const { user, login, logout } = useOpenApeAuth()
103
+ const email = ref('')
104
+ </script>
105
+
106
+ <template>
107
+ <div v-if="user">
108
+ Logged in as {{ user.sub }}
109
+ <button @click="logout">Logout</button>
110
+ </div>
111
+ <form v-else @submit.prevent="login(email)">
112
+ <input v-model="email" type="email" placeholder="you@example.com" />
113
+ <button type="submit">Login</button>
114
+ </form>
115
+ </template>
116
+ ```
117
+
118
+ See the [examples](../examples) directory for a fully working SP setup.
119
+
11
120
  ## License
12
121
 
13
- MIT
122
+ [MIT](./LICENSE)
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openape/nuxt-auth-sp",
3
3
  "configKey": "openapeSp",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.4",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -8,7 +8,7 @@ const module = defineNuxtModule({
8
8
  },
9
9
  defaults: {
10
10
  spId: "",
11
- spName: "OpenAPE Service Provider",
11
+ spName: "OpenApe Service Provider",
12
12
  sessionSecret: "change-me-sp-secret-at-least-32-chars-long",
13
13
  openapeUrl: ""
14
14
  },
@@ -1,4 +1,7 @@
1
+ import { defineEventHandler, getQuery, getRequestURL, sendRedirect } from "h3";
1
2
  import { handleCallback } from "@openape/auth";
3
+ import { getFlowState, getSpConfig, clearFlowState } from "../utils/sp-config.js";
4
+ import { getSpSession } from "../utils/sp-session.js";
2
5
  export default defineEventHandler(async (event) => {
3
6
  const query = getQuery(event);
4
7
  const { code, state, error, error_description } = query;
@@ -1,4 +1,6 @@
1
+ import { createError, defineEventHandler, getRequestURL, readBody } from "h3";
1
2
  import { createAuthorizationURL, discoverIdP } from "@openape/auth";
3
+ import { getSpConfig, saveFlowState } from "../utils/sp-config.js";
2
4
  export default defineEventHandler(async (event) => {
3
5
  const body = await readBody(event);
4
6
  const { spId, openapeUrl } = getSpConfig();
@@ -1,3 +1,5 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { getSpSession } from "../utils/sp-session.js";
1
3
  export default defineEventHandler(async (event) => {
2
4
  const session = await getSpSession(event);
3
5
  await session.clear();
@@ -1,3 +1,5 @@
1
+ import { createError, defineEventHandler } from "h3";
2
+ import { getSpSession } from "../utils/sp-session.js";
1
3
  export default defineEventHandler(async (event) => {
2
4
  const session = await getSpSession(event);
3
5
  const data = session.data;
@@ -1,4 +1,6 @@
1
+ import { defineEventHandler, getRequestURL } from "h3";
1
2
  import { createSPManifest } from "@openape/auth";
3
+ import { getSpConfig } from "../../utils/sp-config.js";
2
4
  export default defineEventHandler((event) => {
3
5
  const { spId, spName } = getSpConfig();
4
6
  const origin = getRequestURL(event).origin;
@@ -6,6 +8,6 @@ export default defineEventHandler((event) => {
6
8
  sp_id: spId,
7
9
  name: spName,
8
10
  redirect_uris: [`${origin}/api/callback`],
9
- description: `${spName} \u2014 OpenAPE Service Provider`
11
+ description: `${spName} \u2014 OpenApe Service Provider`
10
12
  });
11
13
  });
@@ -1,10 +1,12 @@
1
+ import { useSession } from "h3";
2
+ import { useRuntimeConfig } from "nitropack/runtime";
1
3
  const FLOW_COOKIE = "openape-flow";
2
4
  export function getSpConfig() {
3
5
  const config = useRuntimeConfig();
4
6
  return {
5
7
  spId: config.openapeSp.spId || "sp.example.com",
6
8
  openapeUrl: config.openapeSp.openapeUrl || "",
7
- spName: config.openapeSp.spName || "OpenAPE Service Provider"
9
+ spName: config.openapeSp.spName || "OpenApe Service Provider"
8
10
  };
9
11
  }
10
12
  export async function saveFlowState(event, state, flow) {
@@ -1,3 +1,5 @@
1
+ import { useSession } from "h3";
2
+ import { useRuntimeConfig } from "nitropack/runtime";
1
3
  export async function getSpSession(event) {
2
4
  const config = useRuntimeConfig();
3
5
  return await useSession(event, {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@openape/nuxt-auth-sp",
3
3
  "type": "module",
4
- "version": "0.1.0",
5
- "description": "OpenAPE Service Provider Nuxt module — adds OIDC login via DNS-based IdP discovery",
4
+ "version": "0.1.2",
5
+ "description": "OpenApe Service Provider Nuxt module — adds OIDC login via DNS-based IdP discovery",
6
6
  "author": "Patrick Hofmann",
7
7
  "license": "MIT",
8
8
  "exports": {
@@ -25,7 +25,8 @@
25
25
  "@nuxt/kit": "^3.16.0",
26
26
  "@openape/auth": "^0.1.0",
27
27
  "@openape/core": "^0.1.0",
28
- "defu": "^6.1.4"
28
+ "defu": "^6.1.4",
29
+ "h3": "^1.15.0"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "nuxt": "^4.0.0"