@authdog/vue 0.0.1 → 0.2.0

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
@@ -5,11 +5,7 @@ Authdog Vue SDK for authentication and user management.
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @authdog/vue
9
- # or
10
- yarn add @authdog/vue
11
- # or
12
- pnpm add @authdog/vue
8
+ bun add @authdog/vue
13
9
  ```
14
10
 
15
11
  ## Usage
@@ -26,7 +22,7 @@ pnpm add @authdog/vue
26
22
  </template>
27
23
 
28
24
  <script setup lang="ts">
29
- import { AuthdogProvider } from '@authdog/vue/client'
25
+ import { AuthdogProvider } from "@authdog/vue/client";
30
26
  </script>
31
27
  ```
32
28
 
@@ -34,22 +30,22 @@ import { AuthdogProvider } from '@authdog/vue/client'
34
30
 
35
31
  ```vue
36
32
  <script setup lang="ts">
37
- import { useSession, useUser } from '@authdog/vue'
33
+ import { useSession, useUser } from "@authdog/vue";
38
34
 
39
- const { session, isLoading } = useSession()
40
- const { user } = useUser()
35
+ const { session, isLoading } = useSession();
36
+ const { user } = useUser();
41
37
  </script>
42
38
  ```
43
39
 
44
40
  ### Server-side
45
41
 
46
42
  ```typescript
47
- import { createAuthdogServer } from '@authdog/vue/server'
43
+ import { createAuthdogServer } from "@authdog/vue/server";
48
44
 
49
45
  const authdog = createAuthdogServer({
50
46
  publicKey: process.env.AUTHDOG_PUBLIC_KEY!,
51
47
  secretKey: process.env.AUTHDOG_SECRET_KEY!,
52
- })
48
+ });
53
49
  ```
54
50
 
55
51
  ## API Reference
package/dist/client.d.mts CHANGED
@@ -1,2 +1,66 @@
1
+ import * as vue from 'vue';
1
2
 
2
- export { }
3
+ declare const AuthdogProvider: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
4
+ [key: string]: any;
5
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
6
+
7
+ declare const getTokenFromUri: (url: string) => string | null;
8
+ interface IFetchUserData {
9
+ user: {
10
+ id: string;
11
+ environmentId: string;
12
+ externalId: string;
13
+ userName: string;
14
+ displayName: string;
15
+ nickName: string;
16
+ profileUrl: string;
17
+ title: string;
18
+ userType: string;
19
+ preferredLanguage: string | null;
20
+ locale: string | null;
21
+ timezone: string | null;
22
+ active: boolean;
23
+ provider: string;
24
+ lastLogin: string;
25
+ createdAt: string;
26
+ updatedAt: string;
27
+ names: {
28
+ id: string;
29
+ userId: string;
30
+ formatted: string | null;
31
+ familyName: string;
32
+ givenName: string;
33
+ middleName: string | null;
34
+ honorificPrefix: string | null;
35
+ honorificSuffix: string | null;
36
+ createdAt: string;
37
+ updatedAt: string;
38
+ };
39
+ addresses: [];
40
+ emails: {
41
+ value: string;
42
+ primary: boolean;
43
+ type: string;
44
+ }[];
45
+ phoneNumbers: [];
46
+ ims: [];
47
+ photos: {
48
+ value: string;
49
+ type: string;
50
+ }[];
51
+ };
52
+ meta: {
53
+ code: number;
54
+ message: string;
55
+ };
56
+ }
57
+ declare const validatePublicKey: (publicKey: string) => void;
58
+ declare const fetchUserData: (publicKey: string, token: string) => Promise<IFetchUserData | null>;
59
+ declare const browserCookiesOptions: {
60
+ maxAge: number;
61
+ path: string;
62
+ secure: boolean;
63
+ sameSite: "lax";
64
+ };
65
+
66
+ export { AuthdogProvider, browserCookiesOptions, fetchUserData, getTokenFromUri, validatePublicKey };
package/dist/client.d.ts CHANGED
@@ -1,2 +1,66 @@
1
+ import * as vue from 'vue';
1
2
 
2
- export { }
3
+ declare const AuthdogProvider: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
4
+ [key: string]: any;
5
+ }>[] | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
6
+
7
+ declare const getTokenFromUri: (url: string) => string | null;
8
+ interface IFetchUserData {
9
+ user: {
10
+ id: string;
11
+ environmentId: string;
12
+ externalId: string;
13
+ userName: string;
14
+ displayName: string;
15
+ nickName: string;
16
+ profileUrl: string;
17
+ title: string;
18
+ userType: string;
19
+ preferredLanguage: string | null;
20
+ locale: string | null;
21
+ timezone: string | null;
22
+ active: boolean;
23
+ provider: string;
24
+ lastLogin: string;
25
+ createdAt: string;
26
+ updatedAt: string;
27
+ names: {
28
+ id: string;
29
+ userId: string;
30
+ formatted: string | null;
31
+ familyName: string;
32
+ givenName: string;
33
+ middleName: string | null;
34
+ honorificPrefix: string | null;
35
+ honorificSuffix: string | null;
36
+ createdAt: string;
37
+ updatedAt: string;
38
+ };
39
+ addresses: [];
40
+ emails: {
41
+ value: string;
42
+ primary: boolean;
43
+ type: string;
44
+ }[];
45
+ phoneNumbers: [];
46
+ ims: [];
47
+ photos: {
48
+ value: string;
49
+ type: string;
50
+ }[];
51
+ };
52
+ meta: {
53
+ code: number;
54
+ message: string;
55
+ };
56
+ }
57
+ declare const validatePublicKey: (publicKey: string) => void;
58
+ declare const fetchUserData: (publicKey: string, token: string) => Promise<IFetchUserData | null>;
59
+ declare const browserCookiesOptions: {
60
+ maxAge: number;
61
+ path: string;
62
+ secure: boolean;
63
+ sameSite: "lax";
64
+ };
65
+
66
+ export { AuthdogProvider, browserCookiesOptions, fetchUserData, getTokenFromUri, validatePublicKey };
package/dist/client.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var m=Object.defineProperty;var t=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var b=(r,o,p,f)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of x(o))!a.call(r,e)&&e!==p&&m(r,e,{get:()=>o[e],enumerable:!(f=t(o,e))||f.enumerable});return r};var c=r=>b(m({},"__esModule",{value:!0}),r);var d={};module.exports=c(d);
1
+ "use strict";var l=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var r in t)l(e,r,{get:t[r],enumerable:!0})},w=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of P(t))!k.call(e,n)&&n!==r&&l(e,n,{get:()=>t[n],enumerable:!(i=x(t,n))||i.enumerable});return e};var A=e=>w(l({},"__esModule",{value:!0}),e);var b={};v(b,{AuthdogProvider:()=>c,browserCookiesOptions:()=>y,fetchUserData:()=>h,getTokenFromUri:()=>p,validatePublicKey:()=>g});module.exports=A(b);var o=require("vue"),T=Symbol("authdog"),u="token",I=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,c=(0,o.defineComponent)({name:"AuthdogProvider",setup(e,{slots:t}){let r=(0,o.ref)(!0),i=(0,o.ref)(null),n=a=>{i.value=a};return(0,o.onMounted)(()=>{if(typeof window<"u"){let a=new URL(window.location.href),s=a.searchParams.get("token");if(s&&(a.searchParams.delete("token"),window.history.replaceState({},document.title,a.toString()),I.test(s))){localStorage.setItem(u,s),n(s),window.location.reload();return}let d=localStorage.getItem(u);d&&n(d),r.value=!1}else r.value=!1}),(0,o.provide)(T,{get isLoading(){return r.value},get token(){return i.value},setToken:n}),()=>{var a;return(a=t.default)==null?void 0:a.call(t)}}});var m=require("@authdog/node-commons"),f=e=>(0,m.validateAndParsePublicKey)(e);var p=e=>new URL(e).searchParams.get("token"),g=e=>{if(!e)throw new Error("Public key is not defined");if(!e.startsWith("pk_"))throw new Error("Invalid public key")},h=async(e,t)=>{g(e);let r=f(e),i=await fetch(`${r==null?void 0:r.identityHost}/oidc/${r==null?void 0:r.environmentId}/userinfo`,{headers:{authorization:`Bearer ${t}`}});if(!i.ok)throw new Error("Failed to fetch user info");return await i.json()},y={maxAge:3600*24*7,path:"/",secure:!0,sameSite:"lax"};0&&(module.exports={AuthdogProvider,browserCookiesOptions,fetchUserData,getTokenFromUri,validatePublicKey});
2
2
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"sourcesContent":["export * from './client'\n"],"mappings":"+WAAA,IAAAA,EAAA,kBAAAC,EAAAD","names":["client_exports","__toCommonJS"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/client/provider.ts","../src/commons.ts","../src/client/session.ts"],"sourcesContent":["export * from \"./client/index\";\n","import {\n defineComponent,\n onMounted,\n ref,\n provide,\n type InjectionKey,\n} from \"vue\";\n\nexport interface AuthdogContext {\n readonly isLoading: boolean;\n readonly token: string | null;\n setToken: (token: string | null) => void;\n}\n\nexport const AUTHDOG_CONTEXT_KEY: InjectionKey<AuthdogContext> =\n Symbol(\"authdog\");\n\n/** Shared localStorage key for the persisted token. */\nexport const TOKEN_STORAGE_KEY = \"token\";\n\n/** JWT shape: three base64url segments separated by dots. */\nconst JWT_PATTERN = /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n\nexport const AuthdogProvider = defineComponent({\n name: \"AuthdogProvider\",\n setup(_, { slots }) {\n const isLoading = ref(true);\n const token = ref<string | null>(null);\n\n const setToken = (newToken: string | null) => {\n token.value = newToken;\n };\n\n onMounted(() => {\n // Check if we're in the browser\n if (typeof window !== \"undefined\") {\n // Check if there's a token in the URL\n const url = new URL(window.location.href);\n const urlToken = url.searchParams.get(\"token\");\n\n if (urlToken) {\n // Remove token from URL without triggering a page reload,\n // regardless of whether the token is valid.\n url.searchParams.delete(\"token\");\n window.history.replaceState({}, document.title, url.toString());\n\n // Only persist values that look like a JWT to avoid storing\n // arbitrary attacker-supplied data.\n if (JWT_PATTERN.test(urlToken)) {\n localStorage.setItem(TOKEN_STORAGE_KEY, urlToken);\n setToken(urlToken);\n\n // Force a reload to ensure the server processes the token\n window.location.reload();\n return;\n }\n }\n\n // Check for existing token in localStorage\n const existingToken = localStorage.getItem(TOKEN_STORAGE_KEY);\n if (existingToken) {\n setToken(existingToken);\n }\n\n // If no token, we're done loading\n isLoading.value = false;\n } else {\n // If we're on the server, don't show loading state\n isLoading.value = false;\n }\n });\n\n // Expose reactive state through getters so consumers always read the\n // live ref values rather than a frozen snapshot taken at setup time.\n const context: AuthdogContext = {\n get isLoading() {\n return isLoading.value;\n },\n get token() {\n return token.value;\n },\n setToken,\n };\n\n provide(AUTHDOG_CONTEXT_KEY, context);\n\n return () => slots.default?.();\n },\n});\n","import {\n validateAndParsePublicKey,\n type PublicKeyPayload,\n} from \"@authdog/node-commons\";\n\nexport type { PublicKeyPayload };\n\n/**\n * Decodes and validates an Authdog public key. Delegates to the hardened\n * shared parser in @authdog/node-commons, which validates the payload and\n * enforces a trusted identity-host allowlist (SSRF / token-exfiltration\n * protection) rather than blindly decoding base64/JSON.\n */\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n return validateAndParsePublicKey(publicKey);\n};\n","import { getPublicKeyPayload } from \"../commons\";\n\nexport const getTokenFromUri = (url: string): string | null => {\n return new URL(url).searchParams.get(\"token\");\n};\n\ninterface IFetchUserData {\n user: {\n id: string;\n environmentId: string;\n externalId: string;\n userName: string;\n displayName: string;\n nickName: string;\n profileUrl: string;\n title: string;\n userType: string;\n preferredLanguage: string | null;\n locale: string | null;\n timezone: string | null;\n active: boolean;\n provider: string;\n lastLogin: string;\n createdAt: string;\n updatedAt: string;\n names: {\n id: string;\n userId: string;\n formatted: string | null;\n familyName: string;\n givenName: string;\n middleName: string | null;\n honorificPrefix: string | null;\n honorificSuffix: string | null;\n createdAt: string;\n updatedAt: string;\n };\n addresses: [];\n emails: {\n value: string;\n primary: boolean;\n type: string;\n }[];\n phoneNumbers: [];\n ims: [];\n photos: {\n value: string;\n type: string;\n }[];\n };\n meta: {\n code: number;\n message: string;\n };\n}\n\nexport const validatePublicKey = (publicKey: string) => {\n if (!publicKey) {\n throw new Error(\"Public key is not defined\");\n }\n\n if (!publicKey.startsWith(\"pk_\")) {\n throw new Error(\"Invalid public key\");\n }\n};\n\nexport const fetchUserData = async (\n publicKey: string,\n token: string,\n): Promise<IFetchUserData | null> => {\n validatePublicKey(publicKey);\n const publicKeyObj = getPublicKeyPayload(publicKey);\n const userData = await fetch(\n `${publicKeyObj?.identityHost}/oidc/${publicKeyObj?.environmentId}/userinfo`,\n {\n headers: {\n authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!userData.ok) {\n throw new Error(\"Failed to fetch user info\");\n }\n\n return await userData.json();\n};\n\n// NOTE: These options are for cookies usable from the browser. `httpOnly` is\n// intentionally omitted — it is a no-op (and misleading) for client-set\n// cookies since JS cannot set HttpOnly. Session cookies should be set\n// server-side with HttpOnly; do not set session cookies from client JS.\nexport const browserCookiesOptions = {\n maxAge: 60 * 60 * 24 * 7, // 1 week\n path: \"/\",\n secure: true,\n sameSite: \"lax\" as const,\n};\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qBAAAE,EAAA,0BAAAC,EAAA,kBAAAC,EAAA,oBAAAC,EAAA,sBAAAC,IAAA,eAAAC,EAAAP,GCAA,IAAAQ,EAMO,eAQMC,EACX,OAAO,SAAS,EAGLC,EAAoB,QAG3BC,EAAc,mDAEPC,KAAkB,mBAAgB,CAC7C,KAAM,kBACN,MAAMC,EAAG,CAAE,MAAAC,CAAM,EAAG,CAClB,IAAMC,KAAY,OAAI,EAAI,EACpBC,KAAQ,OAAmB,IAAI,EAE/BC,EAAYC,GAA4B,CAC5CF,EAAM,MAAQE,CAChB,EAEA,sBAAU,IAAM,CAEd,GAAI,OAAO,OAAW,IAAa,CAEjC,IAAMC,EAAM,IAAI,IAAI,OAAO,SAAS,IAAI,EAClCC,EAAWD,EAAI,aAAa,IAAI,OAAO,EAE7C,GAAIC,IAGFD,EAAI,aAAa,OAAO,OAAO,EAC/B,OAAO,QAAQ,aAAa,CAAC,EAAG,SAAS,MAAOA,EAAI,SAAS,CAAC,EAI1DR,EAAY,KAAKS,CAAQ,GAAG,CAC9B,aAAa,QAAQV,EAAmBU,CAAQ,EAChDH,EAASG,CAAQ,EAGjB,OAAO,SAAS,OAAO,EACvB,MACF,CAIF,IAAMC,EAAgB,aAAa,QAAQX,CAAiB,EACxDW,GACFJ,EAASI,CAAa,EAIxBN,EAAU,MAAQ,EACpB,MAEEA,EAAU,MAAQ,EAEtB,CAAC,KAcD,WAAQN,EAVwB,CAC9B,IAAI,WAAY,CACd,OAAOM,EAAU,KACnB,EACA,IAAI,OAAQ,CACV,OAAOC,EAAM,KACf,EACA,SAAAC,CACF,CAEoC,EAE7B,IAAG,CAtFd,IAAAK,EAsFiB,OAAAA,EAAAR,EAAM,UAAN,YAAAQ,EAAA,KAAAR,GACf,CACF,CAAC,ECxFD,IAAAS,EAGO,iCAUMC,EAAuBC,MAC3B,6BAA0BA,CAAS,ECZrC,IAAMC,EAAmBC,GACvB,IAAI,IAAIA,CAAG,EAAE,aAAa,IAAI,OAAO,EAqDjCC,EAAqBC,GAAsB,CACtD,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,2BAA2B,EAG7C,GAAI,CAACA,EAAU,WAAW,KAAK,EAC7B,MAAM,IAAI,MAAM,oBAAoB,CAExC,EAEaC,EAAgB,MAC3BD,EACAE,IACmC,CACnCH,EAAkBC,CAAS,EAC3B,IAAMG,EAAeC,EAAoBJ,CAAS,EAC5CK,EAAW,MAAM,MACrB,GAAGF,GAAA,YAAAA,EAAc,YAAY,SAASA,GAAA,YAAAA,EAAc,aAAa,YACjE,CACE,QAAS,CACP,cAAe,UAAUD,CAAK,EAChC,CACF,CACF,EAEA,GAAI,CAACG,EAAS,GACZ,MAAM,IAAI,MAAM,2BAA2B,EAG7C,OAAO,MAAMA,EAAS,KAAK,CAC7B,EAMaC,EAAwB,CACnC,OAAQ,KAAU,GAAK,EACvB,KAAM,IACN,OAAQ,GACR,SAAU,KACZ","names":["client_exports","__export","AuthdogProvider","browserCookiesOptions","fetchUserData","getTokenFromUri","validatePublicKey","__toCommonJS","import_vue","AUTHDOG_CONTEXT_KEY","TOKEN_STORAGE_KEY","JWT_PATTERN","AuthdogProvider","_","slots","isLoading","token","setToken","newToken","url","urlToken","existingToken","_a","import_node_commons","getPublicKeyPayload","publicKey","getTokenFromUri","url","validatePublicKey","publicKey","fetchUserData","token","publicKeyObj","getPublicKeyPayload","userData","browserCookiesOptions"]}
package/dist/client.mjs CHANGED
@@ -1 +1,2 @@
1
+ import{defineComponent as c,onMounted as m,ref as l,provide as f}from"vue";var p=Symbol("authdog"),g="token",h=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,y=c({name:"AuthdogProvider",setup(e,{slots:n}){let t=l(!0),o=l(null),a=r=>{o.value=r};return m(()=>{if(typeof window<"u"){let r=new URL(window.location.href),i=r.searchParams.get("token");if(i&&(r.searchParams.delete("token"),window.history.replaceState({},document.title,r.toString()),h.test(i))){localStorage.setItem(g,i),a(i),window.location.reload();return}let s=localStorage.getItem(g);s&&a(s),t.value=!1}else t.value=!1}),f(p,{get isLoading(){return t.value},get token(){return o.value},setToken:a}),()=>{var r;return(r=n.default)==null?void 0:r.call(n)}}});import{validateAndParsePublicKey as x}from"@authdog/node-commons";var d=e=>x(e);var P=e=>new URL(e).searchParams.get("token"),u=e=>{if(!e)throw new Error("Public key is not defined");if(!e.startsWith("pk_"))throw new Error("Invalid public key")},k=async(e,n)=>{u(e);let t=d(e),o=await fetch(`${t==null?void 0:t.identityHost}/oidc/${t==null?void 0:t.environmentId}/userinfo`,{headers:{authorization:`Bearer ${n}`}});if(!o.ok)throw new Error("Failed to fetch user info");return await o.json()},v={maxAge:3600*24*7,path:"/",secure:!0,sameSite:"lax"};export{y as AuthdogProvider,v as browserCookiesOptions,k as fetchUserData,P as getTokenFromUri,u as validatePublicKey};
1
2
  //# sourceMappingURL=client.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/client/provider.ts","../src/commons.ts","../src/client/session.ts"],"sourcesContent":["import {\n defineComponent,\n onMounted,\n ref,\n provide,\n type InjectionKey,\n} from \"vue\";\n\nexport interface AuthdogContext {\n readonly isLoading: boolean;\n readonly token: string | null;\n setToken: (token: string | null) => void;\n}\n\nexport const AUTHDOG_CONTEXT_KEY: InjectionKey<AuthdogContext> =\n Symbol(\"authdog\");\n\n/** Shared localStorage key for the persisted token. */\nexport const TOKEN_STORAGE_KEY = \"token\";\n\n/** JWT shape: three base64url segments separated by dots. */\nconst JWT_PATTERN = /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n\nexport const AuthdogProvider = defineComponent({\n name: \"AuthdogProvider\",\n setup(_, { slots }) {\n const isLoading = ref(true);\n const token = ref<string | null>(null);\n\n const setToken = (newToken: string | null) => {\n token.value = newToken;\n };\n\n onMounted(() => {\n // Check if we're in the browser\n if (typeof window !== \"undefined\") {\n // Check if there's a token in the URL\n const url = new URL(window.location.href);\n const urlToken = url.searchParams.get(\"token\");\n\n if (urlToken) {\n // Remove token from URL without triggering a page reload,\n // regardless of whether the token is valid.\n url.searchParams.delete(\"token\");\n window.history.replaceState({}, document.title, url.toString());\n\n // Only persist values that look like a JWT to avoid storing\n // arbitrary attacker-supplied data.\n if (JWT_PATTERN.test(urlToken)) {\n localStorage.setItem(TOKEN_STORAGE_KEY, urlToken);\n setToken(urlToken);\n\n // Force a reload to ensure the server processes the token\n window.location.reload();\n return;\n }\n }\n\n // Check for existing token in localStorage\n const existingToken = localStorage.getItem(TOKEN_STORAGE_KEY);\n if (existingToken) {\n setToken(existingToken);\n }\n\n // If no token, we're done loading\n isLoading.value = false;\n } else {\n // If we're on the server, don't show loading state\n isLoading.value = false;\n }\n });\n\n // Expose reactive state through getters so consumers always read the\n // live ref values rather than a frozen snapshot taken at setup time.\n const context: AuthdogContext = {\n get isLoading() {\n return isLoading.value;\n },\n get token() {\n return token.value;\n },\n setToken,\n };\n\n provide(AUTHDOG_CONTEXT_KEY, context);\n\n return () => slots.default?.();\n },\n});\n","import {\n validateAndParsePublicKey,\n type PublicKeyPayload,\n} from \"@authdog/node-commons\";\n\nexport type { PublicKeyPayload };\n\n/**\n * Decodes and validates an Authdog public key. Delegates to the hardened\n * shared parser in @authdog/node-commons, which validates the payload and\n * enforces a trusted identity-host allowlist (SSRF / token-exfiltration\n * protection) rather than blindly decoding base64/JSON.\n */\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n return validateAndParsePublicKey(publicKey);\n};\n","import { getPublicKeyPayload } from \"../commons\";\n\nexport const getTokenFromUri = (url: string): string | null => {\n return new URL(url).searchParams.get(\"token\");\n};\n\ninterface IFetchUserData {\n user: {\n id: string;\n environmentId: string;\n externalId: string;\n userName: string;\n displayName: string;\n nickName: string;\n profileUrl: string;\n title: string;\n userType: string;\n preferredLanguage: string | null;\n locale: string | null;\n timezone: string | null;\n active: boolean;\n provider: string;\n lastLogin: string;\n createdAt: string;\n updatedAt: string;\n names: {\n id: string;\n userId: string;\n formatted: string | null;\n familyName: string;\n givenName: string;\n middleName: string | null;\n honorificPrefix: string | null;\n honorificSuffix: string | null;\n createdAt: string;\n updatedAt: string;\n };\n addresses: [];\n emails: {\n value: string;\n primary: boolean;\n type: string;\n }[];\n phoneNumbers: [];\n ims: [];\n photos: {\n value: string;\n type: string;\n }[];\n };\n meta: {\n code: number;\n message: string;\n };\n}\n\nexport const validatePublicKey = (publicKey: string) => {\n if (!publicKey) {\n throw new Error(\"Public key is not defined\");\n }\n\n if (!publicKey.startsWith(\"pk_\")) {\n throw new Error(\"Invalid public key\");\n }\n};\n\nexport const fetchUserData = async (\n publicKey: string,\n token: string,\n): Promise<IFetchUserData | null> => {\n validatePublicKey(publicKey);\n const publicKeyObj = getPublicKeyPayload(publicKey);\n const userData = await fetch(\n `${publicKeyObj?.identityHost}/oidc/${publicKeyObj?.environmentId}/userinfo`,\n {\n headers: {\n authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!userData.ok) {\n throw new Error(\"Failed to fetch user info\");\n }\n\n return await userData.json();\n};\n\n// NOTE: These options are for cookies usable from the browser. `httpOnly` is\n// intentionally omitted — it is a no-op (and misleading) for client-set\n// cookies since JS cannot set HttpOnly. Session cookies should be set\n// server-side with HttpOnly; do not set session cookies from client JS.\nexport const browserCookiesOptions = {\n maxAge: 60 * 60 * 24 * 7, // 1 week\n path: \"/\",\n secure: true,\n sameSite: \"lax\" as const,\n};\n"],"mappings":"AAAA,OACE,mBAAAA,EACA,aAAAC,EACA,OAAAC,EACA,WAAAC,MAEK,MAQA,IAAMC,EACX,OAAO,SAAS,EAGLC,EAAoB,QAG3BC,EAAc,mDAEPC,EAAkBP,EAAgB,CAC7C,KAAM,kBACN,MAAMQ,EAAG,CAAE,MAAAC,CAAM,EAAG,CAClB,IAAMC,EAAYR,EAAI,EAAI,EACpBS,EAAQT,EAAmB,IAAI,EAE/BU,EAAYC,GAA4B,CAC5CF,EAAM,MAAQE,CAChB,EAEA,OAAAZ,EAAU,IAAM,CAEd,GAAI,OAAO,OAAW,IAAa,CAEjC,IAAMa,EAAM,IAAI,IAAI,OAAO,SAAS,IAAI,EAClCC,EAAWD,EAAI,aAAa,IAAI,OAAO,EAE7C,GAAIC,IAGFD,EAAI,aAAa,OAAO,OAAO,EAC/B,OAAO,QAAQ,aAAa,CAAC,EAAG,SAAS,MAAOA,EAAI,SAAS,CAAC,EAI1DR,EAAY,KAAKS,CAAQ,GAAG,CAC9B,aAAa,QAAQV,EAAmBU,CAAQ,EAChDH,EAASG,CAAQ,EAGjB,OAAO,SAAS,OAAO,EACvB,MACF,CAIF,IAAMC,EAAgB,aAAa,QAAQX,CAAiB,EACxDW,GACFJ,EAASI,CAAa,EAIxBN,EAAU,MAAQ,EACpB,MAEEA,EAAU,MAAQ,EAEtB,CAAC,EAcDP,EAAQC,EAVwB,CAC9B,IAAI,WAAY,CACd,OAAOM,EAAU,KACnB,EACA,IAAI,OAAQ,CACV,OAAOC,EAAM,KACf,EACA,SAAAC,CACF,CAEoC,EAE7B,IAAG,CAtFd,IAAAK,EAsFiB,OAAAA,EAAAR,EAAM,UAAN,YAAAQ,EAAA,KAAAR,GACf,CACF,CAAC,ECxFD,OACE,6BAAAS,MAEK,wBAUA,IAAMC,EAAuBC,GAC3BF,EAA0BE,CAAS,ECZrC,IAAMC,EAAmBC,GACvB,IAAI,IAAIA,CAAG,EAAE,aAAa,IAAI,OAAO,EAqDjCC,EAAqBC,GAAsB,CACtD,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,2BAA2B,EAG7C,GAAI,CAACA,EAAU,WAAW,KAAK,EAC7B,MAAM,IAAI,MAAM,oBAAoB,CAExC,EAEaC,EAAgB,MAC3BD,EACAE,IACmC,CACnCH,EAAkBC,CAAS,EAC3B,IAAMG,EAAeC,EAAoBJ,CAAS,EAC5CK,EAAW,MAAM,MACrB,GAAGF,GAAA,YAAAA,EAAc,YAAY,SAASA,GAAA,YAAAA,EAAc,aAAa,YACjE,CACE,QAAS,CACP,cAAe,UAAUD,CAAK,EAChC,CACF,CACF,EAEA,GAAI,CAACG,EAAS,GACZ,MAAM,IAAI,MAAM,2BAA2B,EAG7C,OAAO,MAAMA,EAAS,KAAK,CAC7B,EAMaC,EAAwB,CACnC,OAAQ,KAAU,GAAK,EACvB,KAAM,IACN,OAAQ,GACR,SAAU,KACZ","names":["defineComponent","onMounted","ref","provide","AUTHDOG_CONTEXT_KEY","TOKEN_STORAGE_KEY","JWT_PATTERN","AuthdogProvider","_","slots","isLoading","token","setToken","newToken","url","urlToken","existingToken","_a","validateAndParsePublicKey","getPublicKeyPayload","publicKey","getTokenFromUri","url","validatePublicKey","publicKey","fetchUserData","token","publicKeyObj","getPublicKeyPayload","userData","browserCookiesOptions"]}
