@adonis-agora/authkit-client 1.0.0-rc.0 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/build/index.d.ts +2 -2
- package/build/index.js +1 -1
- package/build/src/host/dashboard_guard.d.ts +25 -28
- package/build/src/host/dashboard_guard.js +17 -37
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @adonis-agora/authkit-client
|
|
2
2
|
|
|
3
|
+
## 1.0.0-rc.1
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#451](https://github.com/DavideCarvalho/adonis-agora-authkit/pull/451) [`1162aee`](https://github.com/DavideCarvalho/adonis-agora-authkit/commit/1162aeeee00d4706b8515d89e37f93d172cec44a) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - `authkitDashboardMiddleware` is removed: every `@adonis-agora` console takes `authorize` now, so use `authkitDashboardAuthorize()` in its place. `authkitDashboardAuthorize` tells the two denials apart: a visitor without a session gets `401` (`{ allowed: false, reason: 'unauthenticated' }`) instead of `403`, and with the new `loginPath` option is sent to the app's login (`{ redirectTo }`). Signed in without the role is still `403`.
|
|
8
|
+
|
|
3
9
|
## 1.0.0-rc.0
|
|
4
10
|
|
|
5
11
|
### Major Changes
|
package/build/index.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export type { CreateDpopProofInput, DpopKeyPair } from './src/dpop.js';
|
|
|
15
15
|
export { createDpopProof, dpopJwkThumbprint, generateDpopKeyPair, } from './src/dpop.js';
|
|
16
16
|
export type { IdentityUserProviderContract } from './src/host/authkit_client_guard.js';
|
|
17
17
|
export { AuthkitClientGuard, authkitClientGuard, authkitIdentityProvider, } from './src/host/authkit_client_guard.js';
|
|
18
|
-
export type { DashboardGuardOptions } from './src/host/dashboard_guard.js';
|
|
19
|
-
export { authkitDashboardAuthorize,
|
|
18
|
+
export type { DashboardGuardOptions, DashboardGuardResult } from './src/host/dashboard_guard.js';
|
|
19
|
+
export { authkitDashboardAuthorize, isAuthkitAdmin, } from './src/host/dashboard_guard.js';
|
|
20
20
|
export type { AuthkitUser, AuthkitUserType } from './src/host/request_authenticator.js';
|
|
21
21
|
export { getAuthkit } from './src/host/request_authenticator.js';
|
|
22
22
|
export type { ResiliencePolicy } from './src/http/resilient_fetch.js';
|
package/build/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export { defineConfig, resolvers } from './src/define_config.js';
|
|
|
7
7
|
export { conventionEndpoints, discoverEndpoints, OidcDiscoveryError } from './src/discovery.js';
|
|
8
8
|
export { createDpopProof, dpopJwkThumbprint, generateDpopKeyPair, } from './src/dpop.js';
|
|
9
9
|
export { AuthkitClientGuard, authkitClientGuard, authkitIdentityProvider, } from './src/host/authkit_client_guard.js';
|
|
10
|
-
export { authkitDashboardAuthorize,
|
|
10
|
+
export { authkitDashboardAuthorize, isAuthkitAdmin, } from './src/host/dashboard_guard.js';
|
|
11
11
|
export { getAuthkit } from './src/host/request_authenticator.js';
|
|
12
12
|
export { resilientFetch } from './src/http/resilient_fetch.js';
|
|
13
13
|
export { InvalidIdTokenError, validateIdToken } from './src/id_token.js';
|
|
@@ -2,22 +2,35 @@ import type { HttpContext } from '@adonisjs/core/http';
|
|
|
2
2
|
export interface DashboardGuardOptions {
|
|
3
3
|
/** Global role required to pass the gate. Default `'ADMIN'`. */
|
|
4
4
|
role?: string;
|
|
5
|
+
/**
|
|
6
|
+
* The app's login page. When set, a visitor without a session is sent there (a page navigation
|
|
7
|
+
* gets a `302`, an API call a `401` carrying `redirectTo`) instead of a plain `401`.
|
|
8
|
+
*/
|
|
9
|
+
loginPath?: string;
|
|
5
10
|
}
|
|
11
|
+
/** What {@link authkitDashboardAuthorize} answers: the shared console `authorize` result. */
|
|
12
|
+
export type DashboardGuardResult = boolean | {
|
|
13
|
+
allowed: false;
|
|
14
|
+
reason: 'unauthenticated';
|
|
15
|
+
} | {
|
|
16
|
+
redirectTo: string;
|
|
17
|
+
};
|
|
6
18
|
/**
|
|
7
|
-
* Core predicate behind {@link authkitDashboardAuthorize}
|
|
8
|
-
*
|
|
9
|
-
* the configured global role — `ctx.authkit.hasGlobalRole('ADMIN')`, the pattern hosts already
|
|
10
|
-
* hand-roll per embedded admin dashboard (durable/media/agent/telescope).
|
|
19
|
+
* Core predicate behind {@link authkitDashboardAuthorize}: authenticated (a resolvable authkit
|
|
20
|
+
* `Identity`) AND holding the configured global role.
|
|
11
21
|
*
|
|
12
|
-
* Resolves the session via {@link getAuthkit}
|
|
13
|
-
*
|
|
22
|
+
* Resolves the session via {@link getAuthkit} rather than reading `ctx.auth` directly: `ctx.auth`'s
|
|
23
|
+
* TYPE is host-owned, so this module can't assume its shape. `getAuthkit` works with both
|
|
24
|
+
* `authkit_middleware`'s `ctx.auth` and `authkitClientGuard`'s `ctx.authkit`, memoized per request.
|
|
14
25
|
*/
|
|
15
26
|
export declare function isAuthkitAdmin(ctx: HttpContext, options?: DashboardGuardOptions): Promise<boolean>;
|
|
16
27
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
28
|
+
* An `authorize` for any `@adonis-agora` console (durable, telescope, media, payments, agent):
|
|
29
|
+
* signed in to authkit AND holding the global role (`ADMIN` by default).
|
|
30
|
+
*
|
|
31
|
+
* - no session → `401` (or the `loginPath` redirect when set);
|
|
32
|
+
* - signed in without the role → `403`;
|
|
33
|
+
* - otherwise allowed.
|
|
21
34
|
*
|
|
22
35
|
* ```ts
|
|
23
36
|
* // config/durable_dashboard.ts
|
|
@@ -25,24 +38,8 @@ export declare function isAuthkitAdmin(ctx: HttpContext, options?: DashboardGuar
|
|
|
25
38
|
* import { authkitDashboardAuthorize } from '@adonis-agora/authkit-client'
|
|
26
39
|
*
|
|
27
40
|
* export default defineConfig({
|
|
28
|
-
* authorize: authkitDashboardAuthorize(),
|
|
29
|
-
* })
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
32
|
-
export declare function authkitDashboardAuthorize(options?: DashboardGuardOptions): (ctx: HttpContext) => Promise<boolean>;
|
|
33
|
-
/**
|
|
34
|
-
* Adapter for the `middleware: (ctx, next) => Promise<void>` shape that
|
|
35
|
-
* `@adonis-agora/media`'s dashboard config expects. Mirrors the hand-rolled `requireAdmin` apps
|
|
36
|
-
* wrote themselves: no session -> `401`; session without the role -> `403`; otherwise `next()`.
|
|
37
|
-
*
|
|
38
|
-
* ```ts
|
|
39
|
-
* // config/media_dashboard.ts
|
|
40
|
-
* import { defineConfig } from '@adonis-agora/media/dashboard'
|
|
41
|
-
* import { authkitDashboardMiddleware } from '@adonis-agora/authkit-client'
|
|
42
|
-
*
|
|
43
|
-
* export default defineConfig({
|
|
44
|
-
* middleware: authkitDashboardMiddleware(),
|
|
41
|
+
* authorize: authkitDashboardAuthorize({ loginPath: '/login' }),
|
|
45
42
|
* })
|
|
46
43
|
* ```
|
|
47
44
|
*/
|
|
48
|
-
export declare function
|
|
45
|
+
export declare function authkitDashboardAuthorize(options?: DashboardGuardOptions): (ctx: HttpContext) => Promise<DashboardGuardResult>;
|
|
@@ -4,13 +4,12 @@ import { getAuthkit } from './request_authenticator.js';
|
|
|
4
4
|
* impersonation/token-exchange) — same convention, not a new one. */
|
|
5
5
|
const DEFAULT_ADMIN_ROLE = 'ADMIN';
|
|
6
6
|
/**
|
|
7
|
-
* Core predicate behind {@link authkitDashboardAuthorize}
|
|
8
|
-
*
|
|
9
|
-
* the configured global role — `ctx.authkit.hasGlobalRole('ADMIN')`, the pattern hosts already
|
|
10
|
-
* hand-roll per embedded admin dashboard (durable/media/agent/telescope).
|
|
7
|
+
* Core predicate behind {@link authkitDashboardAuthorize}: authenticated (a resolvable authkit
|
|
8
|
+
* `Identity`) AND holding the configured global role.
|
|
11
9
|
*
|
|
12
|
-
* Resolves the session via {@link getAuthkit}
|
|
13
|
-
*
|
|
10
|
+
* Resolves the session via {@link getAuthkit} rather than reading `ctx.auth` directly: `ctx.auth`'s
|
|
11
|
+
* TYPE is host-owned, so this module can't assume its shape. `getAuthkit` works with both
|
|
12
|
+
* `authkit_middleware`'s `ctx.auth` and `authkitClientGuard`'s `ctx.authkit`, memoized per request.
|
|
14
13
|
*/
|
|
15
14
|
export async function isAuthkitAdmin(ctx, options = {}) {
|
|
16
15
|
const authkit = await getAuthkit(ctx);
|
|
@@ -19,10 +18,12 @@ export async function isAuthkitAdmin(ctx, options = {}) {
|
|
|
19
18
|
return authkit.hasGlobalRole(options.role ?? DEFAULT_ADMIN_ROLE);
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* An `authorize` for any `@adonis-agora` console (durable, telescope, media, payments, agent):
|
|
22
|
+
* signed in to authkit AND holding the global role (`ADMIN` by default).
|
|
23
|
+
*
|
|
24
|
+
* - no session → `401` (or the `loginPath` redirect when set);
|
|
25
|
+
* - signed in without the role → `403`;
|
|
26
|
+
* - otherwise allowed.
|
|
26
27
|
*
|
|
27
28
|
* ```ts
|
|
28
29
|
* // config/durable_dashboard.ts
|
|
@@ -30,39 +31,18 @@ export async function isAuthkitAdmin(ctx, options = {}) {
|
|
|
30
31
|
* import { authkitDashboardAuthorize } from '@adonis-agora/authkit-client'
|
|
31
32
|
*
|
|
32
33
|
* export default defineConfig({
|
|
33
|
-
* authorize: authkitDashboardAuthorize(),
|
|
34
|
+
* authorize: authkitDashboardAuthorize({ loginPath: '/login' }),
|
|
34
35
|
* })
|
|
35
36
|
* ```
|
|
36
37
|
*/
|
|
37
38
|
export function authkitDashboardAuthorize(options = {}) {
|
|
38
|
-
return (ctx) =>
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Adapter for the `middleware: (ctx, next) => Promise<void>` shape that
|
|
42
|
-
* `@adonis-agora/media`'s dashboard config expects. Mirrors the hand-rolled `requireAdmin` apps
|
|
43
|
-
* wrote themselves: no session -> `401`; session without the role -> `403`; otherwise `next()`.
|
|
44
|
-
*
|
|
45
|
-
* ```ts
|
|
46
|
-
* // config/media_dashboard.ts
|
|
47
|
-
* import { defineConfig } from '@adonis-agora/media/dashboard'
|
|
48
|
-
* import { authkitDashboardMiddleware } from '@adonis-agora/authkit-client'
|
|
49
|
-
*
|
|
50
|
-
* export default defineConfig({
|
|
51
|
-
* middleware: authkitDashboardMiddleware(),
|
|
52
|
-
* })
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export function authkitDashboardMiddleware(options = {}) {
|
|
56
|
-
return async (ctx, next) => {
|
|
39
|
+
return async (ctx) => {
|
|
57
40
|
const authkit = await getAuthkit(ctx);
|
|
58
41
|
if (!(await authkit.check())) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (!authkit.hasGlobalRole(options.role ?? DEFAULT_ADMIN_ROLE)) {
|
|
63
|
-
ctx.response.forbidden({ message: 'Admin access required' });
|
|
64
|
-
return;
|
|
42
|
+
return options.loginPath
|
|
43
|
+
? { redirectTo: options.loginPath }
|
|
44
|
+
: { allowed: false, reason: 'unauthenticated' };
|
|
65
45
|
}
|
|
66
|
-
|
|
46
|
+
return authkit.hasGlobalRole(options.role ?? DEFAULT_ADMIN_ROLE);
|
|
67
47
|
};
|
|
68
48
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonis-agora/authkit-client",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
4
|
"description": "AdonisJS OIDC/OAuth2 relying-party (client) toolkit: session-based authentication against an OpenID Connect identity provider, with JWT/PAT user resolvers and OpenTelemetry metrics.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "dudousxd",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"jose": "6.2.15"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@adonis-agora/authkit-server": "1.0.0-rc.
|
|
84
|
+
"@adonis-agora/authkit-server": "1.0.0-rc.1",
|
|
85
85
|
"@adonis-agora/resilience": "0.4.3",
|
|
86
86
|
"@adonisjs/auth": "10.1.0",
|
|
87
87
|
"@adonisjs/core": "7.6.0",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"@japa/runner": "5.4.0",
|
|
93
93
|
"@poppinss/ts-exec": "1.5.2",
|
|
94
94
|
"@tanstack/intent": "0.5.6",
|
|
95
|
-
"@types/node": "26.6.
|
|
95
|
+
"@types/node": "26.6.6",
|
|
96
96
|
"ioredis-mock": "8.13.1",
|
|
97
97
|
"tempura": "0.4.1",
|
|
98
98
|
"testcontainers": "12.2.1",
|