@vaadin/hilla-react-auth 24.7.0-alpha9 → 24.8.0-alpha1

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.
@@ -1,35 +1,37 @@
1
- import { type IndexRouteObject, type NonIndexRouteObject } from 'react-router';
2
- import { type AccessProps } from './useAuth.js';
1
+ import { type IndexRouteObject, type NonIndexRouteObject } from "react-router";
2
+ import { type AccessProps } from "./useAuth.js";
3
3
  type CustomMetadata = Record<string, any>;
4
4
  type HandleWithAuth = Readonly<{
5
- handle?: AccessProps & CustomMetadata;
5
+ handle?: AccessProps & CustomMetadata
6
6
  }>;
7
- type Override<T, E> = E & Omit<T, keyof E>;
7
+ type Override<
8
+ T,
9
+ E
10
+ > = E & Omit<T, keyof E>;
8
11
  type IndexRouteObjectWithAuth = Override<IndexRouteObject, HandleWithAuth>;
9
12
  type NonIndexRouteObjectWithAuth = Override<Override<NonIndexRouteObject, HandleWithAuth>, {
10
- children?: RouteObjectWithAuth[];
13
+ children?: RouteObjectWithAuth[]
11
14
  }>;
12
15
  export type RouteObjectWithAuth = IndexRouteObjectWithAuth | NonIndexRouteObjectWithAuth;
13
16
  /**
14
- * Adds protection to a single route that requires authentication.
15
- * These route should contain the {@link AccessProps.loginRequired} and/or
16
- * {@link AccessProps.rolesAllowed} property to get the protection. Route
17
- * without that property won't be protected.
18
- *
19
- * @param route - the route to protect
20
- * @param redirectPath - the path to redirect to if the route is protected
21
- * and the user is not authenticated.
22
- * @returns the route extended with protection if needed
23
- */
17
+ * Adds protection to a single route that requires authentication.
18
+ * These route should contain the {@link AccessProps.loginRequired} and/or
19
+ * {@link AccessProps.rolesAllowed} property to get the protection. Route
20
+ * without that property won't be protected.
21
+ *
22
+ * @param route - the route to protect
23
+ * @param redirectPath - the path to redirect to if the route is protected
24
+ * and the user is not authenticated.
25
+ * @returns the route extended with protection if needed
26
+ */
24
27
  export declare function protectRoute(route: RouteObjectWithAuth, redirectPath?: string): RouteObjectWithAuth;
25
28
  /**
26
- * Protects a route tree with {@link protectRoute} function.
27
- *
28
- * @param routes - the roots of the route tree that requires protection.
29
- * @param redirectPath - the path to redirect to if the route is
30
- * protected and the user is not authenticated.
31
- * @returns the protected route tree
32
- */
29
+ * Protects a route tree with {@link protectRoute} function.
30
+ *
31
+ * @param routes - the roots of the route tree that requires protection.
32
+ * @param redirectPath - the path to redirect to if the route is
33
+ * protected and the user is not authenticated.
34
+ * @returns the protected route tree
35
+ */
33
36
  export declare function protectRoutes(routes: RouteObjectWithAuth[], redirectPath?: string): RouteObjectWithAuth[];
34
37
  export {};
35
- //# sourceMappingURL=ProtectedRoute.d.ts.map
package/ProtectedRoute.js CHANGED
@@ -1,53 +1,70 @@
1
- import { jsx } from "react/jsx-runtime";
2
1
  import { useContext } from "react";
3
2
  import { Navigate, useLocation } from "react-router";
4
3
  import { AuthContext } from "./useAuth.js";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  function ProtectedRoute({ redirectPath, access, element }) {
6
- const {
7
- state: { initializing, loading, user },
8
- hasAccess
9
- } = useContext(AuthContext);
10
- const location = useLocation();
11
- if (initializing || loading) {
12
- return /* @__PURE__ */ jsx("div", {});
13
- }
14
- if (!hasAccess(access)) {
15
- return /* @__PURE__ */ jsx(Navigate, { to: redirectPath, state: { from: location }, replace: true });
16
- }
17
- return element;
6
+ const { state: { initializing, loading }, hasAccess } = useContext(AuthContext);
7
+ const location = useLocation();
8
+ if (initializing || loading) {
9
+ return _jsx(
10
+ "div",
11
+ // This is for copilot to recognize this
12
+ {}
13
+ );
14
+ }
15
+ if (!hasAccess(access)) {
16
+ return _jsx(Navigate, {
17
+ to: redirectPath,
18
+ state: { from: location },
19
+ replace: true
20
+ });
21
+ }
22
+ return element;
18
23
  }
19
24
  ProtectedRoute.type = "ProtectedRoute";
20
25
  function* traverse(routes) {
21
- for (const route of routes) {
22
- yield route;
23
- if (route.children) {
24
- yield* traverse(route.children);
25
- }
26
- }
26
+ for (const route of routes) {
27
+ yield route;
28
+ if (route.children) {
29
+ yield* traverse(route.children);
30
+ }
31
+ }
27
32
  }
