@versini/auth-provider 8.0.3 → 8.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,149 @@
1
1
  # @versini/auth-provider
2
2
 
3
- This package provides a simple authentication provider for your application.
3
+ High-level React authentication components & hooks supporting password (PKCE Code) and Passkey (WebAuthn) flows, with optional Auth0 integration. Built on the primitives from `@versini/auth-common`.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @versini/auth-provider @versini/auth-common react react-dom
9
+ ```
10
+
11
+ Peer deps: `react` (>= 19) & `react-dom`.
12
+
13
+ ## Packages Relationship
14
+
15
+ ```
16
+ @versini/auth-provider -> @versini/auth-common (utilities, constants)
17
+ -> @versini/ui-hooks (local storage abstraction)
18
+ ```
19
+
20
+ ## Features
21
+
22
+ - PKCE Code + Refresh token flow
23
+ - Passkey (WebAuthn) registration & authentication
24
+ - Silent access token refresh with refresh token rotation
25
+ - Role / permission helpers (re-export of `isGranted` & `AUTH_TYPES`)
26
+ - Opt-in Auth0 provider wrapper
27
+ - Local storage isolation per `clientId`
28
+ - Timezone & build metadata banner injection (in distributed bundles)
29
+
30
+ ## Quick Start (Custom Auth Backend)
31
+
32
+ ```tsx
33
+ import { AuthProvider } from "@versini/auth-provider";
34
+
35
+ function App() {
36
+ return (
37
+ <AuthProvider clientId="my-web-app" sessionExpiration="3600" debug>
38
+ <MainRoutes />
39
+ </AuthProvider>
40
+ );
41
+ }
42
+ ```
43
+
44
+ Inside your components:
45
+
46
+ ```tsx
47
+ import { useAuth } from "@versini/auth-provider/hooks";
48
+
49
+ export function Profile() {
50
+ const { user, isAuthenticated, login, logout, getAccessToken } = useAuth();
51
+
52
+ if (!isAuthenticated) {
53
+ return <button onClick={() => login("alice", "p@ssw0rd")}>Login</button>;
54
+ }
55
+ return (
56
+ <div>
57
+ <p>User: {user?.username}</p>
58
+ <button onClick={logout}>Logout</button>
59
+ <button
60
+ onClick={async () => {
61
+ const token = await getAccessToken();
62
+ console.log("access", token.slice(0, 20) + "...");
63
+ }}
64
+ >
65
+ Get Access Token
66
+ </button>
67
+ </div>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ## Passkey (WebAuthn) Flow
73
+
74
+ ```tsx
75
+ const { registeringForPasskey, loginWithPasskey } = useAuth();
76
+
77
+ // After user authenticates with password you can offer passkey registration:
78
+ await registeringForPasskey();
79
+
80
+ // Later, user can login directly with passkey:
81
+ await loginWithPasskey();
82
+ ```
83
+
84
+ ## Auth0 Integration
85
+
86
+ ```tsx
87
+ import { Auth0Provider } from "@versini/auth-provider/auth0";
88
+
89
+ <Auth0Provider
90
+ domain="YOUR_DOMAIN"
91
+ clientId="YOUR_CLIENT_ID"
92
+ authorizationParams={{ redirect_uri: window.location.origin }}
93
+ >
94
+ <App />
95
+ </Auth0Provider>;
96
+ ```
97
+
98
+ All Auth hooks still come from `@versini/auth-provider/hooks`.
99
+
100
+ ## Public API Summary
101
+
102
+ - `<AuthProvider />` – Core provider. Props:
103
+ - `clientId: string` (required)
104
+ - `sessionExpiration?: string` (TTL hint sent to backend)
105
+ - `domain?: string` (multi-tenant / custom domain support)
106
+ - `debug?: boolean` (enables internal logging via `useLogger`)
107
+ - `endpoint?: string` (override default auth service URL)
108
+ - Hooks (from `hooks` entry):
109
+ - `useAuth()` – Returns `AuthContextProps`:
110
+ - state: `isLoading`, `isAuthenticated`, `user`, `logoutReason`, `authenticationType`
111
+ - methods: `login(username, password)`, `logout()`, `getAccessToken()`, `getIdToken()`, `registeringForPasskey()`, `loginWithPasskey()`
112
+ - Auth0:
113
+ - `<Auth0Provider />` – Wraps children and injects Auth0 context + shared `useAuth` hook wiring.
114
+ - Re-exports from `@versini/auth-common`:
115
+ - `AUTH_TYPES`, `isGranted`
116
+
117
+ ## Storage Strategy
118
+
119
+ Local storage keys are namespaced: `@@auth@@::<clientId>::@@<token-type>@@`.
120
+ On logout or token invalidation all related keys are purged atomically (`removeStateAndLocalStorage`).
121
+
122
+ ## Token Refresh
123
+
124
+ `getAccessToken()` validates the existing access token; if expired/invalid it attempts a silent refresh via `TokenManager.refreshtoken()`. Failure triggers a forced logout (security-first principle).
125
+
126
+ ## Error & Security Principles
127
+
128
+ - Deny-by-default: unauthorized or invalid token state leads to logout.
129
+ - All network operations funnel through typed helpers; unexpected responses cause cleanup.
130
+ - No sensitive values are logged unless `debug` is enabled (still avoid including raw tokens in production logs).
131
+ - PKCE flow ensures authorization code interception resistance.
132
+
133
+ ## Bundling Notes
134
+
135
+ Entry files are emitted without hashes (`index.js`, `auth.js`, `auth0.js`, `hooks.js`) for stable package exports; internal split chunks are hashed (`chunks/[name].[hash].js`). This is intentional for library consumption stability.
136
+
137
+ ## TypeScript
138
+
139
+ Distributed ESM with full `.d.ts` declarations; strict types encourage safe usage. Avoid `any`; leverage `AuthContextProps` for context consumers.
140
+
141
+ ## Roadmap / Ideas
142
+
143
+ - SSR helpers for preloading user session
144
+ - Optional cookie-based storage abstraction
145
+ - Enhanced role/permission model (attribute-based access)
146
+
147
+ ## License
148
+
149
+ MIT © gizmette.com
package/dist/auth.js CHANGED
@@ -1,18 +1,18 @@
1
1
  var Pe = Object.defineProperty;
2
2
  var Ce = (e, t, n) => t in e ? Pe(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
3
  var K = (e, t, n) => Ce(e, typeof t != "symbol" ? t + "" : t, n);
4
- import { jsx as H } from "react/jsx-runtime";
5
- import { at as ie, st as ve, K as T, ot as M, nt as C, Ye as D, ct as Ue } from "./index-DxGUVOpC.js";
4
+ import { jsx as V } from "react/jsx-runtime";
5
+ import { HEADERS as ie, decodeToken as ve, JWT as T, API_TYPE as M, AUTH_TYPES as C, verifyAndExtractToken as D, pkceChallengePair as Ue } from "@versini/auth-common";
6
6
  import De, { useSyncExternalStore as Le, useCallback as S, useEffect as ce, createContext as $e, useContext as Ke, useReducer as Ye, useRef as Ge } from "react";
7
- import { AuthHookContext as Ve } from "./AuthHookContext-C9a2AwWZ.js";
7
+ import { AuthHookContext as He } from "./AuthHookContext-C9a2AwWZ.js";
8
8
  /*!
9
- @versini/auth-provider v8.0.3
9
+ @versini/auth-provider v8.0.5
10
10
  © 2025 gizmette.com
11
11
  */
12
12
  try {
13
13
  window.__VERSINI_AUTH_CLIENT__ || (window.__VERSINI_AUTH_CLIENT__ = {
14
- version: "8.0.3",
15
- buildTime: "06/02/2025 05:45 PM EDT",
14
+ version: "8.0.5",
15
+ buildTime: "09/01/2025 07:37 PM EDT",
16
16
  homepage: "https://github.com/aversini/auth-client",
17
17
  license: "MIT"
18
18
  });
@@ -32,9 +32,9 @@ function F(e) {
32
32
  return o;
33
33
  }
34
34
  function X() {
35
- return He.stubThis(globalThis?.PublicKeyCredential !== void 0 && typeof globalThis.PublicKeyCredential == "function");
35
+ return Ve.stubThis(globalThis?.PublicKeyCredential !== void 0 && typeof globalThis.PublicKeyCredential == "function");
36
36
  }
37
- const He = {
37
+ const Ve = {
38
38
  stubThis: (e) => e
39
39
  };
40
40
  function ue(e) {
@@ -407,7 +407,7 @@ function z(e, t, n) {
407
407
  throw new Error("Random bytes length must be >= 16");
408
408
  return a[6] = a[6] & 15 | 64, a[8] = a[8] & 63 | 128, Qe(a);
409
409
  }
410
- const b = "Your session has expired. For your security, please log in again to continue.", tt = "Your session has been successfully terminated.", Q = "Login failed. Please try again.", nt = "Error getting access token, please re-authenticate.", at = "You forgot to wrap your component in <AuthProvider>.", G = "@@auth@@", U = "LOADING", x = "LOGIN", pe = "LOGOUT", L = "success", A = "failure", fe = "include", Te = "POST", ye = "application/json", V = {
410
+ const b = "Your session has expired. For your security, please log in again to continue.", tt = "Your session has been successfully terminated.", Q = "Login failed. Please try again.", nt = "Error getting access token, please re-authenticate.", at = "You forgot to wrap your component in <AuthProvider>.", G = "@@auth@@", U = "LOADING", x = "LOGIN", pe = "LOGOUT", L = "success", A = "failure", fe = "include", Te = "POST", ye = "application/json", H = {
411
411
  GET_REGISTRATION_OPTIONS: `mutation GetPasskeyRegistrationOptions(
412
412
  $clientId: String!,
413
413
  $username: String!,
@@ -490,19 +490,19 @@ const b = "Your session has expired. For your security, please log in again to c
490
490
  }`
491
491
  }, N = {
492
492
  GET_REGISTRATION_OPTIONS: {
493
- schema: V.GET_REGISTRATION_OPTIONS,
493
+ schema: H.GET_REGISTRATION_OPTIONS,
494
494
  method: "getPasskeyRegistrationOptions"
495
495
  },
496
496
  VERIFY_REGISTRATION: {
497
- schema: V.VERIFY_REGISTRATION,
497
+ schema: H.VERIFY_REGISTRATION,
498
498
  method: "verifyPasskeyRegistration"
499
499
  },
500
500
  GET_AUTHENTICATION_OPTIONS: {
501
- schema: V.GET_AUTHENTICATION_OPTIONS,
501
+ schema: H.GET_AUTHENTICATION_OPTIONS,
502
502
  method: "getPasskeyAuthenticationOptions"
503
503
  },
504
504
  VERIFY_AUTHENTICATION: {
505
- schema: V.VERIFY_AUTHENTICATION,
505
+ schema: H.VERIFY_AUTHENTICATION,
506
506
  method: "verifyPasskeyAuthentication"
507
507
  }
508
508
  }, k = async ({
@@ -814,7 +814,7 @@ const P = () => {
814
814
  logoutReason: t.payload.logoutReason
815
815
  } : e, Tt = ({ children: e }) => {
816
816
  const t = ht();
817
- return /* @__PURE__ */ H(Ve.Provider, { value: t, children: e });
817
+ return /* @__PURE__ */ V(He.Provider, { value: t, children: e });
818
818
  }, wt = ({
819
819
  children: e,
820
820
  sessionExpiration: t,
@@ -1083,7 +1083,7 @@ const P = () => {
1083
1083
  }
1084
1084
  return !1;
1085
1085
  };
1086
- return /* @__PURE__ */ H(pt.Provider, { value: { state: c, dispatch: r }, children: /* @__PURE__ */ H(
1086
+ return /* @__PURE__ */ V(pt.Provider, { value: { state: c, dispatch: r }, children: /* @__PURE__ */ V(
1087
1087
  me.Provider,
1088
1088
  {
1089
1089
  value: {
@@ -1095,7 +1095,7 @@ const P = () => {
1095
1095
  registeringForPasskey: be,
1096
1096
  loginWithPasskey: Ne
1097
1097
  },
1098
- children: /* @__PURE__ */ H(Tt, { children: e })
1098
+ children: /* @__PURE__ */ V(Tt, { children: e })
1099
1099
  }
1100
1100
  ) });
1101
1101
  };