package/dist/index.d.mts CHANGED
@@ -1,11 +1,12 @@
1
+ export { AuthdogProvider, browserCookiesOptions, fetchUserData, getTokenFromUri, validatePublicKey } from './client.mjs';
1
2
  import * as vue from 'vue';
2
3
 
3
4
  declare const useSession: () => {
4
- session: {
5
+ session: vue.ComputedRef<{
5
6
  token: string | null;
6
7
  isAuthenticated: boolean;
7
- };
8
- isLoading: boolean;
8
+ }>;
9
+ isLoading: vue.ComputedRef<boolean>;
9
10
  };
10
11
 
11
12
  declare const useUser: () => {
@@ -90,7 +91,25 @@ declare const useOrganizationList: () => {
90
91
  fetchOrganizations: () => Promise<any[]>;
91
92
  };
92
93
 
93
- declare const useAuthz: () => {
94
+ /**
95
+ * ⚠️ PRESENTATIONAL ONLY — NOT A SECURITY BOUNDARY.
96
+ *
97
+ * This composable fetches a permission list to drive UI affordances (showing
98
+ * or hiding buttons, menu items, etc.). It runs entirely in the browser and
99
+ * is therefore trivially bypassable by any client. It MUST NOT be used to
100
+ * gate access to data or actions.
101
+ *
102
+ * Every protected operation MUST be independently enforced server-side.
103
+ */
104
+ interface UseAuthzOptions {
105
+ /**
106
+ * URL of the endpoint that returns the current user's permissions.
107
+ * Defaults to "/api/permissions". This endpoint is informational only;
108
+ * authorization must still be enforced on every protected server endpoint.
109
+ */
110
+ permissionsUrl?: string;
111
+ }
112
+ declare const useAuthz: (options?: UseAuthzOptions) => {
94
113
  permissions: vue.ComputedRef<string[]>;
95
114
  isLoading: vue.ComputedRef<boolean>;
96
115
  error: vue.ComputedRef<Error | null>;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
+ export { AuthdogProvider, browserCookiesOptions, fetchUserData, getTokenFromUri, validatePublicKey } from './client.js';
1
2
  import * as vue from 'vue';
2
3
 
3
4
  declare const useSession: () => {
4
- session: {
5
+ session: vue.ComputedRef<{
5
6
  token: string | null;
6
7
  isAuthenticated: boolean;
7
- };
8
- isLoading: boolean;
8
+ }>;
9
+ isLoading: vue.ComputedRef<boolean>;
9
10
  };
10
11
 
11
12
  declare const useUser: () => {
@@ -90,7 +91,25 @@ declare const useOrganizationList: () => {
90
91
  fetchOrganizations: () => Promise<any[]>;
91
92
  };
92
93
 
93
- declare const useAuthz: () => {
94
+ /**
95
+ * ⚠️ PRESENTATIONAL ONLY — NOT A SECURITY BOUNDARY.
96
+ *
97
+ * This composable fetches a permission list to drive UI affordances (showing
98
+ * or hiding buttons, menu items, etc.). It runs entirely in the browser and
99
+ * is therefore trivially bypassable by any client. It MUST NOT be used to
100
+ * gate access to data or actions.
101
+ *
102
+ * Every protected operation MUST be independently enforced server-side.
103
+ */
104
+ interface UseAuthzOptions {
105
+ /**
106
+ * URL of the endpoint that returns the current user's permissions.
107
+ * Defaults to "/api/permissions". This endpoint is informational only;
108
+ * authorization must still be enforced on every protected server endpoint.
109
+ */
110
+ permissionsUrl?: string;
111
+ }
112
+ declare const useAuthz: (options?: UseAuthzOptions) => {
94
113
  permissions: vue.ComputedRef<string[]>;
95
114
  isLoading: vue.ComputedRef<boolean>;
96
115
  error: vue.ComputedRef<Error | null>;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var x=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var N=(t,e)=>{for(var r in e)x(t,r,{get:e[r],enumerable:!0})},j=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of I(e))!b.call(t,s)&&s!==r&&x(t,s,{get:()=>e[s],enumerable:!(n=S(e,s))||n.enumerable});return t};var H=t=>j(x({},"__esModule",{value:!0}),t);var D={};N(D,{useAuthz:()=>z,useOrganization:()=>_,useOrganizationList:()=>L,useSession:()=>E,useSignIn:()=>T,useSignOut:()=>U,useSignUp:()=>C,useUser:()=>O});module.exports=H(D);var y=require("vue");var m=require("vue"),a=Symbol("authdog"),X=(0,m.defineComponent)({name:"AuthdogProvider",setup(t,{slots:e}){let r=(0,m.ref)(!0),n=(0,m.ref)(null),s=o=>{n.value=o};(0,m.onMounted)(()=>{if(typeof window<"u"){let o=new URL(window.location.href),i=o.searchParams.get("token");if(i){o.searchParams.delete("token"),window.history.replaceState({},document.title,o.toString()),localStorage.setItem("token",i),s(i),window.location.reload();return}let l=localStorage.getItem("token");l&&s(l),r.value=!1}else r.value=!1});let u={isLoading:r.value,token:n.value,setToken:s};return(0,m.provide)(a,u),()=>{var o;return(o=e.default)==null?void 0:o.call(e)}}});var E=()=>{let t=(0,y.inject)(a);if(!t)throw new Error("useSession must be used within AuthdogProvider");return{session:(0,y.computed)(()=>({token:t.token,isAuthenticated:!!t.token})).value,isLoading:t.isLoading}};var c=require("vue");var k=t=>{if(!t)throw new Error("Public key is not defined");if(!t.startsWith("pk_"))throw new Error("Invalid public key");try{return JSON.parse(Buffer.from(t.replace("pk_",""),"base64").toString("utf-8"))}catch{throw new Error("Failed to parse public key")}};var A=t=>{if(!t)throw new Error("Public key is not defined");if(!t.startsWith("pk_"))throw new Error("Invalid public key")},P=async(t,e)=>{A(t);let r=k(t),n=await fetch(`${r==null?void 0:r.identityHost}/oidc/${r==null?void 0:r.environmentId}/userinfo`,{headers:{authorization:`Bearer ${e}`}});if(!n.ok)throw new Error("Failed to fetch user info");return await n.json()},W={maxAge:60*60*24*7,path:"/",httpOnly:!0};var O=()=>{let t=(0,c.inject)(a),e=(0,c.ref)(null),r=(0,c.ref)(!1),n=(0,c.ref)(null);if(!t)throw new Error("useUser must be used within AuthdogProvider");let s=async o=>{if(!t.token)return null;r.value=!0,n.value=null;try{A(o);let i=await P(o,t.token);return e.value=(i==null?void 0:i.user)||null,(i==null?void 0:i.user)||null}catch(i){return n.value=i,null}finally{r.value=!1}},u=(0,c.computed)(()=>!!t.token&&!!e.value);return{user:(0,c.computed)(()=>e.value),isLoading:(0,c.computed)(()=>r.value),error:(0,c.computed)(()=>n.value),isAuthenticated:u,fetchUser:s}};var h=require("vue");var T=()=>{let t=(0,h.inject)(a),e=(0,h.ref)(!1),r=(0,h.ref)(null);if(!t)throw new Error("useSignIn must be used within AuthdogProvider");return{signIn:async(s,u)=>{e.value=!0,r.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),i=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);i.searchParams.set("client_id",s),i.searchParams.set("response_type","code"),i.searchParams.set("scope","openid profile email"),i.searchParams.set("redirect_uri",u||window.location.origin),window.location.href=i.toString()}catch(o){r.value=o}finally{e.value=!1}},isLoading:(0,h.computed)(()=>e.value),error:(0,h.computed)(()=>r.value)}};var p=require("vue");var C=()=>{let t=(0,p.inject)(a),e=(0,p.ref)(!1),r=(0,p.ref)(null);if(!t)throw new Error("useSignUp must be used within AuthdogProvider");return{signUp:async(s,u)=>{e.value=!0,r.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),i=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);i.searchParams.set("client_id",s),i.searchParams.set("response_type","code"),i.searchParams.set("scope","openid profile email"),i.searchParams.set("redirect_uri",u||window.location.origin),i.searchParams.set("prompt","signup"),window.location.href=i.toString()}catch(o){r.value=o}finally{e.value=!1}},isLoading:(0,p.computed)(()=>e.value),error:(0,p.computed)(()=>r.value)}};var v=require("vue");var U=()=>{let t=(0,v.inject)(a),e=(0,v.ref)(!1),r=(0,v.ref)(null);if(!t)throw new Error("useSignOut must be used within AuthdogProvider");return{signOut:async()=>{e.value=!0,r.value=null;try{t.setToken(null),typeof window<"u"&&localStorage.removeItem("token"),typeof window<"u"&&(window.location.href="/logout")}catch(s){r.value=s}finally{e.value=!1}},isLoading:(0,v.computed)(()=>e.value),error:(0,v.computed)(()=>r.value)}};var d=require("vue");var _=()=>{let t=(0,d.inject)(a),e=(0,d.ref)(null),r=(0,d.ref)(!1),n=(0,d.ref)(null);if(!t)throw new Error("useOrganization must be used within AuthdogProvider");let s=async u=>{if(!t.token)return null;r.value=!0,n.value=null;try{let o=await fetch(`/api/organizations/${u}`,{headers:{Authorization:`Bearer ${t.token}`}});if(!o.ok)throw new Error("Failed to fetch organization");return e.value=await o.json(),e.value}catch(o){return n.value=o,null}finally{r.value=!1}};return{organization:(0,d.computed)(()=>e.value),isLoading:(0,d.computed)(()=>r.value),error:(0,d.computed)(()=>n.value),fetchOrganization:s}};var g=require("vue");var L=()=>{let t=(0,g.inject)(a),e=(0,g.ref)([]),r=(0,g.ref)(!1),n=(0,g.ref)(null);if(!t)throw new Error("useOrganizationList must be used within AuthdogProvider");let s=async()=>{if(!t.token)return[];r.value=!0,n.value=null;try{let u=await fetch("/api/organizations",{headers:{Authorization:`Bearer ${t.token}`}});if(!u.ok)throw new Error("Failed to fetch organizations");let o=await u.json();return e.value=o.organizations||[],e.value}catch(u){return n.value=u,[]}finally{r.value=!1}};return{organizations:(0,g.computed)(()=>e.value),isLoading:(0,g.computed)(()=>r.value),error:(0,g.computed)(()=>n.value),fetchOrganizations:s}};var f=require("vue");var z=()=>{let t=(0,f.inject)(a),e=(0,f.ref)([]),r=(0,f.ref)(!1),n=(0,f.ref)(null);if(!t)throw new Error("useAuthz must be used within AuthdogProvider");let s=async()=>{if(!t.token)return[];r.value=!0,n.value=null;try{let l=await fetch("/api/permissions",{headers:{Authorization:`Bearer ${t.token}`}});if(!l.ok)throw new Error("Failed to fetch permissions");let w=await l.json();return e.value=w.permissions||[],e.value}catch(l){return n.value=l,[]}finally{r.value=!1}},u=l=>e.value.includes(l),o=l=>l.some(w=>e.value.includes(w)),i=l=>l.every(w=>e.value.includes(w));return{permissions:(0,f.computed)(()=>e.value),isLoading:(0,f.computed)(()=>r.value),error:(0,f.computed)(()=>n.value),fetchPermissions:s,hasPermission:u,hasAnyPermission:o,hasAllPermissions:i}};0&&(module.exports={useAuthz,useOrganization,useOrganizationList,useSession,useSignIn,useSignOut,useSignUp,useUser});