28
- function protectRoute(route, redirectPath = "/login") {
29
- const { handle } = route;
30
- const requiresAuth = handle?.loginRequired ?? handle?.requiresLogin ?? handle?.rolesAllowed?.length;
31
- if (requiresAuth) {
32
- route.element = /* @__PURE__ */ jsx(
33
- ProtectedRoute,
34
- {
35
- redirectPath,
36
- access: handle,
37
- element: route.element
38
- }
39
- );
40
- }
41
- return route;
33
+ /**
34
+ * Adds protection to a single route that requires authentication.
35
+ * These route should contain the {@link AccessProps.loginRequired} and/or
36
+ * {@link AccessProps.rolesAllowed} property to get the protection. Route
37
+ * without that property won't be protected.
38
+ *
39
+ * @param route - the route to protect
40
+ * @param redirectPath - the path to redirect to if the route is protected
41
+ * and the user is not authenticated.
42
+ * @returns the route extended with protection if needed
43
+ */
44
+ export function protectRoute(route, redirectPath = "/login") {
45
+ const { handle } = route;
46
+ const requiresAuth = handle?.loginRequired ?? handle?.requiresLogin ?? handle?.rolesAllowed?.length;
47
+ if (requiresAuth) {
48
+ route.element = _jsx(ProtectedRoute, {
49
+ redirectPath,
50
+ access: handle,
51
+ element: route.element
52
+ });
53
+ }
54
+ return route;
42
55
  }
43
- function protectRoutes(routes, redirectPath = "/login") {
44
- for (const route of traverse(routes)) {
45
- protectRoute(route, redirectPath);
46
- }
47
- return routes;
56
+ /**
57
+ * Protects a route tree with {@link protectRoute} function.
58
+ *
59
+ * @param routes - the roots of the route tree that requires protection.
60
+ * @param redirectPath - the path to redirect to if the route is
61
+ * protected and the user is not authenticated.
62
+ * @returns the protected route tree
63
+ */
64
+ export function protectRoutes(routes, redirectPath = "/login") {
65
+ for (const route of traverse(routes)) {
66
+ protectRoute(route, redirectPath);
67
+ }
68
+ return routes;
48
69
  }
49
- export {
50
- protectRoute,
51
- protectRoutes
52
- };
53
- //# sourceMappingURL=ProtectedRoute.js.map
70
+ //# sourceMappingURL=./ProtectedRoute.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/ProtectedRoute.tsx"],
4
- "sourcesContent": ["import { useContext, type JSX } from 'react';\nimport type { RouteObject } from 'react-router';\nimport { type IndexRouteObject, Navigate, type NonIndexRouteObject, useLocation } from 'react-router';\nimport { type AccessProps, AuthContext } from './useAuth.js';\n\ntype CustomMetadata = Record<string, any>;\n\ntype HandleWithAuth = Readonly<{ handle?: AccessProps & CustomMetadata }>;\n\ntype Override<T, E> = E & Omit<T, keyof E>;\n\ntype IndexRouteObjectWithAuth = Override<IndexRouteObject, HandleWithAuth>;\ntype NonIndexRouteObjectWithAuth = Override<\n Override<NonIndexRouteObject, HandleWithAuth>,\n {\n children?: RouteObjectWithAuth[];\n }\n>;\nexport type RouteObjectWithAuth = IndexRouteObjectWithAuth | NonIndexRouteObjectWithAuth;\n\ninterface ProtectedRouteProps {\n redirectPath: string;\n access: AccessProps;\n element: JSX.Element;\n}\n\nfunction ProtectedRoute({ redirectPath, access, element }: ProtectedRouteProps): JSX.Element | null {\n const {\n state: { initializing, loading, user },\n hasAccess,\n } = useContext(AuthContext);\n\n const location = useLocation();\n\n if (initializing || loading) {\n return <div></div>;\n }\n\n if (!hasAccess(access)) {\n return <Navigate to={redirectPath} state={{ from: location }} replace />;\n }\n\n return element;\n}\nProtectedRoute.type = 'ProtectedRoute'; // This is for copilot to recognize this\n\nfunction* traverse<T extends RouteObject>(routes: T[]): Generator<T, undefined, undefined> {\n for (const route of routes) {\n yield route;\n if (route.children) {\n yield* traverse(route.children as T[]);\n }\n }\n}\n\n/**\n * Adds protection to a single route that requires authentication.\n * These route should contain the {@link AccessProps.loginRequired} and/or\n * {@link AccessProps.rolesAllowed} property to get the protection. Route\n * without that property won't be protected.\n *\n * @param route - the route to protect\n * @param redirectPath - the path to redirect to if the route is protected\n * and the user is not authenticated.\n * @returns the route extended with protection if needed\n */\nexport function protectRoute(route: RouteObjectWithAuth, redirectPath: string = '/login'): RouteObjectWithAuth {\n const { handle } = route;\n const requiresAuth = handle?.loginRequired ?? handle?.requiresLogin ?? handle?.rolesAllowed?.length;\n\n if (requiresAuth) {\n route.element = (\n <ProtectedRoute\n redirectPath={redirectPath}\n access={handle as AccessProps}\n element={route.element as JSX.Element}\n />\n );\n }\n\n return route;\n}\n\n/**\n * Protects a route tree with {@link protectRoute} function.\n *\n * @param routes - the roots of the route tree that requires protection.\n * @param redirectPath - the path to redirect to if the route is\n * protected and the user is not authenticated.\n * @returns the protected route tree\n */\nexport function protectRoutes(routes: RouteObjectWithAuth[], redirectPath: string = '/login'): RouteObjectWithAuth[] {\n for (const route of traverse(routes)) {\n protectRoute(route, redirectPath);\n }\n\n return routes;\n}\n"],
5
- "mappings": "AAmCW;AAnCX,SAAS,kBAA4B;AAErC,SAAgC,UAAoC,mBAAmB;AACvF,SAA2B,mBAAmB;AAuB9C,SAAS,eAAe,EAAE,cAAc,QAAQ,QAAQ,GAA4C;AAClG,QAAM;AAAA,IACJ,OAAO,EAAE,cAAc,SAAS,KAAK;AAAA,IACrC;AAAA,EACF,IAAI,WAAW,WAAW;AAE1B,QAAM,WAAW,YAAY;AAE7B,MAAI,gBAAgB,SAAS;AAC3B,WAAO,oBAAC,SAAI;AAAA,EACd;AAEA,MAAI,CAAC,UAAU,MAAM,GAAG;AACtB,WAAO,oBAAC,YAAS,IAAI,cAAc,OAAO,EAAE,MAAM,SAAS,GAAG,SAAO,MAAC;AAAA,EACxE;AAEA,SAAO;AACT;AACA,eAAe,OAAO;AAEtB,UAAU,SAAgC,QAAiD;AACzF,aAAW,SAAS,QAAQ;AAC1B,UAAM;AACN,QAAI,MAAM,UAAU;AAClB,aAAO,SAAS,MAAM,QAAe;AAAA,IACvC;AAAA,EACF;AACF;AAaO,SAAS,aAAa,OAA4B,eAAuB,UAA+B;AAC7G,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,eAAe,QAAQ,iBAAiB,QAAQ,iBAAiB,QAAQ,cAAc;AAE7F,MAAI,cAAc;AAChB,UAAM,UACJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAQ;AAAA,QACR,SAAS,MAAM;AAAA;AAAA,IACjB;AAAA,EAEJ;AAEA,SAAO;AACT;AAUO,SAAS,cAAc,QAA+B,eAAuB,UAAiC;AACnH,aAAW,SAAS,SAAS,MAAM,GAAG;AACpC,iBAAa,OAAO,YAAY;AAAA,EAClC;AAEA,SAAO;AACT;",
6
- "names": []
7
- }
1
+ {"mappings":"AAAA,SAAS,yBAAoC;AAE7C,SAAgC,UAAoC,iCAAkC;AACtG,SAA2B,iCAAkC;;AAuB7D,SAAS,eAAe,EAAE,cAAc,QAAQ,SAA8B,EAAsB;CAClG,MAAM,EACJ,OAAO,EAAE,cAAc,SAAS,EAChC,WACD,GAAG,WAAW,YAAY;CAE3B,MAAM,WAAW,aAAa;AAE9B,KAAI,gBAAgB,SAAS;AAC3B,SAAO;GAAC;;;CAAU;CACnB;AAED,MAAK,UAAU,OAAO,EAAE;AACtB,SAAO,KAAC;GAAS,IAAI;GAAc,OAAO,EAAE,MAAM,SAAU;GAAE;IAAU;CACzE;AAED,QAAO;AACR;AAED,eAAe,OAAO;AAEtB,UAAU,SAAgCA,QAAiD;AACzF,MAAK,MAAM,SAAS,QAAQ;AAC1B,QAAM;AACN,MAAI,MAAM,UAAU;AAClB,UAAO,SAAS,MAAM,SAAgB;EACvC;CACF;AACF;;;;;;;;;;;;AAaD,OAAO,SAAS,aAAaC,OAA4BC,eAAuB,UAA+B;CAC7G,MAAM,EAAE,QAAQ,GAAG;CACnB,MAAM,eAAe,QAAQ,iBAAiB,QAAQ,iBAAiB,QAAQ,cAAc;AAE7F,KAAI,cAAc;AAChB,QAAM,UACJ,KAAC;GACe;GACd,QAAQ;GACR,SAAS,MAAM;IACf;CAEL;AAED,QAAO;AACR;;;;;;;;;AAUD,OAAO,SAAS,cAAcC,QAA+BD,eAAuB,UAAiC;AACnH,MAAK,MAAM,SAAS,SAAS,OAAO,EAAE;AACpC,eAAa,OAAO,aAAa;CAClC;AAED,QAAO;AACR","names":["routes: T[]","route: RouteObjectWithAuth","redirectPath: string","routes: RouteObjectWithAuth[]"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/react-auth/src/ProtectedRoute.tsx"],"sourcesContent":["import { useContext, type JSX } from 'react';\nimport type { RouteObject } from 'react-router';\nimport { type IndexRouteObject, Navigate, type NonIndexRouteObject, useLocation } from 'react-router';\nimport { type AccessProps, AuthContext } from './useAuth.js';\n\ntype CustomMetadata = Record<string, any>;\n\ntype HandleWithAuth = Readonly<{ handle?: AccessProps & CustomMetadata }>;\n\ntype Override<T, E> = E & Omit<T, keyof E>;\n\ntype IndexRouteObjectWithAuth = Override<IndexRouteObject, HandleWithAuth>;\ntype NonIndexRouteObjectWithAuth = Override<\n Override<NonIndexRouteObject, HandleWithAuth>,\n {\n children?: RouteObjectWithAuth[];\n }\n>;\nexport type RouteObjectWithAuth = IndexRouteObjectWithAuth | NonIndexRouteObjectWithAuth;\n\ninterface ProtectedRouteProps {\n redirectPath: string;\n access: AccessProps;\n element: JSX.Element;\n}\n\nfunction ProtectedRoute({ redirectPath, access, element }: ProtectedRouteProps): JSX.Element | null {\n const {\n state: { initializing, loading },\n hasAccess,\n } = useContext(AuthContext);\n\n const location = useLocation();\n\n if (initializing || loading) {\n return <div></div>;\n }\n\n if (!hasAccess(access)) {\n return <Navigate to={redirectPath} state={{ from: location }} replace />;\n }\n\n return element;\n}\n\nProtectedRoute.type = 'ProtectedRoute'; // This is for copilot to recognize this\n\nfunction* traverse<T extends RouteObject>(routes: T[]): Generator<T, undefined, undefined> {\n for (const route of routes) {\n yield route;\n if (route.children) {\n yield* traverse(route.children as T[]);\n }\n }\n}\n\n/**\n * Adds protection to a single route that requires authentication.\n * These route should contain the {@link AccessProps.loginRequired} and/or\n * {@link AccessProps.rolesAllowed} property to get the protection. Route\n * without that property won't be protected.\n *\n * @param route - the route to protect\n * @param redirectPath - the path to redirect to if the route is protected\n * and the user is not authenticated.\n * @returns the route extended with protection if needed\n */\nexport function protectRoute(route: RouteObjectWithAuth, redirectPath: string = '/login'): RouteObjectWithAuth {\n const { handle } = route;\n const requiresAuth = handle?.loginRequired ?? handle?.requiresLogin ?? handle?.rolesAllowed?.length;\n\n if (requiresAuth) {\n route.element = (\n <ProtectedRoute\n redirectPath={redirectPath}\n access={handle as AccessProps}\n element={route.element as JSX.Element}\n />\n );\n }\n\n return route;\n}\n\n/**\n * Protects a route tree with {@link protectRoute} function.\n *\n * @param routes - the roots of the route tree that requires protection.\n * @param redirectPath - the path to redirect to if the route is\n * protected and the user is not authenticated.\n * @returns the protected route tree\n */\nexport function protectRoutes(routes: RouteObjectWithAuth[], redirectPath: string = '/login'): RouteObjectWithAuth[] {\n for (const route of traverse(routes)) {\n protectRoute(route, redirectPath);\n }\n\n return routes;\n}\n"],"version":3}
package/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- export * from './ProtectedRoute.js';
2
- export * from './useAuth.js';
3
- //# sourceMappingURL=index.d.ts.map
1
+ export * from "./ProtectedRoute.js";
2
+ export * from "./useAuth.js";
package/index.js CHANGED
@@ -1,11 +1,10 @@
1
- function __REGISTER__(feature, vaadinObj = window.Vaadin ??= {}) {
2
- vaadinObj.registrations ??= [];
3
- vaadinObj.registrations.push({
4
- is: feature ? `${"@vaadin/hilla-react-auth"}/${feature}` : "@vaadin/hilla-react-auth",
5
- version: "24.7.0-alpha9"
6
- });
7
- }
8
1
  export * from "./ProtectedRoute.js";
9
2
  export * from "./useAuth.js";
10
- __REGISTER__();
11
- //# sourceMappingURL=index.js.map
3
+ ((feature, vaadinObj = window.Vaadin ??= {}) => {
4
+ vaadinObj.registrations ??= [];
5
+ vaadinObj.registrations.push({
6
+ is: feature ? `@vaadin/hilla-react-auth/${feature}` : "@vaadin/hilla-react-auth",
7
+ version: "24.8.0-alpha1"
8
+ });
9
+ })();
10
+ //# sourceMappingURL=./index.js.map
package/index.js.map CHANGED
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../scripts/register.js", "src/index.ts"],
4
- "sourcesContent": ["export function __REGISTER__(feature, vaadinObj = (window.Vaadin ??= {})) {\n vaadinObj.registrations ??= [];\n vaadinObj.registrations.push({\n is: feature ? `${__NAME__}/${feature}` : __NAME__,\n version: __VERSION__,\n });\n}\n", "export * from './ProtectedRoute.js';\nexport * from './useAuth.js';\n\n// @ts-expect-error: esbuild injection\n// eslint-disable-next-line @typescript-eslint/no-unsafe-call\n__REGISTER__();\n"],
5
- "mappings": "AAAO,SAAS,aAAa,SAAS,YAAa,OAAO,WAAW,CAAC,GAAI;AACxE,YAAU,kBAAkB,CAAC;AAC7B,YAAU,cAAc,KAAK;AAAA,IAC3B,IAAI,UAAU,GAAG,0BAAQ,IAAI,OAAO,KAAK;AAAA,IACzC,SAAS;AAAA,EACX,CAAC;AACH;ACNA,cAAc;AACd,cAAc;AAId,aAAa;",
6
- "names": []
7
- }
1
+ {"mappings":"AAAA;AACA;AAIA,CAAC,CAAC,SAAS,YAAa,OAAO,WAAW,CAAE,MAAM;AAChD,WAAU,kBAAkB,CAAE;AAC9B,WAAU,cAAc,KAAK;EAC3B,IAAI,WAAW,2BAA2B,QAAQ,IAAI;EACtD,SAAS;CACV,EAAC;AACH,IAAG","names":[],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/react-auth/src/index.ts"],"sourcesContent":["export * from './ProtectedRoute.js';\nexport * from './useAuth.js';\n\n// @ts-expect-error: esbuild injection\n// eslint-disable-next-line @typescript-eslint/no-unsafe-call\n((feature, vaadinObj = (window.Vaadin ??= {})) => {\n vaadinObj.registrations ??= [];\n vaadinObj.registrations.push({\n is: feature ? `@vaadin/hilla-react-auth/${feature}` : '@vaadin/hilla-react-auth',\n version: '24.8.0-alpha1',\n });\n})();\n"],"version":3}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/hilla-react-auth",
3
- "version": "24.7.0-alpha9",
3
+ "version": "24.8.0-alpha1",
4
4
  "description": "Hilla auth utils for React",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
@@ -17,15 +17,12 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "clean:build": "git clean -fx . -e .vite -e node_modules",
20
- "build": "concurrently npm:build:*",
21
- "build:esbuild": "tsx ../../../scripts/build.ts",
22
- "build:dts": "tsc --isolatedModules -p tsconfig.build.json",
23
- "build:copy": "cd src && copyfiles **/*.d.ts ..",
20
+ "build": "tsx ../../../scripts/fast-build.ts",
24
21
  "lint": "eslint src test",
25
22
  "lint:fix": "eslint src test --fix",
26
- "test": "npx --node-options=\"--import tsx\" wtr --config ../../../wtr.config.ts",
27
- "test:coverage": "npm run test -- --coverage",
28
- "test:watch": "npm run test -- --watch",
23
+ "test": "vitest --run",
24
+ "test:coverage": "vitest --run --coverage",
25
+ "test:watch": "vitest",
29
26
  "typecheck": "tsc --noEmit"
30
27
  },
31
28
  "exports": {
@@ -46,31 +43,11 @@
46
43
  "access": "public"
47
44
  },
48
45
  "dependencies": {
49
- "@vaadin/hilla-frontend": "24.7.0-alpha9"
46
+ "@vaadin/hilla-frontend": "24.8.0-alpha1"
50
47
  },
51
48
  "peerDependencies": {
52
49
  "react": "18 || 19",
53
50
  "react-dom": "18 || 19",
54
- "react-router": "^7"
55
- },
56
- "devDependencies": {
57
- "@testing-library/dom": "^10.4.0",
58
- "@testing-library/react": "^16.1.0",
59
- "@testing-library/user-event": "^14.5.2",
60
- "@types/chai": "^4.3.20",
61
- "@types/chai-dom": "^1.11.3",
62
- "@types/mocha": "^10.0.10",
63
- "@types/react": "^18.3.18",
64
- "@types/react-dom": "^18",
65
- "@types/sinon": "^10.0.20",
66
- "@types/sinon-chai": "^3.2.12",
67
- "@types/validator": "^13.12.2",
68
- "@web/test-runner": "^0.19.0",
69
- "chai": "^5.1.2",
70
- "chai-dom": "^1.12.0",
71
- "react-router": "^7.1.1",
72
- "sinon": "^16.1.3",
73
- "sinon-chai": "^3.7.0",
74
- "typescript": "5.7.3"
51
+ "react-router": "7"
75
52
  }
76
53
  }
package/useAuth.d.ts CHANGED
@@ -1,70 +1,59 @@
1
- import { type LoginResult } from '@vaadin/hilla-frontend';
2
- type LoginFunction = (username: string, password: string) => Promise<LoginResult>;
1
+ import { type LoginOptions, type LoginResult } from "@vaadin/hilla-frontend";
2
+ import { type Context } from "react";
3
+ type LoginFunction = (username: string, password: string, options?: LoginOptions) => Promise<LoginResult>;
3
4
  type LogoutFunction = () => Promise<void>;
4
5
  /**
5
- * The type of the function that is used to get the authenticated user.
6
- */
6
+ * The type of the function that is used to get the authenticated user.
7
+ */
7
8
  export type GetUserFn<TUser> = () => Promise<TUser | undefined>;
8
9
  type AuthState<TUser> = Readonly<{
9
- initializing: boolean;
10
- loading: boolean;
11
- user?: TUser;
12
- error?: string;
13
- getAuthenticatedUser?: GetUserFn<TUser>;
10
+ initializing: boolean
11
+ loading: boolean
12
+ user?: TUser
13
+ error?: string
14
+ getAuthenticatedUser?: GetUserFn<TUser>
14
15
  }>;
15
16
  /**
16
- * The properties that can be used to control access to a route.
17
- * They can be added to the route type handler as properties.
18
- */
17
+ * The properties that can be used to control access to a route.
18
+ * They can be added to the route type handler as properties.
19
+ */
19
20
  export type AccessProps = Readonly<{
20
- /**
21
- * If true, the user must be logged in to access the route.
22
- */
23
- loginRequired?: boolean;
24
- /**
25
- * If true, the user must be logged in to access the route.
26
- *
27
- * @deprecated Use `loginRequired` instead.
28
- */
29
- requiresLogin?: boolean;
30
- /**
31
- * The list of roles that are allowed to access the route.
32
- */
33
- rolesAllowed?: readonly [string, ...string[]];
21
+ /**
22
+ * If true, the user must be logged in to access the route.
23
+ */
24
+ loginRequired?: boolean
25
+ /**
26
+ * If true, the user must be logged in to access the route.
27
+ *
28
+ * @deprecated Use `loginRequired` instead.
29
+ */
30
+ requiresLogin?: boolean
31
+ /**
32
+ * The list of roles that are allowed to access the route.
33
+ */
34
+ rolesAllowed?: readonly [string, ...string[]]
34
35
  }>;
35
36
  /**
36
- * The type of the authentication hook.
37
- */
37
+ * The type of the authentication hook.
38
+ */
38
39
  export type Authentication<TUser> = Readonly<{
39
- state: AuthState<TUser>;
40
- login: LoginFunction;
41
- logout: LogoutFunction;
42
- hasAccess(accessProps: AccessProps): boolean;
40
+ state: AuthState<TUser>
41
+ login: LoginFunction
42
+ logout: LogoutFunction
43
+ hasAccess(accessProps: AccessProps): boolean
43
44
  }>;
44
45
  /**
45
- * The hook that can be used to get the authentication state.
46
- * It returns the state of the authentication.
47
- */
48
- export declare const AuthContext: import("react").Context<Readonly<{
49
- state: Readonly<{
50
- initializing: boolean;
51
- loading: boolean;
52
- user?: unknown;
53
- error?: string;
54
- getAuthenticatedUser?: GetUserFn<unknown> | undefined;
55
- }>;
56
- login: LoginFunction;
57
- logout: LogoutFunction;
58
- hasAccess(accessProps: AccessProps): boolean;
59
- }>>;
46
+ * The hook that can be used to get the authentication state.
47
+ * It returns the state of the authentication.
48
+ */
49
+ export declare const AuthContext: Context<Authentication<unknown>>;
60
50
  interface AuthConfig<TUser> {
61
- getRoles?(user: TUser): readonly string[];
51
+ getRoles?(user: TUser): readonly string[];
62
52
  }
63
53
  export type AuthHook<TUser> = () => Authentication<TUser>;
64
54
  interface AuthModule<TUser> {
65
- AuthProvider: React.FC<React.PropsWithChildren>;
66
- useAuth: AuthHook<TUser>;
55
+ AuthProvider: React.FC<React.PropsWithChildren>;
56
+ useAuth: AuthHook<TUser>;
67
57
  }
68
58
  export declare function configureAuth<TUser>(getAuthenticatedUser: GetUserFn<TUser>, config?: AuthConfig<TUser>): AuthModule<TUser>;
69
59
  export {};
70
- //# sourceMappingURL=useAuth.d.ts.map
package/useAuth.js CHANGED
@@ -1,142 +1,147 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import {
3
- login as _login,
4
- logout as _logout,
5
- UnauthorizedResponseError
6
- } from "@vaadin/hilla-frontend";
1
+ import { login as _login, logout as _logout, UnauthorizedResponseError } from "@vaadin/hilla-frontend";
7
2
  import { createContext, useContext, useEffect, useReducer } from "react";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
8
4
  const LOGIN_FETCH = "LOGIN_FETCH";
9
5
  const LOGIN_SUCCESS = "LOGIN_SUCCESS";
10
6
  const LOGIN_FAILURE = "LOGIN_FAILURE";
11
7
  const LOGOUT = "LOGOUT";
12
8
  function createAuthenticateThunk(dispatch, getAuthenticatedUser) {
13
- async function authenticate() {
14
- dispatch({ type: LOGIN_FETCH });
15
- const user = await getAuthenticatedUser().catch((error) => {
16
- if (error instanceof UnauthorizedResponseError) {
17
- return void 0;
18
- }
19
- throw error;
20
- });
21
- if (user) {
22
- dispatch({
23
- user,
24
- type: LOGIN_SUCCESS
25
- });
26
- } else {
27
- dispatch({
28
- error: "Not authenticated",
29
- type: LOGIN_FAILURE
30
- });
31
- }
32
- }
33
- return authenticate;
9
+ async function authenticate() {
10
+ dispatch({ type: LOGIN_FETCH });
11
+ const user = await getAuthenticatedUser().catch((error) => {
12
+ if (error instanceof UnauthorizedResponseError) {
13
+ return undefined;
14
+ }
15
+ throw error;
16
+ });
17
+ if (user) {
18
+ dispatch({
19
+ user,
20
+ type: LOGIN_SUCCESS
21
+ });
22
+ } else {
23
+ dispatch({
24
+ error: "Not authenticated",
25
+ type: LOGIN_FAILURE
26
+ });
27
+ }
28
+ }
29
+ return authenticate;
34
30
  }
35
31
  function createUnauthenticateThunk(dispatch) {
36
- return () => {
37
- dispatch({ type: LOGOUT });
38
- };
32
+ return () => {
33
+ dispatch({ type: LOGOUT });
34
+ };
39
35
  }
40
36
  const initialState = {
41
- initializing: true,
42
- loading: false
37
+ initializing: true,
38
+ loading: false
43
39
  };
44
40
  function reducer(state, action) {
45
- switch (action.type) {
46
- case LOGIN_FETCH:
47
- return {
48
- initializing: false,
49
- loading: true
50
- };
51
- case LOGIN_SUCCESS:
52
- return {
53
- initializing: false,
54
- loading: false,
55
- user: action.user
56
- };
57
- case LOGIN_FAILURE:
58
- return {
59
- initializing: false,
60
- loading: false,
61
- error: action.error
62
- };
63
- case LOGOUT:
64
- return { initializing: false, loading: false };
65
- default:
66
- return state;
67
- }
41
+ switch (action.type) {
42
+ case LOGIN_FETCH: return {
43
+ initializing: false,
44
+ loading: true
45
+ };
46
+ case LOGIN_SUCCESS: return {
47
+ initializing: false,
48
+ loading: false,
49
+ user: action.user
50
+ };
51
+ case LOGIN_FAILURE: return {
52
+ initializing: false,
53
+ loading: false,
54
+ error: action.error
55
+ };
56
+ case LOGOUT: return {
57
+ initializing: false,
58
+ loading: false
59
+ };
60
+ default: return state;
61
+ }
68
62
  }
69
- const AuthContext = createContext({
70
- state: initialState,
71
- login() {
72
- throw new Error("AuthContext not initialized");
73
- },
74
- logout() {
75
- throw new Error("AuthContext not initialized");
76
- },
77
- hasAccess() {
78
- throw new Error("AuthContext not initialized");
79
- }
63
+ /**
64
+ * The hook that can be used to get the authentication state.
65
+ * It returns the state of the authentication.
66
+ */
67
+ export const AuthContext = createContext({
68
+ state: initialState,
69
+ login() {
70
+ throw new Error("AuthContext not initialized");
71
+ },
72
+ logout() {
73
+ throw new Error("AuthContext not initialized");
74
+ },
75
+ hasAccess() {
76
+ throw new Error("AuthContext not initialized");
77
+ }
80
78
  });
81
79
  const getDefaultRoles = (user) => {
82
- const userWithRoles = user;
83
- return Array.isArray(userWithRoles.roles) ? userWithRoles.roles : [];
80
+ const userWithRoles = user;
81
+ return Array.isArray(userWithRoles.roles) ? userWithRoles.roles : [];
84
82
  };
85
83
  function AuthProvider({ children, getAuthenticatedUser, config }) {
86
- const [state, dispatch] = useReducer(reducer, initialState);
87
- const authenticate = createAuthenticateThunk(dispatch, getAuthenticatedUser);
88
- const unauthenticate = createUnauthenticateThunk(dispatch);
89
- async function login(username, password, options) {
90
- const result = await _login(username, password, options);
91
- if (!result.error) {
92
- await authenticate();
93
- }
94
- return result;
95
- }
96
- async function logout(options) {
97
- await _logout(options);
98
- unauthenticate();
99
- }
100
- function hasAccess({ loginRequired, requiresLogin, rolesAllowed }) {
101
- const requiresAuth = loginRequired ?? requiresLogin ?? rolesAllowed;
102
- if (!requiresAuth) {
103
- return true;
104
- }
105
- if (!state.user) {
106
- return false;
107
- }
108
- if (rolesAllowed) {
109
- const userRoles = config?.getRoles ? config.getRoles(state.user) : getDefaultRoles(state.user);
110
- return rolesAllowed.some((allowedRole) => userRoles.includes(allowedRole));
111
- }
112
- return true;
113
- }
114
- useEffect(() => {
115
- authenticate().catch(() => {
116
- });
117
- }, []);
118
- const auth = {
119
- state,
120
- login,
121
- logout,
122
- hasAccess
123
- };
124
- return /* @__PURE__ */ jsx(AuthContext.Provider, { value: auth, children });
84
+ const [state, dispatch] = useReducer(reducer, initialState);
85
+ const authenticate = createAuthenticateThunk(dispatch, getAuthenticatedUser);
86
+ const unauthenticate = createUnauthenticateThunk(dispatch);
87
+ async function login(username, password, options) {
88
+ const result = await _login(username, password, options);
89
+ if (!result.error) {
90
+ await authenticate();
91
+ }
92
+ return result;
93
+ }
94
+ async function logout(options) {
95
+ await _logout(options);
96
+ unauthenticate();
97
+ }
98
+ function hasAccess({ loginRequired, requiresLogin, rolesAllowed }) {
99
+ const requiresAuth = loginRequired ?? requiresLogin ?? rolesAllowed;
100
+ if (!requiresAuth) {
101
+ return true;
102
+ }
103
+ if (!state.user) {
104
+ return false;
105
+ }
106
+ if (rolesAllowed) {
107
+ const userRoles = config?.getRoles ? config.getRoles(state.user) : getDefaultRoles(state.user);
108
+ return rolesAllowed.some((allowedRole) => userRoles.includes(allowedRole));
109
+ }
110
+ return true;
111
+ }
112
+ useEffect(() => {
113
+ authenticate().catch(() => {});
114
+ }, []);
115
+ const auth = {
116
+ state,
117
+ login,
118
+ logout,
119
+ hasAccess
120
+ };
121
+ return _jsx(AuthContext.Provider, {
122
+ value: auth,
123
+ children
124
+ });
125
125
  }
126
+ /**
127
+ * The hook that can be used to authenticate the user.
128
+ * It returns the state of the authentication and the functions
129
+ * to authenticate and unauthenticate the user.
130
+ */
126
131
  function useAuth() {
127
- return useContext(AuthContext);
132
+ return useContext(AuthContext);
128
133
  }
129
- function configureAuth(getAuthenticatedUser, config) {
130
- function PreconfiguredAuthProvider({ children }) {
131
- return /* @__PURE__ */ jsx(AuthProvider, { getAuthenticatedUser, config, children });
132
- }
133
- return {
134
- AuthProvider: PreconfiguredAuthProvider,
135
- useAuth
136
- };
134
+ export function configureAuth(getAuthenticatedUser, config) {
135
+ function PreconfiguredAuthProvider({ children }) {
136
+ return _jsx(AuthProvider, {
137
+ getAuthenticatedUser,
138
+ config,
139
+ children
140
+ });
141
+ }
142
+ return {
143
+ AuthProvider: PreconfiguredAuthProvider,
144
+ useAuth
145
+ };
137
146
  }
138
- export {
139
- AuthContext,
140
- configureAuth
141
- };
142
- //# sourceMappingURL=useAuth.js.map
147
+ //# sourceMappingURL=./useAuth.js.map
package/useAuth.js.map CHANGED
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/useAuth.tsx"],
4
- "sourcesContent": ["import {\n login as _login,\n type LoginOptions,\n type LoginResult,\n logout as _logout,\n type LogoutOptions,\n UnauthorizedResponseError,\n} from '@vaadin/hilla-frontend';\nimport { createContext, type Dispatch, useContext, useEffect, useReducer } from 'react';\n\ntype LoginFunction = (username: string, password: string) => Promise<LoginResult>;\ntype LogoutFunction = () => Promise<void>;\n\nconst LOGIN_FETCH = 'LOGIN_FETCH';\nconst LOGIN_SUCCESS = 'LOGIN_SUCCESS';\nconst LOGIN_FAILURE = 'LOGIN_FAILURE';\nconst LOGOUT = 'LOGOUT';\n\n/**\n * The type of the function that is used to get the authenticated user.\n */\nexport type GetUserFn<TUser> = () => Promise<TUser | undefined>;\n\ntype AuthState<TUser> = Readonly<{\n initializing: boolean;\n loading: boolean;\n user?: TUser;\n error?: string;\n getAuthenticatedUser?: GetUserFn<TUser>;\n}>;\n\ntype LoginFetchAction = Readonly<{\n type: typeof LOGIN_FETCH;\n}>;\n\ntype LoginSuccessAction = Readonly<{\n user: unknown;\n type: typeof LOGIN_SUCCESS;\n}>;\n\ntype LoginFailureAction = Readonly<{\n error: string;\n type: typeof LOGIN_FAILURE;\n}>;\n\ntype LoginActions = LoginFailureAction | LoginFetchAction | LoginSuccessAction;\n\ntype LogoutAction = Readonly<{\n type: typeof LOGOUT;\n}>;\n\nfunction createAuthenticateThunk<TUser>(dispatch: Dispatch<LoginActions>, getAuthenticatedUser: GetUserFn<TUser>) {\n async function authenticate() {\n dispatch({ type: LOGIN_FETCH });\n\n // Get user info from endpoint\n const user = await getAuthenticatedUser().catch((error: unknown) => {\n if (error instanceof UnauthorizedResponseError) {\n // 401 response: the user is not authenticated\n return undefined;\n }\n\n throw error;\n });\n\n if (user) {\n dispatch({\n user,\n type: LOGIN_SUCCESS,\n });\n } else {\n dispatch({\n error: 'Not authenticated',\n type: LOGIN_FAILURE,\n });\n }\n }\n\n return authenticate;\n}\n\nfunction createUnauthenticateThunk(dispatch: Dispatch<LogoutAction>) {\n return () => {\n dispatch({ type: LOGOUT });\n };\n}\n\nconst initialState: AuthState<unknown> = {\n initializing: true,\n loading: false,\n};\n\nfunction reducer(state: AuthState<unknown>, action: LoginActions | LogoutAction) {\n switch (action.type) {\n case LOGIN_FETCH:\n return {\n initializing: false,\n loading: true,\n };\n case LOGIN_SUCCESS:\n return {\n initializing: false,\n loading: false,\n user: action.user,\n };\n case LOGIN_FAILURE:\n return {\n initializing: false,\n loading: false,\n error: action.error,\n };\n case LOGOUT:\n return { initializing: false, loading: false };\n default:\n return state;\n }\n}\n\n/**\n * The properties that can be used to control access to a route.\n * They can be added to the route type handler as properties.\n */\nexport type AccessProps = Readonly<{\n /**\n * If true, the user must be logged in to access the route.\n */\n loginRequired?: boolean;\n /**\n * If true, the user must be logged in to access the route.\n *\n * @deprecated Use `loginRequired` instead.\n */\n requiresLogin?: boolean;\n /**\n * The list of roles that are allowed to access the route.\n */\n rolesAllowed?: readonly [string, ...string[]];\n}>;\n\n/**\n * The type of the authentication hook.\n */\nexport type Authentication<TUser> = Readonly<{\n state: AuthState<TUser>;\n login: LoginFunction;\n logout: LogoutFunction;\n hasAccess(accessProps: AccessProps): boolean;\n}>;\n\n/**\n * The hook that can be used to get the authentication state.\n * It returns the state of the authentication.\n */\nexport const AuthContext = createContext<Authentication<unknown>>({\n state: initialState,\n login() {\n throw new Error('AuthContext not initialized');\n },\n logout() {\n throw new Error('AuthContext not initialized');\n },\n hasAccess(): boolean {\n throw new Error('AuthContext not initialized');\n },\n});\n\ninterface AuthConfig<TUser> {\n getRoles?(user: TUser): readonly string[];\n}\n\ninterface AuthProviderProps<TUser> extends React.PropsWithChildren {\n getAuthenticatedUser: GetUserFn<TUser>;\n config?: AuthConfig<TUser>;\n}\n\ninterface UserWithRoles {\n roles?: any;\n}\n\nconst getDefaultRoles = (user: unknown) => {\n const userWithRoles = user as UserWithRoles;\n return Array.isArray(userWithRoles.roles) ? userWithRoles.roles : [];\n};\n\nfunction AuthProvider<TUser>({ children, getAuthenticatedUser, config }: AuthProviderProps<TUser>) {\n const [state, dispatch] = useReducer(reducer, initialState);\n const authenticate = createAuthenticateThunk(dispatch, getAuthenticatedUser);\n const unauthenticate = createUnauthenticateThunk(dispatch);\n\n async function login(username: string, password: string, options?: LoginOptions): Promise<LoginResult> {\n const result = await _login(username, password, options);\n\n if (!result.error) {\n await authenticate();\n }\n\n return result;\n }\n\n async function logout(options?: LogoutOptions): Promise<void> {\n await _logout(options);\n unauthenticate();\n }\n\n function hasAccess({ loginRequired, requiresLogin, rolesAllowed }: AccessProps): boolean {\n const requiresAuth = loginRequired ?? requiresLogin ?? rolesAllowed;\n if (!requiresAuth) {\n return true;\n }\n\n if (!state.user) {\n return false;\n }\n\n if (rolesAllowed) {\n const userRoles = config?.getRoles ? config.getRoles(state.user as TUser) : getDefaultRoles(state.user);\n return rolesAllowed.some((allowedRole) => userRoles.includes(allowedRole));\n }\n\n return true;\n }\n\n useEffect(() => {\n authenticate().catch(() => {\n // Do nothing\n });\n }, []);\n\n const auth = {\n state,\n login,\n logout,\n hasAccess,\n };\n\n return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;\n}\n\nexport type AuthHook<TUser> = () => Authentication<TUser>;\n\n/**\n * The hook that can be used to authenticate the user.\n * It returns the state of the authentication and the functions\n * to authenticate and unauthenticate the user.\n */\nfunction useAuth<TUser>(): Authentication<TUser> {\n return useContext(AuthContext) as Authentication<TUser>;\n}\n\ninterface AuthModule<TUser> {\n AuthProvider: React.FC<React.PropsWithChildren>;\n useAuth: AuthHook<TUser>;\n}\n\nexport function configureAuth<TUser>(\n getAuthenticatedUser: GetUserFn<TUser>,\n config?: AuthConfig<TUser>,\n): AuthModule<TUser> {\n function PreconfiguredAuthProvider({ children }: React.PropsWithChildren) {\n return (\n <AuthProvider<TUser> getAuthenticatedUser={getAuthenticatedUser} config={config}>\n {children}\n </AuthProvider>\n );\n }\n\n return {\n AuthProvider: PreconfiguredAuthProvider,\n useAuth: useAuth as AuthHook<TUser>,\n };\n}\n"],
5
- "mappings": "AA2OS;AA3OT;AAAA,EACE,SAAS;AAAA,EAGT,UAAU;AAAA,EAEV;AAAA,OACK;AACP,SAAS,eAA8B,YAAY,WAAW,kBAAkB;AAKhF,MAAM,cAAc;AACpB,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AACtB,MAAM,SAAS;AAmCf,SAAS,wBAA+B,UAAkC,sBAAwC;AAChH,iBAAe,eAAe;AAC5B,aAAS,EAAE,MAAM,YAAY,CAAC;AAG9B,UAAM,OAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,UAAmB;AAClE,UAAI,iBAAiB,2BAA2B;AAE9C,eAAO;AAAA,MACT;AAEA,YAAM;AAAA,IACR,CAAC;AAED,QAAI,MAAM;AACR,eAAS;AAAA,QACP;AAAA,QACA,MAAM;AAAA,MACR,CAAC;AAAA,IACH,OAAO;AACL,eAAS;AAAA,QACP,OAAO;AAAA,QACP,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,0BAA0B,UAAkC;AACnE,SAAO,MAAM;AACX,aAAS,EAAE,MAAM,OAAO,CAAC;AAAA,EAC3B;AACF;AAEA,MAAM,eAAmC;AAAA,EACvC,cAAc;AAAA,EACd,SAAS;AACX;AAEA,SAAS,QAAQ,OAA2B,QAAqC;AAC/E,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,QACL,cAAc;AAAA,QACd,SAAS;AAAA,MACX;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,cAAc;AAAA,QACd,SAAS;AAAA,QACT,MAAM,OAAO;AAAA,MACf;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,cAAc;AAAA,QACd,SAAS;AAAA,QACT,OAAO,OAAO;AAAA,MAChB;AAAA,IACF,KAAK;AACH,aAAO,EAAE,cAAc,OAAO,SAAS,MAAM;AAAA,IAC/C;AACE,aAAO;AAAA,EACX;AACF;AAqCO,MAAM,cAAc,cAAuC;AAAA,EAChE,OAAO;AAAA,EACP,QAAQ;AACN,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAAA,EACA,SAAS;AACP,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAAA,EACA,YAAqB;AACnB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACF,CAAC;AAeD,MAAM,kBAAkB,CAAC,SAAkB;AACzC,QAAM,gBAAgB;AACtB,SAAO,MAAM,QAAQ,cAAc,KAAK,IAAI,cAAc,QAAQ,CAAC;AACrE;AAEA,SAAS,aAAoB,EAAE,UAAU,sBAAsB,OAAO,GAA6B;AACjG,QAAM,CAAC,OAAO,QAAQ,IAAI,WAAW,SAAS,YAAY;AAC1D,QAAM,eAAe,wBAAwB,UAAU,oBAAoB;AAC3E,QAAM,iBAAiB,0BAA0B,QAAQ;AAEzD,iBAAe,MAAM,UAAkB,UAAkB,SAA8C;AACrG,UAAM,SAAS,MAAM,OAAO,UAAU,UAAU,OAAO;AAEvD,QAAI,CAAC,OAAO,OAAO;AACjB,YAAM,aAAa;AAAA,IACrB;AAEA,WAAO;AAAA,EACT;AAEA,iBAAe,OAAO,SAAwC;AAC5D,UAAM,QAAQ,OAAO;AACrB,mBAAe;AAAA,EACjB;AAEA,WAAS,UAAU,EAAE,eAAe,eAAe,aAAa,GAAyB;AACvF,UAAM,eAAe,iBAAiB,iBAAiB;AACvD,QAAI,CAAC,cAAc;AACjB,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,MAAM,MAAM;AACf,aAAO;AAAA,IACT;AAEA,QAAI,cAAc;AAChB,YAAM,YAAY,QAAQ,WAAW,OAAO,SAAS,MAAM,IAAa,IAAI,gBAAgB,MAAM,IAAI;AACtG,aAAO,aAAa,KAAK,CAAC,gBAAgB,UAAU,SAAS,WAAW,CAAC;AAAA,IAC3E;AAEA,WAAO;AAAA,EACT;AAEA,YAAU,MAAM;AACd,iBAAa,EAAE,MAAM,MAAM;AAAA,IAE3B,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAO,MAAO,UAAS;AACtD;AASA,SAAS,UAAwC;AAC/C,SAAO,WAAW,WAAW;AAC/B;AAOO,SAAS,cACd,sBACA,QACmB;AACnB,WAAS,0BAA0B,EAAE,SAAS,GAA4B;AACxE,WACE,oBAAC,gBAAoB,sBAA4C,QAC9D,UACH;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,cAAc;AAAA,IACd;AAAA,EACF;AACF;",
6
- "names": []
7
- }
1
+ {"mappings":"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","names":["dispatch: Dispatch<LoginActions>","getAuthenticatedUser: GetUserFn<TUser>","error: unknown","dispatch: Dispatch<LogoutAction>","initialState: AuthState<unknown>","state: AuthState<unknown>","action: LoginActions | LogoutAction","AuthContext: Context<Authentication<unknown>>","user: unknown","username: string","password: string","options?: LoginOptions","options?: LogoutOptions","config?: AuthConfig<TUser>"],"sources":["/opt/agent/work/1af72d8adc613024/hilla/packages/ts/react-auth/src/useAuth.tsx"],"sourcesContent":["import {\n login as _login,\n type LoginOptions,\n type LoginResult,\n logout as _logout,\n type LogoutOptions,\n UnauthorizedResponseError,\n} from '@vaadin/hilla-frontend';\nimport { type Context, createContext, type Dispatch, useContext, useEffect, useReducer } from 'react';\n\ntype LoginFunction = (username: string, password: string, options?: LoginOptions) => Promise<LoginResult>;\ntype LogoutFunction = () => Promise<void>;\n\nconst LOGIN_FETCH = 'LOGIN_FETCH';\nconst LOGIN_SUCCESS = 'LOGIN_SUCCESS';\nconst LOGIN_FAILURE = 'LOGIN_FAILURE';\nconst LOGOUT = 'LOGOUT';\n\n/**\n * The type of the function that is used to get the authenticated user.\n */\nexport type GetUserFn<TUser> = () => Promise<TUser | undefined>;\n\ntype AuthState<TUser> = Readonly<{\n initializing: boolean;\n loading: boolean;\n user?: TUser;\n error?: string;\n getAuthenticatedUser?: GetUserFn<TUser>;\n}>;\n\ntype LoginFetchAction = Readonly<{\n type: typeof LOGIN_FETCH;\n}>;\n\ntype LoginSuccessAction = Readonly<{\n user: unknown;\n type: typeof LOGIN_SUCCESS;\n}>;\n\ntype LoginFailureAction = Readonly<{\n error: string;\n type: typeof LOGIN_FAILURE;\n}>;\n\ntype LoginActions = LoginFailureAction | LoginFetchAction | LoginSuccessAction;\n\ntype LogoutAction = Readonly<{\n type: typeof LOGOUT;\n}>;\n\nfunction createAuthenticateThunk<TUser>(dispatch: Dispatch<LoginActions>, getAuthenticatedUser: GetUserFn<TUser>) {\n async function authenticate() {\n dispatch({ type: LOGIN_FETCH });\n\n // Get user info from endpoint\n const user = await getAuthenticatedUser().catch((error: unknown) => {\n if (error instanceof UnauthorizedResponseError) {\n // 401 response: the user is not authenticated\n return undefined;\n }\n\n throw error;\n });\n\n if (user) {\n dispatch({\n user,\n type: LOGIN_SUCCESS,\n });\n } else {\n dispatch({\n error: 'Not authenticated',\n type: LOGIN_FAILURE,\n });\n }\n }\n\n return authenticate;\n}\n\nfunction createUnauthenticateThunk(dispatch: Dispatch<LogoutAction>) {\n return () => {\n dispatch({ type: LOGOUT });\n };\n}\n\nconst initialState: AuthState<unknown> = {\n initializing: true,\n loading: false,\n};\n\nfunction reducer(state: AuthState<unknown>, action: LoginActions | LogoutAction) {\n switch (action.type) {\n case LOGIN_FETCH:\n return {\n initializing: false,\n loading: true,\n };\n case LOGIN_SUCCESS:\n return {\n initializing: false,\n loading: false,\n user: action.user,\n };\n case LOGIN_FAILURE:\n return {\n initializing: false,\n loading: false,\n error: action.error,\n };\n case LOGOUT:\n return { initializing: false, loading: false };\n default:\n return state;\n }\n}\n\n/**\n * The properties that can be used to control access to a route.\n * They can be added to the route type handler as properties.\n */\nexport type AccessProps = Readonly<{\n /**\n * If true, the user must be logged in to access the route.\n */\n loginRequired?: boolean;\n /**\n * If true, the user must be logged in to access the route.\n *\n * @deprecated Use `loginRequired` instead.\n */\n requiresLogin?: boolean;\n /**\n * The list of roles that are allowed to access the route.\n */\n rolesAllowed?: readonly [string, ...string[]];\n}>;\n\n/**\n * The type of the authentication hook.\n */\nexport type Authentication<TUser> = Readonly<{\n state: AuthState<TUser>;\n login: LoginFunction;\n logout: LogoutFunction;\n hasAccess(accessProps: AccessProps): boolean;\n}>;\n\n/**\n * The hook that can be used to get the authentication state.\n * It returns the state of the authentication.\n */\nexport const AuthContext: Context<Authentication<unknown>> = createContext<Authentication<unknown>>({\n state: initialState,\n login() {\n throw new Error('AuthContext not initialized');\n },\n logout() {\n throw new Error('AuthContext not initialized');\n },\n hasAccess(): boolean {\n throw new Error('AuthContext not initialized');\n },\n});\n\ninterface AuthConfig<TUser> {\n getRoles?(user: TUser): readonly string[];\n}\n\ninterface AuthProviderProps<TUser> extends React.PropsWithChildren {\n getAuthenticatedUser: GetUserFn<TUser>;\n config?: AuthConfig<TUser>;\n}\n\ninterface UserWithRoles {\n roles?: any;\n}\n\nconst getDefaultRoles = (user: unknown) => {\n const userWithRoles = user as UserWithRoles;\n return Array.isArray(userWithRoles.roles) ? userWithRoles.roles : [];\n};\n\nfunction AuthProvider<TUser>({ children, getAuthenticatedUser, config }: AuthProviderProps<TUser>) {\n const [state, dispatch] = useReducer(reducer, initialState);\n const authenticate = createAuthenticateThunk(dispatch, getAuthenticatedUser);\n const unauthenticate = createUnauthenticateThunk(dispatch);\n\n async function login(username: string, password: string, options?: LoginOptions): Promise<LoginResult> {\n const result = await _login(username, password, options);\n\n if (!result.error) {\n await authenticate();\n }\n\n return result;\n }\n\n async function logout(options?: LogoutOptions): Promise<void> {\n await _logout(options);\n unauthenticate();\n }\n\n function hasAccess({ loginRequired, requiresLogin, rolesAllowed }: AccessProps): boolean {\n const requiresAuth = loginRequired ?? requiresLogin ?? rolesAllowed;\n if (!requiresAuth) {\n return true;\n }\n\n if (!state.user) {\n return false;\n }\n\n if (rolesAllowed) {\n const userRoles = config?.getRoles ? config.getRoles(state.user as TUser) : getDefaultRoles(state.user);\n return rolesAllowed.some((allowedRole) => userRoles.includes(allowedRole));\n }\n\n return true;\n }\n\n useEffect(() => {\n authenticate().catch(() => {\n // Do nothing\n });\n }, []);\n\n const auth = {\n state,\n login,\n logout,\n hasAccess,\n };\n\n return <AuthContext.Provider value={auth}>{children}</AuthContext.Provider>;\n}\n\nexport type AuthHook<TUser> = () => Authentication<TUser>;\n\n/**\n * The hook that can be used to authenticate the user.\n * It returns the state of the authentication and the functions\n * to authenticate and unauthenticate the user.\n */\nfunction useAuth<TUser>(): Authentication<TUser> {\n return useContext(AuthContext) as Authentication<TUser>;\n}\n\ninterface AuthModule<TUser> {\n AuthProvider: React.FC<React.PropsWithChildren>;\n useAuth: AuthHook<TUser>;\n}\n\nexport function configureAuth<TUser>(\n getAuthenticatedUser: GetUserFn<TUser>,\n config?: AuthConfig<TUser>,\n): AuthModule<TUser> {\n function PreconfiguredAuthProvider({ children }: React.PropsWithChildren) {\n return (\n <AuthProvider<TUser> getAuthenticatedUser={getAuthenticatedUser} config={config}>\n {children}\n </AuthProvider>\n );\n }\n\n return {\n AuthProvider: PreconfiguredAuthProvider,\n useAuth: useAuth as AuthHook<TUser>,\n };\n}\n"],"version":3}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ProtectedRoute.d.ts","sourceRoot":"","sources":["src/ProtectedRoute.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAY,KAAK,mBAAmB,EAAe,MAAM,cAAc,CAAC;AACtG,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,cAAc,CAAC;AAE7D,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE1C,KAAK,cAAc,GAAG,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,WAAW,GAAG,cAAc,CAAA;CAAE,CAAC,CAAC;AAE1E,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAE3C,KAAK,wBAAwB,GAAG,QAAQ,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;AAC3E,KAAK,2BAA2B,GAAG,QAAQ,CACzC,QAAQ,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAC7C;IACE,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAClC,CACF,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,2BAA2B,CAAC;AAqCzF;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,YAAY,GAAE,MAAiB,GAAG,mBAAmB,CAe7G;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,EAAE,EAAE,YAAY,GAAE,MAAiB,GAAG,mBAAmB,EAAE,CAMnH"}
package/index.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC"}
package/useAuth.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["src/useAuth.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EAIjB,MAAM,wBAAwB,CAAC;AAGhC,KAAK,aAAa,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAClF,KAAK,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAO1C;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,KAAK,IAAI,MAAM,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;AAEhE,KAAK,SAAS,CAAC,KAAK,IAAI,QAAQ,CAAC;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;CACzC,CAAC,CAAC;AAyFH;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAC/C,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,CAAC,KAAK,IAAI,QAAQ,CAAC;IAC3C,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACxB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC;CAC9C,CAAC,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,WAAW;;sBAjIR,OAAO;iBACZ,OAAO;;gBAER,MAAM;;;WAqHP,aAAa;YACZ,cAAc;2BACC,WAAW,GAAG,OAAO;GAkB5C,CAAC;AAEH,UAAU,UAAU,CAAC,KAAK;IACxB,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,MAAM,EAAE,CAAC;CAC3C;AAsED,MAAM,MAAM,QAAQ,CAAC,KAAK,IAAI,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;AAW1D,UAAU,UAAU,CAAC,KAAK;IACxB,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAChD,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,KAAK,EACjC,oBAAoB,EAAE,SAAS,CAAC,KAAK,CAAC,EACtC,MAAM,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,GACzB,UAAU,CAAC,KAAK,CAAC,CAanB"}