1
+ "use strict";var T=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var H=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var Y=(t,r)=>{for(var e in r)T(t,e,{get:r[e],enumerable:!0})},X=(t,r,e,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of H(r))!G.call(t,s)&&s!==e&&T(t,s,{get:()=>r[s],enumerable:!(i=D(r,s))||i.enumerable});return t};var F=t=>X(T({},"__esModule",{value:!0}),t);var B={};Y(B,{AuthdogProvider:()=>O,browserCookiesOptions:()=>z,fetchUserData:()=>P,getTokenFromUri:()=>_,useAuthz:()=>j,useOrganization:()=>I,useOrganizationList:()=>K,useSession:()=>C,useSignIn:()=>S,useSignOut:()=>N,useSignUp:()=>b,useUser:()=>L,validatePublicKey:()=>y});module.exports=F(B);var m=require("vue"),a=Symbol("authdog"),E="token",R=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,O=(0,m.defineComponent)({name:"AuthdogProvider",setup(t,{slots:r}){let e=(0,m.ref)(!0),i=(0,m.ref)(null),s=o=>{i.value=o};return(0,m.onMounted)(()=>{if(typeof window<"u"){let o=new URL(window.location.href),n=o.searchParams.get("token");if(n&&(o.searchParams.delete("token"),window.history.replaceState({},document.title,o.toString()),R.test(n))){localStorage.setItem(E,n),s(n),window.location.reload();return}let A=localStorage.getItem(E);A&&s(A),e.value=!1}else e.value=!1}),(0,m.provide)(a,{get isLoading(){return e.value},get token(){return i.value},setToken:s}),()=>{var o;return(o=r.default)==null?void 0:o.call(r)}}});var k=require("@authdog/node-commons"),U=t=>(0,k.validateAndParsePublicKey)(t);var _=t=>new URL(t).searchParams.get("token"),y=t=>{if(!t)throw new Error("Public key is not defined");if(!t.startsWith("pk_"))throw new Error("Invalid public key")},P=async(t,r)=>{y(t);let e=U(t),i=await fetch(`${e==null?void 0:e.identityHost}/oidc/${e==null?void 0:e.environmentId}/userinfo`,{headers:{authorization:`Bearer ${r}`}});if(!i.ok)throw new Error("Failed to fetch user info");return await i.json()},z={maxAge:3600*24*7,path:"/",secure:!0,sameSite:"lax"};var x=require("vue");var C=()=>{let t=(0,x.inject)(a);if(!t)throw new Error("useSession must be used within AuthdogProvider");return{session:(0,x.computed)(()=>({token:t.token,isAuthenticated:!!t.token})),isLoading:(0,x.computed)(()=>t.isLoading)}};var c=require("vue");var L=()=>{let t=(0,c.inject)(a),r=(0,c.ref)(null),e=(0,c.ref)(!1),i=(0,c.ref)(null);if(!t)throw new Error("useUser must be used within AuthdogProvider");let s=async o=>{if(!t.token)return null;e.value=!0,i.value=null;try{y(o);let n=await P(o,t.token);return r.value=(n==null?void 0:n.user)||null,(n==null?void 0:n.user)||null}catch(n){return i.value=n,null}finally{e.value=!1}},u=(0,c.computed)(()=>!!t.token&&!!r.value);return{user:(0,c.computed)(()=>r.value),isLoading:(0,c.computed)(()=>e.value),error:(0,c.computed)(()=>i.value),isAuthenticated:u,fetchUser:s}};var p=require("vue");var S=()=>{let t=(0,p.inject)(a),r=(0,p.ref)(!1),e=(0,p.ref)(null);if(!t)throw new Error("useSignIn must be used within AuthdogProvider");return{signIn:async(s,u)=>{r.value=!0,e.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),n=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);n.searchParams.set("client_id",s),n.searchParams.set("response_type","code"),n.searchParams.set("scope","openid profile email"),n.searchParams.set("redirect_uri",u||window.location.origin),window.location.href=n.toString()}catch(o){e.value=o}finally{r.value=!1}},isLoading:(0,p.computed)(()=>r.value),error:(0,p.computed)(()=>e.value)}};var h=require("vue");var b=()=>{let t=(0,h.inject)(a),r=(0,h.ref)(!1),e=(0,h.ref)(null);if(!t)throw new Error("useSignUp must be used within AuthdogProvider");return{signUp:async(s,u)=>{r.value=!0,e.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),n=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);n.searchParams.set("client_id",s),n.searchParams.set("response_type","code"),n.searchParams.set("scope","openid profile email"),n.searchParams.set("redirect_uri",u||window.location.origin),n.searchParams.set("prompt","signup"),window.location.href=n.toString()}catch(o){e.value=o}finally{r.value=!1}},isLoading:(0,h.computed)(()=>r.value),error:(0,h.computed)(()=>e.value)}};var v=require("vue");var N=()=>{let t=(0,v.inject)(a),r=(0,v.ref)(!1),e=(0,v.ref)(null);if(!t)throw new Error("useSignOut must be used within AuthdogProvider");return{signOut:async()=>{r.value=!0,e.value=null;try{t.setToken(null),typeof window<"u"&&localStorage.removeItem(E),typeof window<"u"&&(window.location.href="/logout")}catch(s){e.value=s}finally{r.value=!1}},isLoading:(0,v.computed)(()=>r.value),error:(0,v.computed)(()=>e.value)}};var d=require("vue");var I=()=>{let t=(0,d.inject)(a),r=(0,d.ref)(null),e=(0,d.ref)(!1),i=(0,d.ref)(null);if(!t)throw new Error("useOrganization must be used within AuthdogProvider");let s=async u=>{if(!t.token)return null;e.value=!0,i.value=null;try{let o=await fetch(`/api/organizations/${u}`,{headers:{Authorization:`Bearer ${t.token}`}});if(!o.ok)throw new Error("Failed to fetch organization");return r.value=await o.json(),r.value}catch(o){return i.value=o,null}finally{e.value=!1}};return{organization:(0,d.computed)(()=>r.value),isLoading:(0,d.computed)(()=>e.value),error:(0,d.computed)(()=>i.value),fetchOrganization:s}};var g=require("vue");var K=()=>{let t=(0,g.inject)(a),r=(0,g.ref)([]),e=(0,g.ref)(!1),i=(0,g.ref)(null);if(!t)throw new Error("useOrganizationList must be used within AuthdogProvider");let s=async()=>{if(!t.token)return[];e.value=!0,i.value=null;try{let u=await fetch("/api/organizations",{headers:{Authorization:`Bearer ${t.token}`}});if(!u.ok)throw new Error("Failed to fetch organizations");let o=await u.json();return r.value=o.organizations||[],r.value}catch(u){return i.value=u,[]}finally{e.value=!1}};return{organizations:(0,g.computed)(()=>r.value),isLoading:(0,g.computed)(()=>e.value),error:(0,g.computed)(()=>i.value),fetchOrganizations:s}};var f=require("vue");var j=(t={})=>{let r=(0,f.inject)(a),e=(0,f.ref)([]),i=(0,f.ref)(!1),s=(0,f.ref)(null);if(!r)throw new Error("useAuthz must be used within AuthdogProvider");let u=t.permissionsUrl??"/api/permissions",o=async()=>{if(!r.token)return[];i.value=!0,s.value=null;try{let l=await fetch(u,{headers:{Authorization:`Bearer ${r.token}`}});if(l.status===401)throw e.value=[],new Error("Unauthorized: authentication failed (401)");if(!l.ok)throw new Error(`Failed to fetch permissions (status ${l.status})`);let w=await l.json();return e.value=w.permissions||[],e.value}catch(l){return s.value=l,[]}finally{i.value=!1}},n=l=>e.value.includes(l),A=l=>l.some(w=>e.value.includes(w)),$=l=>l.every(w=>e.value.includes(w));return{permissions:(0,f.computed)(()=>e.value),isLoading:(0,f.computed)(()=>i.value),error:(0,f.computed)(()=>s.value),fetchPermissions:o,hasPermission:n,hasAnyPermission:A,hasAllPermissions:$}};0&&(module.exports={AuthdogProvider,browserCookiesOptions,fetchUserData,getTokenFromUri,useAuthz,useOrganization,useOrganizationList,useSession,useSignIn,useSignOut,useSignUp,useUser,validatePublicKey});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/composables/use-session.ts","../src/client/provider.ts","../src/composables/use-user.ts","../src/commons.ts","../src/client/session.ts","../src/composables/use-signin.ts","../src/composables/use-signup.ts","../src/composables/use-signout.ts","../src/composables/use-organization.ts","../src/composables/use-organization-list.ts","../src/composables/use-authz.ts"],"sourcesContent":["export * from './client'\nexport * from './composables'\n","import { computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSession = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n\n if (!context) {\n throw new Error('useSession must be used within AuthdogProvider')\n }\n\n const session = computed(() => ({\n token: context.token,\n isAuthenticated: !!context.token,\n }))\n\n return {\n session: session.value,\n isLoading: context.isLoading,\n }\n}\n","import { defineComponent, onMounted, ref, provide, inject, type InjectionKey } from 'vue'\n\nexport interface AuthdogContext {\n isLoading: boolean\n token: string | null\n setToken: (token: string | null) => void\n}\n\nexport const AUTHDOG_CONTEXT_KEY: InjectionKey<AuthdogContext> = Symbol('authdog')\n\nexport const AuthdogProvider = defineComponent({\n name: 'AuthdogProvider',\n setup(_, { slots }) {\n const isLoading = ref(true)\n const token = ref<string | null>(null)\n\n const setToken = (newToken: string | null) => {\n token.value = newToken\n }\n\n onMounted(() => {\n // Check if we're in the browser\n if (typeof window !== 'undefined') {\n // Check if there's a token in the URL\n const url = new URL(window.location.href)\n const urlToken = url.searchParams.get('token')\n\n if (urlToken) {\n // Remove token from URL without triggering a page reload\n url.searchParams.delete('token')\n window.history.replaceState({}, document.title, url.toString())\n \n // Store token and reload to ensure server processes it\n localStorage.setItem('token', urlToken)\n setToken(urlToken)\n \n // Force a reload to ensure the server processes the token\n window.location.reload()\n return\n }\n\n // Check for existing token in localStorage\n const existingToken = localStorage.getItem('token')\n if (existingToken) {\n setToken(existingToken)\n }\n\n // If no token, we're done loading\n isLoading.value = false\n } else {\n // If we're on the server, don't show loading state\n isLoading.value = false\n }\n })\n\n const context: AuthdogContext = {\n isLoading: isLoading.value,\n token: token.value,\n setToken\n }\n\n provide(AUTHDOG_CONTEXT_KEY, context)\n\n return () => slots.default?.()\n }\n})\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\nimport { fetchUserData, validatePublicKey } from '../client/session'\n\nexport const useUser = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const user = ref<any>(null)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useUser must be used within AuthdogProvider')\n }\n\n const fetchUser = async (publicKey: string) => {\n if (!context.token) {\n return null\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n validatePublicKey(publicKey)\n const userData = await fetchUserData(publicKey, context.token)\n user.value = userData?.user || null\n return userData?.user || null\n } catch (err) {\n error.value = err as Error\n return null\n } finally {\n isLoading.value = false\n }\n }\n\n const isAuthenticated = computed(() => !!context.token && !!user.value)\n\n return {\n user: computed(() => user.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n isAuthenticated,\n fetchUser,\n }\n}\n","export interface PublicKeyPayload {\n environmentId: string\n identityHost: string\n}\n\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n if (!publicKey) {\n throw new Error('Public key is not defined')\n }\n\n if (!publicKey.startsWith('pk_')) {\n throw new Error('Invalid public key')\n }\n\n try {\n return JSON.parse(\n Buffer.from(publicKey.replace('pk_', ''), 'base64').toString('utf-8'),\n )\n } catch (e) {\n throw new Error('Failed to parse public key')\n }\n}\n","import { getPublicKeyPayload } from '../commons'\n\nexport const getTokenFromUri = (url: string): string | null => {\n return new URL(url).searchParams.get('token')\n}\n\ninterface IFetchUserData {\n user: {\n id: string\n environmentId: string\n externalId: string\n userName: string\n displayName: string\n nickName: string\n profileUrl: string\n title: string\n userType: string\n preferredLanguage: string | null\n locale: string | null\n timezone: string | null\n active: boolean\n provider: string\n lastLogin: string\n createdAt: string\n updatedAt: string\n names: {\n id: string\n userId: string\n formatted: string | null\n familyName: string\n givenName: string\n middleName: string | null\n honorificPrefix: string | null\n honorificSuffix: string | null\n createdAt: string\n updatedAt: string\n }\n addresses: []\n emails: {\n value: string\n primary: boolean\n type: string\n }[]\n phoneNumbers: []\n ims: []\n photos: {\n value: string\n type: string\n }[]\n }\n meta: {\n code: number\n message: string\n }\n}\n\nexport const validatePublicKey = (publicKey: string) => {\n if (!publicKey) {\n throw new Error('Public key is not defined')\n }\n\n if (!publicKey.startsWith('pk_')) {\n throw new Error('Invalid public key')\n }\n}\n\nexport const fetchUserData = async (\n publicKey: string,\n token: string,\n): Promise<IFetchUserData | null> => {\n validatePublicKey(publicKey)\n const publicKeyObj = getPublicKeyPayload(publicKey)\n const userData = await fetch(\n `${publicKeyObj?.identityHost}/oidc/${publicKeyObj?.environmentId}/userinfo`,\n {\n headers: {\n authorization: `Bearer ${token}`,\n },\n },\n )\n\n if (!userData.ok) {\n throw new Error('Failed to fetch user info')\n }\n\n return await userData.json()\n}\n\nexport const browserCookiesOptions = {\n maxAge: 60 * 60 * 24 * 7, // 1 week\n path: '/',\n httpOnly: true,\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSignIn = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useSignIn must be used within AuthdogProvider')\n }\n\n const signIn = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true\n error.value = null\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace('pk_', ''), 'base64').toString('utf-8')\n )\n \n const authUrl = new URL(`${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`)\n authUrl.searchParams.set('client_id', publicKey)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('scope', 'openid profile email')\n authUrl.searchParams.set('redirect_uri', redirectUrl || window.location.origin)\n \n window.location.href = authUrl.toString()\n } catch (err) {\n error.value = err as Error\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n signIn,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSignUp = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useSignUp must be used within AuthdogProvider')\n }\n\n const signUp = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true\n error.value = null\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace('pk_', ''), 'base64').toString('utf-8')\n )\n \n const authUrl = new URL(`${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`)\n authUrl.searchParams.set('client_id', publicKey)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('scope', 'openid profile email')\n authUrl.searchParams.set('redirect_uri', redirectUrl || window.location.origin)\n authUrl.searchParams.set('prompt', 'signup')\n \n window.location.href = authUrl.toString()\n } catch (err) {\n error.value = err as Error\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n signUp,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSignOut = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useSignOut must be used within AuthdogProvider')\n }\n\n const signOut = async () => {\n isLoading.value = true\n error.value = null\n\n try {\n // Clear token from context\n context.setToken(null)\n \n // Clear token from localStorage\n if (typeof window !== 'undefined') {\n localStorage.removeItem('token')\n }\n \n // Redirect to logout endpoint or home page\n if (typeof window !== 'undefined') {\n window.location.href = '/logout'\n }\n } catch (err) {\n error.value = err as Error\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n signOut,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useOrganization = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const organization = ref<any>(null)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useOrganization must be used within AuthdogProvider')\n }\n\n const fetchOrganization = async (organizationId: string) => {\n if (!context.token) {\n return null\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n // This would be implemented based on your organization API\n // For now, returning a placeholder\n const response = await fetch(`/api/organizations/${organizationId}`, {\n headers: {\n 'Authorization': `Bearer ${context.token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch organization')\n }\n\n organization.value = await response.json()\n return organization.value\n } catch (err) {\n error.value = err as Error\n return null\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n organization: computed(() => organization.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganization,\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useOrganizationList = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const organizations = ref<any[]>([])\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useOrganizationList must be used within AuthdogProvider')\n }\n\n const fetchOrganizations = async () => {\n if (!context.token) {\n return []\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n // This would be implemented based on your organizations API\n // For now, returning a placeholder\n const response = await fetch('/api/organizations', {\n headers: {\n 'Authorization': `Bearer ${context.token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch organizations')\n }\n\n const data = await response.json()\n organizations.value = data.organizations || []\n return organizations.value\n } catch (err) {\n error.value = err as Error\n return []\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n organizations: computed(() => organizations.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganizations,\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useAuthz = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const permissions = ref<string[]>([])\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useAuthz must be used within AuthdogProvider')\n }\n\n const fetchPermissions = async () => {\n if (!context.token) {\n return []\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n // This would be implemented based on your authorization API\n // For now, returning a placeholder\n const response = await fetch('/api/permissions', {\n headers: {\n 'Authorization': `Bearer ${context.token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch permissions')\n }\n\n const data = await response.json()\n permissions.value = data.permissions || []\n return permissions.value\n } catch (err) {\n error.value = err as Error\n return []\n } finally {\n isLoading.value = false\n }\n }\n\n const hasPermission = (permission: string) => {\n return permissions.value.includes(permission)\n }\n\n const hasAnyPermission = (permissionList: string[]) => {\n return permissionList.some(permission => permissions.value.includes(permission))\n }\n\n const hasAllPermissions = (permissionList: string[]) => {\n return permissionList.every(permission => permissions.value.includes(permission))\n }\n\n return {\n permissions: computed(() => permissions.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchPermissions,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n }\n}\n"],"mappings":"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","names":["index_exports","__export","useAuthz","useOrganization","useOrganizationList","useSession","useSignIn","useSignOut","useSignUp","useUser","__toCommonJS","import_vue","import_vue","AUTHDOG_CONTEXT_KEY","AuthdogProvider","_","slots","isLoading","token","setToken","newToken","url","urlToken","existingToken","context","_a","useSession","context","AUTHDOG_CONTEXT_KEY","import_vue","getPublicKeyPayload","publicKey","validatePublicKey","publicKey","fetchUserData","token","publicKeyObj","getPublicKeyPayload","userData","browserCookiesOptions","useUser","context","AUTHDOG_CONTEXT_KEY","user","isLoading","error","fetchUser","publicKey","validatePublicKey","userData","fetchUserData","err","isAuthenticated","import_vue","useSignIn","context","AUTHDOG_CONTEXT_KEY","isLoading","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","import_vue","useSignUp","context","AUTHDOG_CONTEXT_KEY","isLoading","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","import_vue","useSignOut","context","AUTHDOG_CONTEXT_KEY","isLoading","error","err","import_vue","useOrganization","context","AUTHDOG_CONTEXT_KEY","organization","isLoading","error","fetchOrganization","organizationId","response","err","import_vue","useOrganizationList","context","AUTHDOG_CONTEXT_KEY","organizations","isLoading","error","fetchOrganizations","response","data","err","import_vue","useAuthz","context","AUTHDOG_CONTEXT_KEY","permissions","isLoading","error","fetchPermissions","response","data","err","hasPermission","permission","hasAnyPermission","permissionList","hasAllPermissions"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client/provider.ts","../src/commons.ts","../src/client/session.ts","../src/composables/use-session.ts","../src/composables/use-user.ts","../src/composables/use-signin.ts","../src/composables/use-signup.ts","../src/composables/use-signout.ts","../src/composables/use-organization.ts","../src/composables/use-organization-list.ts","../src/composables/use-authz.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./composables\";\n","import {\n defineComponent,\n onMounted,\n ref,\n provide,\n type InjectionKey,\n} from \"vue\";\n\nexport interface AuthdogContext {\n readonly isLoading: boolean;\n readonly token: string | null;\n setToken: (token: string | null) => void;\n}\n\nexport const AUTHDOG_CONTEXT_KEY: InjectionKey<AuthdogContext> =\n Symbol(\"authdog\");\n\n/** Shared localStorage key for the persisted token. */\nexport const TOKEN_STORAGE_KEY = \"token\";\n\n/** JWT shape: three base64url segments separated by dots. */\nconst JWT_PATTERN = /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n\nexport const AuthdogProvider = defineComponent({\n name: \"AuthdogProvider\",\n setup(_, { slots }) {\n const isLoading = ref(true);\n const token = ref<string | null>(null);\n\n const setToken = (newToken: string | null) => {\n token.value = newToken;\n };\n\n onMounted(() => {\n // Check if we're in the browser\n if (typeof window !== \"undefined\") {\n // Check if there's a token in the URL\n const url = new URL(window.location.href);\n const urlToken = url.searchParams.get(\"token\");\n\n if (urlToken) {\n // Remove token from URL without triggering a page reload,\n // regardless of whether the token is valid.\n url.searchParams.delete(\"token\");\n window.history.replaceState({}, document.title, url.toString());\n\n // Only persist values that look like a JWT to avoid storing\n // arbitrary attacker-supplied data.\n if (JWT_PATTERN.test(urlToken)) {\n localStorage.setItem(TOKEN_STORAGE_KEY, urlToken);\n setToken(urlToken);\n\n // Force a reload to ensure the server processes the token\n window.location.reload();\n return;\n }\n }\n\n // Check for existing token in localStorage\n const existingToken = localStorage.getItem(TOKEN_STORAGE_KEY);\n if (existingToken) {\n setToken(existingToken);\n }\n\n // If no token, we're done loading\n isLoading.value = false;\n } else {\n // If we're on the server, don't show loading state\n isLoading.value = false;\n }\n });\n\n // Expose reactive state through getters so consumers always read the\n // live ref values rather than a frozen snapshot taken at setup time.\n const context: AuthdogContext = {\n get isLoading() {\n return isLoading.value;\n },\n get token() {\n return token.value;\n },\n setToken,\n };\n\n provide(AUTHDOG_CONTEXT_KEY, context);\n\n return () => slots.default?.();\n },\n});\n","import {\n validateAndParsePublicKey,\n type PublicKeyPayload,\n} from \"@authdog/node-commons\";\n\nexport type { PublicKeyPayload };\n\n/**\n * Decodes and validates an Authdog public key. Delegates to the hardened\n * shared parser in @authdog/node-commons, which validates the payload and\n * enforces a trusted identity-host allowlist (SSRF / token-exfiltration\n * protection) rather than blindly decoding base64/JSON.\n */\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n return validateAndParsePublicKey(publicKey);\n};\n","import { getPublicKeyPayload } from \"../commons\";\n\nexport const getTokenFromUri = (url: string): string | null => {\n return new URL(url).searchParams.get(\"token\");\n};\n\ninterface IFetchUserData {\n user: {\n id: string;\n environmentId: string;\n externalId: string;\n userName: string;\n displayName: string;\n nickName: string;\n profileUrl: string;\n title: string;\n userType: string;\n preferredLanguage: string | null;\n locale: string | null;\n timezone: string | null;\n active: boolean;\n provider: string;\n lastLogin: string;\n createdAt: string;\n updatedAt: string;\n names: {\n id: string;\n userId: string;\n formatted: string | null;\n familyName: string;\n givenName: string;\n middleName: string | null;\n honorificPrefix: string | null;\n honorificSuffix: string | null;\n createdAt: string;\n updatedAt: string;\n };\n addresses: [];\n emails: {\n value: string;\n primary: boolean;\n type: string;\n }[];\n phoneNumbers: [];\n ims: [];\n photos: {\n value: string;\n type: string;\n }[];\n };\n meta: {\n code: number;\n message: string;\n };\n}\n\nexport const validatePublicKey = (publicKey: string) => {\n if (!publicKey) {\n throw new Error(\"Public key is not defined\");\n }\n\n if (!publicKey.startsWith(\"pk_\")) {\n throw new Error(\"Invalid public key\");\n }\n};\n\nexport const fetchUserData = async (\n publicKey: string,\n token: string,\n): Promise<IFetchUserData | null> => {\n validatePublicKey(publicKey);\n const publicKeyObj = getPublicKeyPayload(publicKey);\n const userData = await fetch(\n `${publicKeyObj?.identityHost}/oidc/${publicKeyObj?.environmentId}/userinfo`,\n {\n headers: {\n authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!userData.ok) {\n throw new Error(\"Failed to fetch user info\");\n }\n\n return await userData.json();\n};\n\n// NOTE: These options are for cookies usable from the browser. `httpOnly` is\n// intentionally omitted — it is a no-op (and misleading) for client-set\n// cookies since JS cannot set HttpOnly. Session cookies should be set\n// server-side with HttpOnly; do not set session cookies from client JS.\nexport const browserCookiesOptions = {\n maxAge: 60 * 60 * 24 * 7, // 1 week\n path: \"/\",\n secure: true,\n sameSite: \"lax\" as const,\n};\n","import { computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useSession = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n\n if (!context) {\n throw new Error(\"useSession must be used within AuthdogProvider\");\n }\n\n const session = computed(() => ({\n token: context.token,\n isAuthenticated: !!context.token,\n }));\n\n return {\n session,\n isLoading: computed(() => context.isLoading),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\nimport { fetchUserData, validatePublicKey } from \"../client/session\";\n\nexport const useUser = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const user = ref<any>(null);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useUser must be used within AuthdogProvider\");\n }\n\n const fetchUser = async (publicKey: string) => {\n if (!context.token) {\n return null;\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n validatePublicKey(publicKey);\n const userData = await fetchUserData(publicKey, context.token);\n user.value = userData?.user || null;\n return userData?.user || null;\n } catch (err) {\n error.value = err as Error;\n return null;\n } finally {\n isLoading.value = false;\n }\n };\n\n const isAuthenticated = computed(() => !!context.token && !!user.value);\n\n return {\n user: computed(() => user.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n isAuthenticated,\n fetchUser,\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useSignIn = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useSignIn must be used within AuthdogProvider\");\n }\n\n const signIn = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true;\n error.value = null;\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace(\"pk_\", \"\"), \"base64\").toString(\"utf-8\"),\n );\n\n const authUrl = new URL(\n `${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`,\n );\n authUrl.searchParams.set(\"client_id\", publicKey);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"scope\", \"openid profile email\");\n authUrl.searchParams.set(\n \"redirect_uri\",\n redirectUrl || window.location.origin,\n );\n\n window.location.href = authUrl.toString();\n } catch (err) {\n error.value = err as Error;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n signIn,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useSignUp = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useSignUp must be used within AuthdogProvider\");\n }\n\n const signUp = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true;\n error.value = null;\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace(\"pk_\", \"\"), \"base64\").toString(\"utf-8\"),\n );\n\n const authUrl = new URL(\n `${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`,\n );\n authUrl.searchParams.set(\"client_id\", publicKey);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"scope\", \"openid profile email\");\n authUrl.searchParams.set(\n \"redirect_uri\",\n redirectUrl || window.location.origin,\n );\n authUrl.searchParams.set(\"prompt\", \"signup\");\n\n window.location.href = authUrl.toString();\n } catch (err) {\n error.value = err as Error;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n signUp,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport {\n AUTHDOG_CONTEXT_KEY,\n TOKEN_STORAGE_KEY,\n type AuthdogContext,\n} from \"../client/provider\";\n\nexport const useSignOut = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useSignOut must be used within AuthdogProvider\");\n }\n\n const signOut = async () => {\n isLoading.value = true;\n error.value = null;\n\n try {\n // Clear token from context\n context.setToken(null);\n\n // Clear token from localStorage\n if (typeof window !== \"undefined\") {\n localStorage.removeItem(TOKEN_STORAGE_KEY);\n }\n\n // Redirect to logout endpoint or home page\n if (typeof window !== \"undefined\") {\n window.location.href = \"/logout\";\n }\n } catch (err) {\n error.value = err as Error;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n signOut,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useOrganization = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const organization = ref<any>(null);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useOrganization must be used within AuthdogProvider\");\n }\n\n const fetchOrganization = async (organizationId: string) => {\n if (!context.token) {\n return null;\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n // This would be implemented based on your organization API\n // For now, returning a placeholder\n const response = await fetch(`/api/organizations/${organizationId}`, {\n headers: {\n Authorization: `Bearer ${context.token}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(\"Failed to fetch organization\");\n }\n\n organization.value = await response.json();\n return organization.value;\n } catch (err) {\n error.value = err as Error;\n return null;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n organization: computed(() => organization.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganization,\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useOrganizationList = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const organizations = ref<any[]>([]);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useOrganizationList must be used within AuthdogProvider\");\n }\n\n const fetchOrganizations = async () => {\n if (!context.token) {\n return [];\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n // This would be implemented based on your organizations API\n // For now, returning a placeholder\n const response = await fetch(\"/api/organizations\", {\n headers: {\n Authorization: `Bearer ${context.token}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(\"Failed to fetch organizations\");\n }\n\n const data = await response.json();\n organizations.value = data.organizations || [];\n return organizations.value;\n } catch (err) {\n error.value = err as Error;\n return [];\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n organizations: computed(() => organizations.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganizations,\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\n/**\n * ⚠️ PRESENTATIONAL ONLY — NOT A SECURITY BOUNDARY.\n *\n * This composable fetches a permission list to drive UI affordances (showing\n * or hiding buttons, menu items, etc.). It runs entirely in the browser and\n * is therefore trivially bypassable by any client. It MUST NOT be used to\n * gate access to data or actions.\n *\n * Every protected operation MUST be independently enforced server-side.\n */\n\nexport interface UseAuthzOptions {\n /**\n * URL of the endpoint that returns the current user's permissions.\n * Defaults to \"/api/permissions\". This endpoint is informational only;\n * authorization must still be enforced on every protected server endpoint.\n */\n permissionsUrl?: string;\n}\n\nexport const useAuthz = (options: UseAuthzOptions = {}) => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const permissions = ref<string[]>([]);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useAuthz must be used within AuthdogProvider\");\n }\n\n const permissionsUrl = options.permissionsUrl ?? \"/api/permissions\";\n\n const fetchPermissions = async () => {\n if (!context.token) {\n return [];\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n const response = await fetch(permissionsUrl, {\n headers: {\n Authorization: `Bearer ${context.token}`,\n },\n });\n\n // Distinguish an authentication failure from an empty permission list.\n // A 401 means the session is invalid/expired and should surface as an\n // error rather than being silently coerced into \"no permissions\".\n if (response.status === 401) {\n permissions.value = [];\n throw new Error(\"Unauthorized: authentication failed (401)\");\n }\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch permissions (status ${response.status})`,\n );\n }\n\n const data = await response.json();\n permissions.value = data.permissions || [];\n return permissions.value;\n } catch (err) {\n error.value = err as Error;\n return [];\n } finally {\n isLoading.value = false;\n }\n };\n\n /**\n * ⚠️ PRESENTATIONAL ONLY. Returns whether the locally-cached permission\n * list contains `permission`. This is for UI hints only and is bypassable;\n * never rely on it as an access-control check. Enforce permissions\n * server-side for every protected operation.\n */\n const hasPermission = (permission: string) => {\n return permissions.value.includes(permission);\n };\n\n const hasAnyPermission = (permissionList: string[]) => {\n return permissionList.some((permission) =>\n permissions.value.includes(permission),\n );\n };\n\n const hasAllPermissions = (permissionList: string[]) => {\n return permissionList.every((permission) =>\n permissions.value.includes(permission),\n );\n };\n\n return {\n permissions: computed(() => permissions.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchPermissions,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n };\n};\n"],"mappings":"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","names":["index_exports","__export","AuthdogProvider","browserCookiesOptions","fetchUserData","getTokenFromUri","useAuthz","useOrganization","useOrganizationList","useSession","useSignIn","useSignOut","useSignUp","useUser","validatePublicKey","__toCommonJS","import_vue","AUTHDOG_CONTEXT_KEY","TOKEN_STORAGE_KEY","JWT_PATTERN","AuthdogProvider","_","slots","isLoading","token","setToken","newToken","url","urlToken","existingToken","_a","import_node_commons","getPublicKeyPayload","publicKey","getTokenFromUri","url","validatePublicKey","publicKey","fetchUserData","token","publicKeyObj","getPublicKeyPayload","userData","browserCookiesOptions","import_vue","useSession","context","AUTHDOG_CONTEXT_KEY","import_vue","useUser","context","AUTHDOG_CONTEXT_KEY","user","isLoading","error","fetchUser","publicKey","validatePublicKey","userData","fetchUserData","err","isAuthenticated","import_vue","useSignIn","context","AUTHDOG_CONTEXT_KEY","isLoading","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","import_vue","useSignUp","context","AUTHDOG_CONTEXT_KEY","isLoading","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","import_vue","useSignOut","context","AUTHDOG_CONTEXT_KEY","isLoading","error","TOKEN_STORAGE_KEY","err","import_vue","useOrganization","context","AUTHDOG_CONTEXT_KEY","organization","isLoading","error","fetchOrganization","organizationId","response","err","import_vue","useOrganizationList","context","AUTHDOG_CONTEXT_KEY","organizations","isLoading","error","fetchOrganizations","response","data","err","import_vue","useAuthz","options","context","AUTHDOG_CONTEXT_KEY","permissions","isLoading","error","permissionsUrl","fetchPermissions","response","data","err","hasPermission","permission","hasAnyPermission","permissionList","hasAllPermissions"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{computed as S,inject as I}from"vue";import{defineComponent as _,onMounted as L,ref as x,provide as z}from"vue";var a=Symbol("authdog"),V=_({name:"AuthdogProvider",setup(e,{slots:t}){let r=x(!0),i=x(null),s=o=>{i.value=o};L(()=>{if(typeof window<"u"){let o=new URL(window.location.href),n=o.searchParams.get("token");if(n){o.searchParams.delete("token"),window.history.replaceState({},document.title,o.toString()),localStorage.setItem("token",n),s(n),window.location.reload();return}let l=localStorage.getItem("token");l&&s(l),r.value=!1}else r.value=!1});let u={isLoading:r.value,token:i.value,setToken:s};return z(a,u),()=>{var o;return(o=t.default)==null?void 0:o.call(t)}}});var b=()=>{let e=I(a);if(!e)throw new Error("useSession must be used within AuthdogProvider");return{session:S(()=>({token:e.token,isAuthenticated:!!e.token})).value,isLoading:e.isLoading}};import{ref as f,computed as d,inject as N}from"vue";var A=e=>{if(!e)throw new Error("Public key is not defined");if(!e.startsWith("pk_"))throw new Error("Invalid public key");try{return JSON.parse(Buffer.from(e.replace("pk_",""),"base64").toString("utf-8"))}catch{throw new Error("Failed to parse public key")}};var g=e=>{if(!e)throw new Error("Public key is not defined");if(!e.startsWith("pk_"))throw new Error("Invalid public key")},E=async(e,t)=>{g(e);let r=A(e),i=await fetch(`${r==null?void 0:r.identityHost}/oidc/${r==null?void 0:r.environmentId}/userinfo`,{headers:{authorization:`Bearer ${t}`}});if(!i.ok)throw new Error("Failed to fetch user info");return await i.json()},ie={maxAge:60*60*24*7,path:"/",httpOnly:!0};var j=()=>{let e=N(a),t=f(null),r=f(!1),i=f(null);if(!e)throw new Error("useUser must be used within AuthdogProvider");let s=async o=>{if(!e.token)return null;r.value=!0,i.value=null;try{g(o);let n=await E(o,e.token);return t.value=(n==null?void 0:n.user)||null,(n==null?void 0:n.user)||null}catch(n){return i.value=n,null}finally{r.value=!1}},u=d(()=>!!e.token&&!!t.value);return{user:d(()=>t.value),isLoading:d(()=>r.value),error:d(()=>i.value),isAuthenticated:u,fetchUser:s}};import{ref as k,computed as P,inject as H}from"vue";var D=()=>{let e=H(a),t=k(!1),r=k(null);if(!e)throw new Error("useSignIn must be used within AuthdogProvider");return{signIn:async(s,u)=>{t.value=!0,r.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),n=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);n.searchParams.set("client_id",s),n.searchParams.set("response_type","code"),n.searchParams.set("scope","openid profile email"),n.searchParams.set("redirect_uri",u||window.location.origin),window.location.href=n.toString()}catch(o){r.value=o}finally{t.value=!1}},isLoading:P(()=>t.value),error:P(()=>r.value)}};import{ref as O,computed as T,inject as $}from"vue";var G=()=>{let e=$(a),t=O(!1),r=O(null);if(!e)throw new Error("useSignUp must be used within AuthdogProvider");return{signUp:async(s,u)=>{t.value=!0,r.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),n=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);n.searchParams.set("client_id",s),n.searchParams.set("response_type","code"),n.searchParams.set("scope","openid profile email"),n.searchParams.set("redirect_uri",u||window.location.origin),n.searchParams.set("prompt","signup"),window.location.href=n.toString()}catch(o){r.value=o}finally{t.value=!1}},isLoading:T(()=>t.value),error:T(()=>r.value)}};import{ref as C,computed as U,inject as K}from"vue";var X=()=>{let e=K(a),t=C(!1),r=C(null);if(!e)throw new Error("useSignOut must be used within AuthdogProvider");return{signOut:async()=>{t.value=!0,r.value=null;try{e.setToken(null),typeof window<"u"&&localStorage.removeItem("token"),typeof window<"u"&&(window.location.href="/logout")}catch(s){r.value=s}finally{t.value=!1}},isLoading:U(()=>t.value),error:U(()=>r.value)}};import{ref as m,computed as h,inject as Y}from"vue";var F=()=>{let e=Y(a),t=m(null),r=m(!1),i=m(null);if(!e)throw new Error("useOrganization must be used within AuthdogProvider");let s=async u=>{if(!e.token)return null;r.value=!0,i.value=null;try{let o=await fetch(`/api/organizations/${u}`,{headers:{Authorization:`Bearer ${e.token}`}});if(!o.ok)throw new Error("Failed to fetch organization");return t.value=await o.json(),t.value}catch(o){return i.value=o,null}finally{r.value=!1}};return{organization:h(()=>t.value),isLoading:h(()=>r.value),error:h(()=>i.value),fetchOrganization:s}};import{ref as p,computed as v,inject as B}from"vue";var R=()=>{let e=B(a),t=p([]),r=p(!1),i=p(null);if(!e)throw new Error("useOrganizationList must be used within AuthdogProvider");let s=async()=>{if(!e.token)return[];r.value=!0,i.value=null;try{let u=await fetch("/api/organizations",{headers:{Authorization:`Bearer ${e.token}`}});if(!u.ok)throw new Error("Failed to fetch organizations");let o=await u.json();return t.value=o.organizations||[],t.value}catch(u){return i.value=u,[]}finally{r.value=!1}};return{organizations:v(()=>t.value),isLoading:v(()=>r.value),error:v(()=>i.value),fetchOrganizations:s}};import{ref as w,computed as y,inject as J}from"vue";var W=()=>{let e=J(a),t=w([]),r=w(!1),i=w(null);if(!e)throw new Error("useAuthz must be used within AuthdogProvider");let s=async()=>{if(!e.token)return[];r.value=!0,i.value=null;try{let l=await fetch("/api/permissions",{headers:{Authorization:`Bearer ${e.token}`}});if(!l.ok)throw new Error("Failed to fetch permissions");let c=await l.json();return t.value=c.permissions||[],t.value}catch(l){return i.value=l,[]}finally{r.value=!1}},u=l=>t.value.includes(l),o=l=>l.some(c=>t.value.includes(c)),n=l=>l.every(c=>t.value.includes(c));return{permissions:y(()=>t.value),isLoading:y(()=>r.value),error:y(()=>i.value),fetchPermissions:s,hasPermission:u,hasAnyPermission:o,hasAllPermissions:n}};export{W as useAuthz,F as useOrganization,R as useOrganizationList,b as useSession,D as useSignIn,X as useSignOut,G as useSignUp,j as useUser};
1
+ import{defineComponent as b,onMounted as N,ref as P,provide as I}from"vue";var a=Symbol("authdog"),g="token",K=/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,j=b({name:"AuthdogProvider",setup(t,{slots:r}){let e=P(!0),i=P(null),s=o=>{i.value=o};return N(()=>{if(typeof window<"u"){let o=new URL(window.location.href),n=o.searchParams.get("token");if(n&&(o.searchParams.delete("token"),window.history.replaceState({},document.title,o.toString()),K.test(n))){localStorage.setItem(g,n),s(n),window.location.reload();return}let d=localStorage.getItem(g);d&&s(d),e.value=!1}else e.value=!1}),I(a,{get isLoading(){return e.value},get token(){return i.value},setToken:s}),()=>{var o;return(o=r.default)==null?void 0:o.call(r)}}});import{validateAndParsePublicKey as $}from"@authdog/node-commons";var T=t=>$(t);var D=t=>new URL(t).searchParams.get("token"),f=t=>{if(!t)throw new Error("Public key is not defined");if(!t.startsWith("pk_"))throw new Error("Invalid public key")},p=async(t,r)=>{f(t);let e=T(t),i=await fetch(`${e==null?void 0:e.identityHost}/oidc/${e==null?void 0:e.environmentId}/userinfo`,{headers:{authorization:`Bearer ${r}`}});if(!i.ok)throw new Error("Failed to fetch user info");return await i.json()},H={maxAge:3600*24*7,path:"/",secure:!0,sameSite:"lax"};import{computed as O,inject as G}from"vue";var Y=()=>{let t=G(a);if(!t)throw new Error("useSession must be used within AuthdogProvider");return{session:O(()=>({token:t.token,isAuthenticated:!!t.token})),isLoading:O(()=>t.isLoading)}};import{ref as h,computed as m,inject as X}from"vue";var F=()=>{let t=X(a),r=h(null),e=h(!1),i=h(null);if(!t)throw new Error("useUser must be used within AuthdogProvider");let s=async o=>{if(!t.token)return null;e.value=!0,i.value=null;try{f(o);let n=await p(o,t.token);return r.value=(n==null?void 0:n.user)||null,(n==null?void 0:n.user)||null}catch(n){return i.value=n,null}finally{e.value=!1}},u=m(()=>!!t.token&&!!r.value);return{user:m(()=>r.value),isLoading:m(()=>e.value),error:m(()=>i.value),isAuthenticated:u,fetchUser:s}};import{ref as k,computed as U,inject as R}from"vue";var B=()=>{let t=R(a),r=k(!1),e=k(null);if(!t)throw new Error("useSignIn must be used within AuthdogProvider");return{signIn:async(s,u)=>{r.value=!0,e.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),n=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);n.searchParams.set("client_id",s),n.searchParams.set("response_type","code"),n.searchParams.set("scope","openid profile email"),n.searchParams.set("redirect_uri",u||window.location.origin),window.location.href=n.toString()}catch(o){e.value=o}finally{r.value=!1}},isLoading:U(()=>r.value),error:U(()=>e.value)}};import{ref as _,computed as z,inject as J}from"vue";var Z=()=>{let t=J(a),r=_(!1),e=_(null);if(!t)throw new Error("useSignUp must be used within AuthdogProvider");return{signUp:async(s,u)=>{r.value=!0,e.value=null;try{let o=JSON.parse(Buffer.from(s.replace("pk_",""),"base64").toString("utf-8")),n=new URL(`${o.identityHost}/oidc/${o.environmentId}/authorize`);n.searchParams.set("client_id",s),n.searchParams.set("response_type","code"),n.searchParams.set("scope","openid profile email"),n.searchParams.set("redirect_uri",u||window.location.origin),n.searchParams.set("prompt","signup"),window.location.href=n.toString()}catch(o){e.value=o}finally{r.value=!1}},isLoading:z(()=>r.value),error:z(()=>e.value)}};import{ref as C,computed as L,inject as W}from"vue";var M=()=>{let t=W(a),r=C(!1),e=C(null);if(!t)throw new Error("useSignOut must be used within AuthdogProvider");return{signOut:async()=>{r.value=!0,e.value=null;try{t.setToken(null),typeof window<"u"&&localStorage.removeItem(g),typeof window<"u"&&(window.location.href="/logout")}catch(s){e.value=s}finally{r.value=!1}},isLoading:L(()=>r.value),error:L(()=>e.value)}};import{ref as v,computed as w,inject as q}from"vue";var Q=()=>{let t=q(a),r=v(null),e=v(!1),i=v(null);if(!t)throw new Error("useOrganization must be used within AuthdogProvider");let s=async u=>{if(!t.token)return null;e.value=!0,i.value=null;try{let o=await fetch(`/api/organizations/${u}`,{headers:{Authorization:`Bearer ${t.token}`}});if(!o.ok)throw new Error("Failed to fetch organization");return r.value=await o.json(),r.value}catch(o){return i.value=o,null}finally{e.value=!1}};return{organization:w(()=>r.value),isLoading:w(()=>e.value),error:w(()=>i.value),fetchOrganization:s}};import{ref as y,computed as x,inject as V}from"vue";var ee=()=>{let t=V(a),r=y([]),e=y(!1),i=y(null);if(!t)throw new Error("useOrganizationList must be used within AuthdogProvider");let s=async()=>{if(!t.token)return[];e.value=!0,i.value=null;try{let u=await fetch("/api/organizations",{headers:{Authorization:`Bearer ${t.token}`}});if(!u.ok)throw new Error("Failed to fetch organizations");let o=await u.json();return r.value=o.organizations||[],r.value}catch(u){return i.value=u,[]}finally{e.value=!1}};return{organizations:x(()=>r.value),isLoading:x(()=>e.value),error:x(()=>i.value),fetchOrganizations:s}};import{ref as A,computed as E,inject as te}from"vue";var re=(t={})=>{let r=te(a),e=A([]),i=A(!1),s=A(null);if(!r)throw new Error("useAuthz must be used within AuthdogProvider");let u=t.permissionsUrl??"/api/permissions",o=async()=>{if(!r.token)return[];i.value=!0,s.value=null;try{let l=await fetch(u,{headers:{Authorization:`Bearer ${r.token}`}});if(l.status===401)throw e.value=[],new Error("Unauthorized: authentication failed (401)");if(!l.ok)throw new Error(`Failed to fetch permissions (status ${l.status})`);let c=await l.json();return e.value=c.permissions||[],e.value}catch(l){return s.value=l,[]}finally{i.value=!1}},n=l=>e.value.includes(l),d=l=>l.some(c=>e.value.includes(c)),S=l=>l.every(c=>e.value.includes(c));return{permissions:E(()=>e.value),isLoading:E(()=>i.value),error:E(()=>s.value),fetchPermissions:o,hasPermission:n,hasAnyPermission:d,hasAllPermissions:S}};export{j as AuthdogProvider,H as browserCookiesOptions,p as fetchUserData,D as getTokenFromUri,re as useAuthz,Q as useOrganization,ee as useOrganizationList,Y as useSession,B as useSignIn,M as useSignOut,Z as useSignUp,F as useUser,f as validatePublicKey};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/composables/use-session.ts","../src/client/provider.ts","../src/composables/use-user.ts","../src/commons.ts","../src/client/session.ts","../src/composables/use-signin.ts","../src/composables/use-signup.ts","../src/composables/use-signout.ts","../src/composables/use-organization.ts","../src/composables/use-organization-list.ts","../src/composables/use-authz.ts"],"sourcesContent":["import { computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSession = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n\n if (!context) {\n throw new Error('useSession must be used within AuthdogProvider')\n }\n\n const session = computed(() => ({\n token: context.token,\n isAuthenticated: !!context.token,\n }))\n\n return {\n session: session.value,\n isLoading: context.isLoading,\n }\n}\n","import { defineComponent, onMounted, ref, provide, inject, type InjectionKey } from 'vue'\n\nexport interface AuthdogContext {\n isLoading: boolean\n token: string | null\n setToken: (token: string | null) => void\n}\n\nexport const AUTHDOG_CONTEXT_KEY: InjectionKey<AuthdogContext> = Symbol('authdog')\n\nexport const AuthdogProvider = defineComponent({\n name: 'AuthdogProvider',\n setup(_, { slots }) {\n const isLoading = ref(true)\n const token = ref<string | null>(null)\n\n const setToken = (newToken: string | null) => {\n token.value = newToken\n }\n\n onMounted(() => {\n // Check if we're in the browser\n if (typeof window !== 'undefined') {\n // Check if there's a token in the URL\n const url = new URL(window.location.href)\n const urlToken = url.searchParams.get('token')\n\n if (urlToken) {\n // Remove token from URL without triggering a page reload\n url.searchParams.delete('token')\n window.history.replaceState({}, document.title, url.toString())\n \n // Store token and reload to ensure server processes it\n localStorage.setItem('token', urlToken)\n setToken(urlToken)\n \n // Force a reload to ensure the server processes the token\n window.location.reload()\n return\n }\n\n // Check for existing token in localStorage\n const existingToken = localStorage.getItem('token')\n if (existingToken) {\n setToken(existingToken)\n }\n\n // If no token, we're done loading\n isLoading.value = false\n } else {\n // If we're on the server, don't show loading state\n isLoading.value = false\n }\n })\n\n const context: AuthdogContext = {\n isLoading: isLoading.value,\n token: token.value,\n setToken\n }\n\n provide(AUTHDOG_CONTEXT_KEY, context)\n\n return () => slots.default?.()\n }\n})\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\nimport { fetchUserData, validatePublicKey } from '../client/session'\n\nexport const useUser = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const user = ref<any>(null)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useUser must be used within AuthdogProvider')\n }\n\n const fetchUser = async (publicKey: string) => {\n if (!context.token) {\n return null\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n validatePublicKey(publicKey)\n const userData = await fetchUserData(publicKey, context.token)\n user.value = userData?.user || null\n return userData?.user || null\n } catch (err) {\n error.value = err as Error\n return null\n } finally {\n isLoading.value = false\n }\n }\n\n const isAuthenticated = computed(() => !!context.token && !!user.value)\n\n return {\n user: computed(() => user.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n isAuthenticated,\n fetchUser,\n }\n}\n","export interface PublicKeyPayload {\n environmentId: string\n identityHost: string\n}\n\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n if (!publicKey) {\n throw new Error('Public key is not defined')\n }\n\n if (!publicKey.startsWith('pk_')) {\n throw new Error('Invalid public key')\n }\n\n try {\n return JSON.parse(\n Buffer.from(publicKey.replace('pk_', ''), 'base64').toString('utf-8'),\n )\n } catch (e) {\n throw new Error('Failed to parse public key')\n }\n}\n","import { getPublicKeyPayload } from '../commons'\n\nexport const getTokenFromUri = (url: string): string | null => {\n return new URL(url).searchParams.get('token')\n}\n\ninterface IFetchUserData {\n user: {\n id: string\n environmentId: string\n externalId: string\n userName: string\n displayName: string\n nickName: string\n profileUrl: string\n title: string\n userType: string\n preferredLanguage: string | null\n locale: string | null\n timezone: string | null\n active: boolean\n provider: string\n lastLogin: string\n createdAt: string\n updatedAt: string\n names: {\n id: string\n userId: string\n formatted: string | null\n familyName: string\n givenName: string\n middleName: string | null\n honorificPrefix: string | null\n honorificSuffix: string | null\n createdAt: string\n updatedAt: string\n }\n addresses: []\n emails: {\n value: string\n primary: boolean\n type: string\n }[]\n phoneNumbers: []\n ims: []\n photos: {\n value: string\n type: string\n }[]\n }\n meta: {\n code: number\n message: string\n }\n}\n\nexport const validatePublicKey = (publicKey: string) => {\n if (!publicKey) {\n throw new Error('Public key is not defined')\n }\n\n if (!publicKey.startsWith('pk_')) {\n throw new Error('Invalid public key')\n }\n}\n\nexport const fetchUserData = async (\n publicKey: string,\n token: string,\n): Promise<IFetchUserData | null> => {\n validatePublicKey(publicKey)\n const publicKeyObj = getPublicKeyPayload(publicKey)\n const userData = await fetch(\n `${publicKeyObj?.identityHost}/oidc/${publicKeyObj?.environmentId}/userinfo`,\n {\n headers: {\n authorization: `Bearer ${token}`,\n },\n },\n )\n\n if (!userData.ok) {\n throw new Error('Failed to fetch user info')\n }\n\n return await userData.json()\n}\n\nexport const browserCookiesOptions = {\n maxAge: 60 * 60 * 24 * 7, // 1 week\n path: '/',\n httpOnly: true,\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSignIn = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useSignIn must be used within AuthdogProvider')\n }\n\n const signIn = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true\n error.value = null\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace('pk_', ''), 'base64').toString('utf-8')\n )\n \n const authUrl = new URL(`${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`)\n authUrl.searchParams.set('client_id', publicKey)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('scope', 'openid profile email')\n authUrl.searchParams.set('redirect_uri', redirectUrl || window.location.origin)\n \n window.location.href = authUrl.toString()\n } catch (err) {\n error.value = err as Error\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n signIn,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSignUp = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useSignUp must be used within AuthdogProvider')\n }\n\n const signUp = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true\n error.value = null\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace('pk_', ''), 'base64').toString('utf-8')\n )\n \n const authUrl = new URL(`${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`)\n authUrl.searchParams.set('client_id', publicKey)\n authUrl.searchParams.set('response_type', 'code')\n authUrl.searchParams.set('scope', 'openid profile email')\n authUrl.searchParams.set('redirect_uri', redirectUrl || window.location.origin)\n authUrl.searchParams.set('prompt', 'signup')\n \n window.location.href = authUrl.toString()\n } catch (err) {\n error.value = err as Error\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n signUp,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useSignOut = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useSignOut must be used within AuthdogProvider')\n }\n\n const signOut = async () => {\n isLoading.value = true\n error.value = null\n\n try {\n // Clear token from context\n context.setToken(null)\n \n // Clear token from localStorage\n if (typeof window !== 'undefined') {\n localStorage.removeItem('token')\n }\n \n // Redirect to logout endpoint or home page\n if (typeof window !== 'undefined') {\n window.location.href = '/logout'\n }\n } catch (err) {\n error.value = err as Error\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n signOut,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useOrganization = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const organization = ref<any>(null)\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useOrganization must be used within AuthdogProvider')\n }\n\n const fetchOrganization = async (organizationId: string) => {\n if (!context.token) {\n return null\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n // This would be implemented based on your organization API\n // For now, returning a placeholder\n const response = await fetch(`/api/organizations/${organizationId}`, {\n headers: {\n 'Authorization': `Bearer ${context.token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch organization')\n }\n\n organization.value = await response.json()\n return organization.value\n } catch (err) {\n error.value = err as Error\n return null\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n organization: computed(() => organization.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganization,\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useOrganizationList = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const organizations = ref<any[]>([])\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useOrganizationList must be used within AuthdogProvider')\n }\n\n const fetchOrganizations = async () => {\n if (!context.token) {\n return []\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n // This would be implemented based on your organizations API\n // For now, returning a placeholder\n const response = await fetch('/api/organizations', {\n headers: {\n 'Authorization': `Bearer ${context.token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch organizations')\n }\n\n const data = await response.json()\n organizations.value = data.organizations || []\n return organizations.value\n } catch (err) {\n error.value = err as Error\n return []\n } finally {\n isLoading.value = false\n }\n }\n\n return {\n organizations: computed(() => organizations.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganizations,\n }\n}\n","import { ref, computed, inject } from 'vue'\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from '../client/provider'\n\nexport const useAuthz = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY)\n const permissions = ref<string[]>([])\n const isLoading = ref(false)\n const error = ref<Error | null>(null)\n\n if (!context) {\n throw new Error('useAuthz must be used within AuthdogProvider')\n }\n\n const fetchPermissions = async () => {\n if (!context.token) {\n return []\n }\n\n isLoading.value = true\n error.value = null\n\n try {\n // This would be implemented based on your authorization API\n // For now, returning a placeholder\n const response = await fetch('/api/permissions', {\n headers: {\n 'Authorization': `Bearer ${context.token}`,\n },\n })\n\n if (!response.ok) {\n throw new Error('Failed to fetch permissions')\n }\n\n const data = await response.json()\n permissions.value = data.permissions || []\n return permissions.value\n } catch (err) {\n error.value = err as Error\n return []\n } finally {\n isLoading.value = false\n }\n }\n\n const hasPermission = (permission: string) => {\n return permissions.value.includes(permission)\n }\n\n const hasAnyPermission = (permissionList: string[]) => {\n return permissionList.some(permission => permissions.value.includes(permission))\n }\n\n const hasAllPermissions = (permissionList: string[]) => {\n return permissionList.every(permission => permissions.value.includes(permission))\n }\n\n return {\n permissions: computed(() => permissions.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchPermissions,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n }\n}\n"],"mappings":"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","names":["computed","inject","defineComponent","onMounted","ref","provide","AUTHDOG_CONTEXT_KEY","AuthdogProvider","_","slots","isLoading","token","setToken","newToken","url","urlToken","existingToken","context","_a","useSession","context","inject","AUTHDOG_CONTEXT_KEY","computed","ref","computed","inject","getPublicKeyPayload","publicKey","validatePublicKey","publicKey","fetchUserData","token","publicKeyObj","getPublicKeyPayload","userData","browserCookiesOptions","useUser","context","inject","AUTHDOG_CONTEXT_KEY","user","ref","isLoading","error","fetchUser","publicKey","validatePublicKey","userData","fetchUserData","err","isAuthenticated","computed","ref","computed","inject","useSignIn","context","inject","AUTHDOG_CONTEXT_KEY","isLoading","ref","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","computed","ref","computed","inject","useSignUp","context","inject","AUTHDOG_CONTEXT_KEY","isLoading","ref","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","computed","ref","computed","inject","useSignOut","context","inject","AUTHDOG_CONTEXT_KEY","isLoading","ref","error","err","computed","ref","computed","inject","useOrganization","context","inject","AUTHDOG_CONTEXT_KEY","organization","ref","isLoading","error","fetchOrganization","organizationId","response","err","computed","ref","computed","inject","useOrganizationList","context","inject","AUTHDOG_CONTEXT_KEY","organizations","ref","isLoading","error","fetchOrganizations","response","data","err","computed","ref","computed","inject","useAuthz","context","inject","AUTHDOG_CONTEXT_KEY","permissions","ref","isLoading","error","fetchPermissions","response","data","err","hasPermission","permission","hasAnyPermission","permissionList","hasAllPermissions","computed"]}
1
+ {"version":3,"sources":["../src/client/provider.ts","../src/commons.ts","../src/client/session.ts","../src/composables/use-session.ts","../src/composables/use-user.ts","../src/composables/use-signin.ts","../src/composables/use-signup.ts","../src/composables/use-signout.ts","../src/composables/use-organization.ts","../src/composables/use-organization-list.ts","../src/composables/use-authz.ts"],"sourcesContent":["import {\n defineComponent,\n onMounted,\n ref,\n provide,\n type InjectionKey,\n} from \"vue\";\n\nexport interface AuthdogContext {\n readonly isLoading: boolean;\n readonly token: string | null;\n setToken: (token: string | null) => void;\n}\n\nexport const AUTHDOG_CONTEXT_KEY: InjectionKey<AuthdogContext> =\n Symbol(\"authdog\");\n\n/** Shared localStorage key for the persisted token. */\nexport const TOKEN_STORAGE_KEY = \"token\";\n\n/** JWT shape: three base64url segments separated by dots. */\nconst JWT_PATTERN = /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/;\n\nexport const AuthdogProvider = defineComponent({\n name: \"AuthdogProvider\",\n setup(_, { slots }) {\n const isLoading = ref(true);\n const token = ref<string | null>(null);\n\n const setToken = (newToken: string | null) => {\n token.value = newToken;\n };\n\n onMounted(() => {\n // Check if we're in the browser\n if (typeof window !== \"undefined\") {\n // Check if there's a token in the URL\n const url = new URL(window.location.href);\n const urlToken = url.searchParams.get(\"token\");\n\n if (urlToken) {\n // Remove token from URL without triggering a page reload,\n // regardless of whether the token is valid.\n url.searchParams.delete(\"token\");\n window.history.replaceState({}, document.title, url.toString());\n\n // Only persist values that look like a JWT to avoid storing\n // arbitrary attacker-supplied data.\n if (JWT_PATTERN.test(urlToken)) {\n localStorage.setItem(TOKEN_STORAGE_KEY, urlToken);\n setToken(urlToken);\n\n // Force a reload to ensure the server processes the token\n window.location.reload();\n return;\n }\n }\n\n // Check for existing token in localStorage\n const existingToken = localStorage.getItem(TOKEN_STORAGE_KEY);\n if (existingToken) {\n setToken(existingToken);\n }\n\n // If no token, we're done loading\n isLoading.value = false;\n } else {\n // If we're on the server, don't show loading state\n isLoading.value = false;\n }\n });\n\n // Expose reactive state through getters so consumers always read the\n // live ref values rather than a frozen snapshot taken at setup time.\n const context: AuthdogContext = {\n get isLoading() {\n return isLoading.value;\n },\n get token() {\n return token.value;\n },\n setToken,\n };\n\n provide(AUTHDOG_CONTEXT_KEY, context);\n\n return () => slots.default?.();\n },\n});\n","import {\n validateAndParsePublicKey,\n type PublicKeyPayload,\n} from \"@authdog/node-commons\";\n\nexport type { PublicKeyPayload };\n\n/**\n * Decodes and validates an Authdog public key. Delegates to the hardened\n * shared parser in @authdog/node-commons, which validates the payload and\n * enforces a trusted identity-host allowlist (SSRF / token-exfiltration\n * protection) rather than blindly decoding base64/JSON.\n */\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n return validateAndParsePublicKey(publicKey);\n};\n","import { getPublicKeyPayload } from \"../commons\";\n\nexport const getTokenFromUri = (url: string): string | null => {\n return new URL(url).searchParams.get(\"token\");\n};\n\ninterface IFetchUserData {\n user: {\n id: string;\n environmentId: string;\n externalId: string;\n userName: string;\n displayName: string;\n nickName: string;\n profileUrl: string;\n title: string;\n userType: string;\n preferredLanguage: string | null;\n locale: string | null;\n timezone: string | null;\n active: boolean;\n provider: string;\n lastLogin: string;\n createdAt: string;\n updatedAt: string;\n names: {\n id: string;\n userId: string;\n formatted: string | null;\n familyName: string;\n givenName: string;\n middleName: string | null;\n honorificPrefix: string | null;\n honorificSuffix: string | null;\n createdAt: string;\n updatedAt: string;\n };\n addresses: [];\n emails: {\n value: string;\n primary: boolean;\n type: string;\n }[];\n phoneNumbers: [];\n ims: [];\n photos: {\n value: string;\n type: string;\n }[];\n };\n meta: {\n code: number;\n message: string;\n };\n}\n\nexport const validatePublicKey = (publicKey: string) => {\n if (!publicKey) {\n throw new Error(\"Public key is not defined\");\n }\n\n if (!publicKey.startsWith(\"pk_\")) {\n throw new Error(\"Invalid public key\");\n }\n};\n\nexport const fetchUserData = async (\n publicKey: string,\n token: string,\n): Promise<IFetchUserData | null> => {\n validatePublicKey(publicKey);\n const publicKeyObj = getPublicKeyPayload(publicKey);\n const userData = await fetch(\n `${publicKeyObj?.identityHost}/oidc/${publicKeyObj?.environmentId}/userinfo`,\n {\n headers: {\n authorization: `Bearer ${token}`,\n },\n },\n );\n\n if (!userData.ok) {\n throw new Error(\"Failed to fetch user info\");\n }\n\n return await userData.json();\n};\n\n// NOTE: These options are for cookies usable from the browser. `httpOnly` is\n// intentionally omitted — it is a no-op (and misleading) for client-set\n// cookies since JS cannot set HttpOnly. Session cookies should be set\n// server-side with HttpOnly; do not set session cookies from client JS.\nexport const browserCookiesOptions = {\n maxAge: 60 * 60 * 24 * 7, // 1 week\n path: \"/\",\n secure: true,\n sameSite: \"lax\" as const,\n};\n","import { computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useSession = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n\n if (!context) {\n throw new Error(\"useSession must be used within AuthdogProvider\");\n }\n\n const session = computed(() => ({\n token: context.token,\n isAuthenticated: !!context.token,\n }));\n\n return {\n session,\n isLoading: computed(() => context.isLoading),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\nimport { fetchUserData, validatePublicKey } from \"../client/session\";\n\nexport const useUser = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const user = ref<any>(null);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useUser must be used within AuthdogProvider\");\n }\n\n const fetchUser = async (publicKey: string) => {\n if (!context.token) {\n return null;\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n validatePublicKey(publicKey);\n const userData = await fetchUserData(publicKey, context.token);\n user.value = userData?.user || null;\n return userData?.user || null;\n } catch (err) {\n error.value = err as Error;\n return null;\n } finally {\n isLoading.value = false;\n }\n };\n\n const isAuthenticated = computed(() => !!context.token && !!user.value);\n\n return {\n user: computed(() => user.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n isAuthenticated,\n fetchUser,\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useSignIn = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useSignIn must be used within AuthdogProvider\");\n }\n\n const signIn = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true;\n error.value = null;\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace(\"pk_\", \"\"), \"base64\").toString(\"utf-8\"),\n );\n\n const authUrl = new URL(\n `${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`,\n );\n authUrl.searchParams.set(\"client_id\", publicKey);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"scope\", \"openid profile email\");\n authUrl.searchParams.set(\n \"redirect_uri\",\n redirectUrl || window.location.origin,\n );\n\n window.location.href = authUrl.toString();\n } catch (err) {\n error.value = err as Error;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n signIn,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useSignUp = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useSignUp must be used within AuthdogProvider\");\n }\n\n const signUp = async (publicKey: string, redirectUrl?: string) => {\n isLoading.value = true;\n error.value = null;\n\n try {\n const publicKeyObj = JSON.parse(\n Buffer.from(publicKey.replace(\"pk_\", \"\"), \"base64\").toString(\"utf-8\"),\n );\n\n const authUrl = new URL(\n `${publicKeyObj.identityHost}/oidc/${publicKeyObj.environmentId}/authorize`,\n );\n authUrl.searchParams.set(\"client_id\", publicKey);\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"scope\", \"openid profile email\");\n authUrl.searchParams.set(\n \"redirect_uri\",\n redirectUrl || window.location.origin,\n );\n authUrl.searchParams.set(\"prompt\", \"signup\");\n\n window.location.href = authUrl.toString();\n } catch (err) {\n error.value = err as Error;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n signUp,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport {\n AUTHDOG_CONTEXT_KEY,\n TOKEN_STORAGE_KEY,\n type AuthdogContext,\n} from \"../client/provider\";\n\nexport const useSignOut = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useSignOut must be used within AuthdogProvider\");\n }\n\n const signOut = async () => {\n isLoading.value = true;\n error.value = null;\n\n try {\n // Clear token from context\n context.setToken(null);\n\n // Clear token from localStorage\n if (typeof window !== \"undefined\") {\n localStorage.removeItem(TOKEN_STORAGE_KEY);\n }\n\n // Redirect to logout endpoint or home page\n if (typeof window !== \"undefined\") {\n window.location.href = \"/logout\";\n }\n } catch (err) {\n error.value = err as Error;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n signOut,\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useOrganization = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const organization = ref<any>(null);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useOrganization must be used within AuthdogProvider\");\n }\n\n const fetchOrganization = async (organizationId: string) => {\n if (!context.token) {\n return null;\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n // This would be implemented based on your organization API\n // For now, returning a placeholder\n const response = await fetch(`/api/organizations/${organizationId}`, {\n headers: {\n Authorization: `Bearer ${context.token}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(\"Failed to fetch organization\");\n }\n\n organization.value = await response.json();\n return organization.value;\n } catch (err) {\n error.value = err as Error;\n return null;\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n organization: computed(() => organization.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganization,\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\nexport const useOrganizationList = () => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const organizations = ref<any[]>([]);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useOrganizationList must be used within AuthdogProvider\");\n }\n\n const fetchOrganizations = async () => {\n if (!context.token) {\n return [];\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n // This would be implemented based on your organizations API\n // For now, returning a placeholder\n const response = await fetch(\"/api/organizations\", {\n headers: {\n Authorization: `Bearer ${context.token}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(\"Failed to fetch organizations\");\n }\n\n const data = await response.json();\n organizations.value = data.organizations || [];\n return organizations.value;\n } catch (err) {\n error.value = err as Error;\n return [];\n } finally {\n isLoading.value = false;\n }\n };\n\n return {\n organizations: computed(() => organizations.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchOrganizations,\n };\n};\n","import { ref, computed, inject } from \"vue\";\nimport { AUTHDOG_CONTEXT_KEY, type AuthdogContext } from \"../client/provider\";\n\n/**\n * ⚠️ PRESENTATIONAL ONLY — NOT A SECURITY BOUNDARY.\n *\n * This composable fetches a permission list to drive UI affordances (showing\n * or hiding buttons, menu items, etc.). It runs entirely in the browser and\n * is therefore trivially bypassable by any client. It MUST NOT be used to\n * gate access to data or actions.\n *\n * Every protected operation MUST be independently enforced server-side.\n */\n\nexport interface UseAuthzOptions {\n /**\n * URL of the endpoint that returns the current user's permissions.\n * Defaults to \"/api/permissions\". This endpoint is informational only;\n * authorization must still be enforced on every protected server endpoint.\n */\n permissionsUrl?: string;\n}\n\nexport const useAuthz = (options: UseAuthzOptions = {}) => {\n const context = inject<AuthdogContext>(AUTHDOG_CONTEXT_KEY);\n const permissions = ref<string[]>([]);\n const isLoading = ref(false);\n const error = ref<Error | null>(null);\n\n if (!context) {\n throw new Error(\"useAuthz must be used within AuthdogProvider\");\n }\n\n const permissionsUrl = options.permissionsUrl ?? \"/api/permissions\";\n\n const fetchPermissions = async () => {\n if (!context.token) {\n return [];\n }\n\n isLoading.value = true;\n error.value = null;\n\n try {\n const response = await fetch(permissionsUrl, {\n headers: {\n Authorization: `Bearer ${context.token}`,\n },\n });\n\n // Distinguish an authentication failure from an empty permission list.\n // A 401 means the session is invalid/expired and should surface as an\n // error rather than being silently coerced into \"no permissions\".\n if (response.status === 401) {\n permissions.value = [];\n throw new Error(\"Unauthorized: authentication failed (401)\");\n }\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch permissions (status ${response.status})`,\n );\n }\n\n const data = await response.json();\n permissions.value = data.permissions || [];\n return permissions.value;\n } catch (err) {\n error.value = err as Error;\n return [];\n } finally {\n isLoading.value = false;\n }\n };\n\n /**\n * ⚠️ PRESENTATIONAL ONLY. Returns whether the locally-cached permission\n * list contains `permission`. This is for UI hints only and is bypassable;\n * never rely on it as an access-control check. Enforce permissions\n * server-side for every protected operation.\n */\n const hasPermission = (permission: string) => {\n return permissions.value.includes(permission);\n };\n\n const hasAnyPermission = (permissionList: string[]) => {\n return permissionList.some((permission) =>\n permissions.value.includes(permission),\n );\n };\n\n const hasAllPermissions = (permissionList: string[]) => {\n return permissionList.every((permission) =>\n permissions.value.includes(permission),\n );\n };\n\n return {\n permissions: computed(() => permissions.value),\n isLoading: computed(() => isLoading.value),\n error: computed(() => error.value),\n fetchPermissions,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n };\n};\n"],"mappings":"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","names":["defineComponent","onMounted","ref","provide","AUTHDOG_CONTEXT_KEY","TOKEN_STORAGE_KEY","JWT_PATTERN","AuthdogProvider","_","slots","isLoading","token","setToken","newToken","url","urlToken","existingToken","_a","validateAndParsePublicKey","getPublicKeyPayload","publicKey","getTokenFromUri","url","validatePublicKey","publicKey","fetchUserData","token","publicKeyObj","getPublicKeyPayload","userData","browserCookiesOptions","computed","inject","useSession","context","inject","AUTHDOG_CONTEXT_KEY","computed","ref","computed","inject","useUser","context","inject","AUTHDOG_CONTEXT_KEY","user","ref","isLoading","error","fetchUser","publicKey","validatePublicKey","userData","fetchUserData","err","isAuthenticated","computed","ref","computed","inject","useSignIn","context","inject","AUTHDOG_CONTEXT_KEY","isLoading","ref","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","computed","ref","computed","inject","useSignUp","context","inject","AUTHDOG_CONTEXT_KEY","isLoading","ref","error","publicKey","redirectUrl","publicKeyObj","authUrl","err","computed","ref","computed","inject","useSignOut","context","inject","AUTHDOG_CONTEXT_KEY","isLoading","ref","error","TOKEN_STORAGE_KEY","err","computed","ref","computed","inject","useOrganization","context","inject","AUTHDOG_CONTEXT_KEY","organization","ref","isLoading","error","fetchOrganization","organizationId","response","err","computed","ref","computed","inject","useOrganizationList","context","inject","AUTHDOG_CONTEXT_KEY","organizations","ref","isLoading","error","fetchOrganizations","response","data","err","computed","ref","computed","inject","useAuthz","options","context","inject","AUTHDOG_CONTEXT_KEY","permissions","ref","isLoading","error","permissionsUrl","fetchPermissions","response","data","err","hasPermission","permission","hasAnyPermission","permissionList","hasAllPermissions","computed"]}
package/dist/server.d.mts CHANGED
@@ -1,2 +1,19 @@
1
+ interface AuthdogServerConfig {
2
+ publicKey: string;
3
+ secretKey: string;
4
+ baseUrl?: string;
5
+ }
6
+ interface AuthdogServer {
7
+ getSession: (request: Request) => Promise<string | null>;
8
+ getPublicKey: () => string;
9
+ logout: (request: Request) => Promise<Response>;
10
+ }
11
+ declare const createAuthdogServer: (config: AuthdogServerConfig) => AuthdogServer;
1
12
 
2
- export { }
13
+ declare const getSessionCookie: (request: Request) => Promise<string | null>;
14
+
15
+ declare const logoutHandler: (request: Request, _secretKey: string) => Promise<Response>;
16
+
17
+ declare const getServerSidePayloadPublicKey: (publicKey: string) => string;
18
+
19
+ export { createAuthdogServer, getServerSidePayloadPublicKey, getSessionCookie, logoutHandler };
package/dist/server.d.ts CHANGED
@@ -1,2 +1,19 @@
1
+ interface AuthdogServerConfig {
2
+ publicKey: string;
3
+ secretKey: string;
4
+ baseUrl?: string;
5
+ }
6
+ interface AuthdogServer {
7
+ getSession: (request: Request) => Promise<string | null>;
8
+ getPublicKey: () => string;
9
+ logout: (request: Request) => Promise<Response>;
10
+ }
11
+ declare const createAuthdogServer: (config: AuthdogServerConfig) => AuthdogServer;
1
12
 
2
- export { }
13
+ declare const getSessionCookie: (request: Request) => Promise<string | null>;
14
+
15
+ declare const logoutHandler: (request: Request, _secretKey: string) => Promise<Response>;
16
+
17
+ declare const getServerSidePayloadPublicKey: (publicKey: string) => string;
18
+
19
+ export { createAuthdogServer, getServerSidePayloadPublicKey, getSessionCookie, logoutHandler };
package/dist/server.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var m=Object.defineProperty;var t=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var b=(r,o,p,f)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of x(o))!a.call(r,e)&&e!==p&&m(r,e,{get:()=>o[e],enumerable:!(f=t(o,e))||f.enumerable});return r};var c=r=>b(m({},"__esModule",{value:!0}),r);var d={};module.exports=c(d);
1
+ "use strict";var u=Object.defineProperty;var P=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var S=(e,r)=>{for(var t in r)u(e,t,{get:r[t],enumerable:!0})},h=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of m(r))!f.call(e,s)&&s!==t&&u(e,s,{get:()=>r[s],enumerable:!(o=P(r,s))||o.enumerable});return e};var b=e=>h(u({},"__esModule",{value:!0}),e);var x={};S(x,{createAuthdogServer:()=>p,getServerSidePayloadPublicKey:()=>n,getSessionCookie:()=>i,logoutHandler:()=>a});module.exports=b(x);var c=require("@authdog/node-commons"),i=async e=>{var o;let r=e.headers.get("cookie");return r?((o=(0,c.parseCookies)(r).find(s=>s.name==="authdog-session"))==null?void 0:o.value)??null:null};var l=require("@authdog/node-commons"),g=e=>(0,l.validateAndParsePublicKey)(e);var n=e=>{if(!e)throw new Error("Public key is not defined");if(!e.startsWith("pk_"))throw new Error("Invalid public key");try{let r=g(e);return JSON.stringify(r)}catch{throw new Error("Failed to parse public key")}};var d=require("@authdog/node-commons"),a=async(e,r)=>{let t=new Response(null,{status:302}),o=process.env.NODE_ENV==="production"?" Secure;":"";t.headers.set("Set-Cookie",`authdog-session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly;${o} SameSite=Lax`);let s=new URL(e.url),y=(0,d.sanitizeRedirectPath)(s.searchParams.get("redirect_uri"),"/");return t.headers.set("Location",y),t};var p=e=>{let{publicKey:r,secretKey:t}=e;return{getSession:async o=>await i(o),getPublicKey:()=>n(r),logout:async o=>await a(o,t)}};0&&(module.exports={createAuthdogServer,getServerSidePayloadPublicKey,getSessionCookie,logoutHandler});
2
2
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts"],"sourcesContent":["export * from './server'\n"],"mappings":"+WAAA,IAAAA,EAAA,kBAAAC,EAAAD","names":["server_exports","__toCommonJS"]}
1
+ {"version":3,"sources":["../src/server.ts","../src/server/cookies.ts","../src/commons.ts","../src/server/publicKey.ts","../src/server/logout.ts","../src/server/server.ts"],"sourcesContent":["export * from \"./server/index\";\n","import { parseCookies } from \"@authdog/node-commons\";\n\nexport const getSessionCookie = async (\n request: Request,\n): Promise<string | null> => {\n const cookieHeader = request.headers.get(\"cookie\");\n\n if (!cookieHeader) {\n return null;\n }\n\n // parseCookies splits on the first \"=\" and URL-decodes values, correctly\n // handling cookie values that themselves contain \"=\" (e.g. base64/JWT).\n const cookies = parseCookies(cookieHeader);\n\n return cookies.find((c) => c.name === \"authdog-session\")?.value ?? null;\n};\n","import {\n validateAndParsePublicKey,\n type PublicKeyPayload,\n} from \"@authdog/node-commons\";\n\nexport type { PublicKeyPayload };\n\n/**\n * Decodes and validates an Authdog public key. Delegates to the hardened\n * shared parser in @authdog/node-commons, which validates the payload and\n * enforces a trusted identity-host allowlist (SSRF / token-exfiltration\n * protection) rather than blindly decoding base64/JSON.\n */\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n return validateAndParsePublicKey(publicKey);\n};\n","import { getPublicKeyPayload } from \"../commons\";\n\nexport const getServerSidePayloadPublicKey = (publicKey: string): string => {\n if (!publicKey) {\n throw new Error(\"Public key is not defined\");\n }\n\n if (!publicKey.startsWith(\"pk_\")) {\n throw new Error(\"Invalid public key\");\n }\n\n try {\n const payload = getPublicKeyPayload(publicKey);\n return JSON.stringify(payload);\n } catch (e) {\n throw new Error(\"Failed to parse public key\");\n }\n};\n","import { sanitizeRedirectPath } from \"@authdog/node-commons\";\n\nexport const logoutHandler = async (\n request: Request,\n // Reserved for future server-side session revocation; not yet used.\n _secretKey: string,\n): Promise<Response> => {\n // Clear the session cookie\n const response = new Response(null, { status: 302 });\n\n // Set cookie to expire immediately. Secure is gated on production so local\n // HTTP development still clears the cookie; HttpOnly + SameSite=Lax retained.\n const secure = process.env.NODE_ENV === \"production\" ? \" Secure;\" : \"\";\n response.headers.set(\n \"Set-Cookie\",\n `authdog-session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly;${secure} SameSite=Lax`,\n );\n\n // Redirect to home page or specified redirect URL. Sanitize to prevent\n // open-redirect via an attacker-controlled redirect_uri parameter.\n const url = new URL(request.url);\n const redirectUrl = sanitizeRedirectPath(\n url.searchParams.get(\"redirect_uri\"),\n \"/\",\n );\n\n response.headers.set(\"Location\", redirectUrl);\n\n return response;\n};\n","import { getSessionCookie } from \"./cookies\";\nimport { getServerSidePayloadPublicKey } from \"./publicKey\";\nimport { logoutHandler } from \"./logout\";\n\nexport interface AuthdogServerConfig {\n publicKey: string;\n secretKey: string;\n baseUrl?: string;\n}\n\nexport interface AuthdogServer {\n getSession: (request: Request) => Promise<string | null>;\n getPublicKey: () => string;\n logout: (request: Request) => Promise<Response>;\n}\n\nexport const createAuthdogServer = (\n config: AuthdogServerConfig,\n): AuthdogServer => {\n const { publicKey, secretKey } = config;\n\n return {\n getSession: async (request: Request) => {\n return await getSessionCookie(request);\n },\n\n getPublicKey: () => {\n return getServerSidePayloadPublicKey(publicKey);\n },\n\n logout: async (request: Request) => {\n return await logoutHandler(request, secretKey);\n },\n };\n};\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,yBAAAE,EAAA,kCAAAC,EAAA,qBAAAC,EAAA,kBAAAC,IAAA,eAAAC,EAAAN,GCAA,IAAAO,EAA6B,iCAEhBC,EAAmB,MAC9BC,GAC2B,CAJ7B,IAAAC,EAKE,IAAMC,EAAeF,EAAQ,QAAQ,IAAI,QAAQ,EAEjD,OAAKE,IAQED,KAFS,gBAAaC,CAAY,EAE1B,KAAMC,GAAMA,EAAE,OAAS,iBAAiB,IAAhD,YAAAF,EAAmD,QAAS,KAP1D,IAQX,EChBA,IAAAG,EAGO,iCAUMC,EAAuBC,MAC3B,6BAA0BA,CAAS,ECZrC,IAAMC,EAAiCC,GAA8B,CAC1E,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,2BAA2B,EAG7C,GAAI,CAACA,EAAU,WAAW,KAAK,EAC7B,MAAM,IAAI,MAAM,oBAAoB,EAGtC,GAAI,CACF,IAAMC,EAAUC,EAAoBF,CAAS,EAC7C,OAAO,KAAK,UAAUC,CAAO,CAC/B,MAAY,CACV,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CACF,ECjBA,IAAAE,EAAqC,iCAExBC,EAAgB,MAC3BC,EAEAC,IACsB,CAEtB,IAAMC,EAAW,IAAI,SAAS,KAAM,CAAE,OAAQ,GAAI,CAAC,EAI7CC,EAAS,QAAQ,IAAI,WAAa,aAAe,WAAa,GACpED,EAAS,QAAQ,IACf,aACA,6EAA6EC,CAAM,eACrF,EAIA,IAAMC,EAAM,IAAI,IAAIJ,EAAQ,GAAG,EACzBK,KAAc,wBAClBD,EAAI,aAAa,IAAI,cAAc,EACnC,GACF,EAEA,OAAAF,EAAS,QAAQ,IAAI,WAAYG,CAAW,EAErCH,CACT,ECbO,IAAMI,EACXC,GACkB,CAClB,GAAM,CAAE,UAAAC,EAAW,UAAAC,CAAU,EAAIF,EAEjC,MAAO,CACL,WAAY,MAAOG,GACV,MAAMC,EAAiBD,CAAO,EAGvC,aAAc,IACLE,EAA8BJ,CAAS,EAGhD,OAAQ,MAAOE,GACN,MAAMG,EAAcH,EAASD,CAAS,CAEjD,CACF","names":["server_exports","__export","createAuthdogServer","getServerSidePayloadPublicKey","getSessionCookie","logoutHandler","__toCommonJS","import_node_commons","getSessionCookie","request","_a","cookieHeader","c","import_node_commons","getPublicKeyPayload","publicKey","getServerSidePayloadPublicKey","publicKey","payload","getPublicKeyPayload","import_node_commons","logoutHandler","request","_secretKey","response","secure","url","redirectUrl","createAuthdogServer","config","publicKey","secretKey","request","getSessionCookie","getServerSidePayloadPublicKey","logoutHandler"]}
package/dist/server.mjs CHANGED
@@ -1 +1,2 @@
1
+ import{parseCookies as l}from"@authdog/node-commons";var i=async e=>{var t;let r=e.headers.get("cookie");return r?((t=l(r).find(s=>s.name==="authdog-session"))==null?void 0:t.value)??null:null};import{validateAndParsePublicKey as g}from"@authdog/node-commons";var u=e=>g(e);var n=e=>{if(!e)throw new Error("Public key is not defined");if(!e.startsWith("pk_"))throw new Error("Invalid public key");try{let r=u(e);return JSON.stringify(r)}catch{throw new Error("Failed to parse public key")}};import{sanitizeRedirectPath as d}from"@authdog/node-commons";var a=async(e,r)=>{let o=new Response(null,{status:302}),t=process.env.NODE_ENV==="production"?" Secure;":"";o.headers.set("Set-Cookie",`authdog-session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly;${t} SameSite=Lax`);let s=new URL(e.url),c=d(s.searchParams.get("redirect_uri"),"/");return o.headers.set("Location",c),o};var p=e=>{let{publicKey:r,secretKey:o}=e;return{getSession:async t=>await i(t),getPublicKey:()=>n(r),logout:async t=>await a(t,o)}};export{p as createAuthdogServer,n as getServerSidePayloadPublicKey,i as getSessionCookie,a as logoutHandler};
1
2
  //# sourceMappingURL=server.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/server/cookies.ts","../src/commons.ts","../src/server/publicKey.ts","../src/server/logout.ts","../src/server/server.ts"],"sourcesContent":["import { parseCookies } from \"@authdog/node-commons\";\n\nexport const getSessionCookie = async (\n request: Request,\n): Promise<string | null> => {\n const cookieHeader = request.headers.get(\"cookie\");\n\n if (!cookieHeader) {\n return null;\n }\n\n // parseCookies splits on the first \"=\" and URL-decodes values, correctly\n // handling cookie values that themselves contain \"=\" (e.g. base64/JWT).\n const cookies = parseCookies(cookieHeader);\n\n return cookies.find((c) => c.name === \"authdog-session\")?.value ?? null;\n};\n","import {\n validateAndParsePublicKey,\n type PublicKeyPayload,\n} from \"@authdog/node-commons\";\n\nexport type { PublicKeyPayload };\n\n/**\n * Decodes and validates an Authdog public key. Delegates to the hardened\n * shared parser in @authdog/node-commons, which validates the payload and\n * enforces a trusted identity-host allowlist (SSRF / token-exfiltration\n * protection) rather than blindly decoding base64/JSON.\n */\nexport const getPublicKeyPayload = (publicKey: string): PublicKeyPayload => {\n return validateAndParsePublicKey(publicKey);\n};\n","import { getPublicKeyPayload } from \"../commons\";\n\nexport const getServerSidePayloadPublicKey = (publicKey: string): string => {\n if (!publicKey) {\n throw new Error(\"Public key is not defined\");\n }\n\n if (!publicKey.startsWith(\"pk_\")) {\n throw new Error(\"Invalid public key\");\n }\n\n try {\n const payload = getPublicKeyPayload(publicKey);\n return JSON.stringify(payload);\n } catch (e) {\n throw new Error(\"Failed to parse public key\");\n }\n};\n","import { sanitizeRedirectPath } from \"@authdog/node-commons\";\n\nexport const logoutHandler = async (\n request: Request,\n // Reserved for future server-side session revocation; not yet used.\n _secretKey: string,\n): Promise<Response> => {\n // Clear the session cookie\n const response = new Response(null, { status: 302 });\n\n // Set cookie to expire immediately. Secure is gated on production so local\n // HTTP development still clears the cookie; HttpOnly + SameSite=Lax retained.\n const secure = process.env.NODE_ENV === \"production\" ? \" Secure;\" : \"\";\n response.headers.set(\n \"Set-Cookie\",\n `authdog-session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly;${secure} SameSite=Lax`,\n );\n\n // Redirect to home page or specified redirect URL. Sanitize to prevent\n // open-redirect via an attacker-controlled redirect_uri parameter.\n const url = new URL(request.url);\n const redirectUrl = sanitizeRedirectPath(\n url.searchParams.get(\"redirect_uri\"),\n \"/\",\n );\n\n response.headers.set(\"Location\", redirectUrl);\n\n return response;\n};\n","import { getSessionCookie } from \"./cookies\";\nimport { getServerSidePayloadPublicKey } from \"./publicKey\";\nimport { logoutHandler } from \"./logout\";\n\nexport interface AuthdogServerConfig {\n publicKey: string;\n secretKey: string;\n baseUrl?: string;\n}\n\nexport interface AuthdogServer {\n getSession: (request: Request) => Promise<string | null>;\n getPublicKey: () => string;\n logout: (request: Request) => Promise<Response>;\n}\n\nexport const createAuthdogServer = (\n config: AuthdogServerConfig,\n): AuthdogServer => {\n const { publicKey, secretKey } = config;\n\n return {\n getSession: async (request: Request) => {\n return await getSessionCookie(request);\n },\n\n getPublicKey: () => {\n return getServerSidePayloadPublicKey(publicKey);\n },\n\n logout: async (request: Request) => {\n return await logoutHandler(request, secretKey);\n },\n };\n};\n"],"mappings":"AAAA,OAAS,gBAAAA,MAAoB,wBAEtB,IAAMC,EAAmB,MAC9BC,GAC2B,CAJ7B,IAAAC,EAKE,IAAMC,EAAeF,EAAQ,QAAQ,IAAI,QAAQ,EAEjD,OAAKE,IAQED,EAFSH,EAAaI,CAAY,EAE1B,KAAMC,GAAMA,EAAE,OAAS,iBAAiB,IAAhD,YAAAF,EAAmD,QAAS,KAP1D,IAQX,EChBA,OACE,6BAAAG,MAEK,wBAUA,IAAMC,EAAuBC,GAC3BF,EAA0BE,CAAS,ECZrC,IAAMC,EAAiCC,GAA8B,CAC1E,GAAI,CAACA,EACH,MAAM,IAAI,MAAM,2BAA2B,EAG7C,GAAI,CAACA,EAAU,WAAW,KAAK,EAC7B,MAAM,IAAI,MAAM,oBAAoB,EAGtC,GAAI,CACF,IAAMC,EAAUC,EAAoBF,CAAS,EAC7C,OAAO,KAAK,UAAUC,CAAO,CAC/B,MAAY,CACV,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CACF,ECjBA,OAAS,wBAAAE,MAA4B,wBAE9B,IAAMC,EAAgB,MAC3BC,EAEAC,IACsB,CAEtB,IAAMC,EAAW,IAAI,SAAS,KAAM,CAAE,OAAQ,GAAI,CAAC,EAI7CC,EAAS,QAAQ,IAAI,WAAa,aAAe,WAAa,GACpED,EAAS,QAAQ,IACf,aACA,6EAA6EC,CAAM,eACrF,EAIA,IAAMC,EAAM,IAAI,IAAIJ,EAAQ,GAAG,EACzBK,EAAcP,EAClBM,EAAI,aAAa,IAAI,cAAc,EACnC,GACF,EAEA,OAAAF,EAAS,QAAQ,IAAI,WAAYG,CAAW,EAErCH,CACT,ECbO,IAAMI,EACXC,GACkB,CAClB,GAAM,CAAE,UAAAC,EAAW,UAAAC,CAAU,EAAIF,EAEjC,MAAO,CACL,WAAY,MAAOG,GACV,MAAMC,EAAiBD,CAAO,EAGvC,aAAc,IACLE,EAA8BJ,CAAS,EAGhD,OAAQ,MAAOE,GACN,MAAMG,EAAcH,EAASD,CAAS,CAEjD,CACF","names":["parseCookies","getSessionCookie","request","_a","cookieHeader","c","validateAndParsePublicKey","getPublicKeyPayload","publicKey","getServerSidePayloadPublicKey","publicKey","payload","getPublicKeyPayload","sanitizeRedirectPath","logoutHandler","request","_secretKey","response","secure","url","redirectUrl","createAuthdogServer","config","publicKey","secretKey","request","getSessionCookie","getServerSidePayloadPublicKey","logoutHandler"]}
package/package.json CHANGED
@@ -1,49 +1,65 @@
1
1
  {
2
- "name": "@authdog/vue",
3
- "version": "0.0.1",
4
- "description": "Authdog Vue SDK",
5
- "source": "src/index.ts",
6
- "main": "dist/index.js",
7
- "module": "dist/index.js",
8
- "types": "dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "dist/index.d.ts",
12
- "import": "dist/index.js"
2
+ "name": "@authdog/vue",
3
+ "version": "0.2.0",
4
+ "description": "Authdog Vue SDK",
5
+ "source": "src/index.ts",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
14
+ },
15
+ "./client": {
16
+ "types": "./dist/client.d.ts",
17
+ "import": "./dist/client.mjs",
18
+ "require": "./dist/client.js"
19
+ },
20
+ "./server": {
21
+ "types": "./dist/server.d.ts",
22
+ "import": "./dist/server.mjs",
23
+ "require": "./dist/server.js"
24
+ }
13
25
  },
14
- "./client": {
15
- "types": "dist/client.d.ts",
16
- "import": "dist/client.js"
26
+ "files": [
27
+ "dist/"
28
+ ],
29
+ "sideEffects": false,
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/authdog-labs/web-sdk.git",
33
+ "directory": "packages/vue"
17
34
  },
18
- "./server": {
19
- "types": "dist/server.d.ts",
20
- "import": "dist/server.js"
35
+ "homepage": "https://github.com/authdog-labs/web-sdk/tree/main/packages/vue#readme",
36
+ "bugs": {
37
+ "url": "https://github.com/authdog-labs/web-sdk/issues"
38
+ },
39
+ "scripts": {
40
+ "format": "prettier --config .prettierrc.json --write \"**/*.{ts,md}\"",
41
+ "type-check": "tsc",
42
+ "clean": "rm -rf dist",
43
+ "build": "bun run clean && tsup",
44
+ "ship": "bun run build && bun publish --access public"
45
+ },
46
+ "dependencies": {
47
+ "@authdog/node-commons": "workspace:*"
48
+ },
49
+ "peerDependencies": {
50
+ "vue": "^3.5.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^22.10.5",
54
+ "dotenv": "^16.4.7",
55
+ "prettier": "^3.4.2",
56
+ "tsup": "^8.3.5",
57
+ "typescript": "^5.7.2",
58
+ "vitest": "^2.1.8",
59
+ "vue": "^3.5.0"
60
+ },
61
+ "publishConfig": {
62
+ "registry": "https://registry.npmjs.org/",
63
+ "access": "public"
21
64
  }
22
- },
23
- "files": [
24
- "dist/"
25
- ],
26
- "dependencies": {
27
- "vue": "^3.5.0",
28
- "@authdog/node-commons": "0.0.22"
29
- },
30
- "devDependencies": {
31
- "@types/node": "^22.10.5",
32
- "dotenv": "^16.4.7",
33
- "prettier": "^3.4.2",
34
- "tsup": "^8.3.5",
35
- "typescript": "^5.7.2",
36
- "vitest": "^2.1.8"
37
- },
38
- "publishConfig": {
39
- "registry": "https://registry.npmjs.org/",
40
- "access": "public"
41
- },
42
- "scripts": {
43
- "format": "prettier --config .prettierrc.json --write \"**/*.{ts,md}\"",
44
- "type-check": "tsc",
45
- "clean": "rm -rf dist",
46
- "build": "pnpm clean && tsup",
47
- "ship": "pnpm build && pnpm publish --access public --no-git-checks"
48
- }
49
- }
65
+ }