@daltonr/authwrite-fastify 0.1.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/dist/index.d.ts +15 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
- package/src/index.ts +49 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FastifyRequest, FastifyReply, preHandlerHookHandler } from 'fastify';
|
|
2
|
+
import type { Action, AuthEvaluator, Decision, Subject, Resource } from '@daltonr/authwrite-core';
|
|
3
|
+
declare module 'fastify' {
|
|
4
|
+
interface FastifyRequest {
|
|
5
|
+
authDecision?: Decision;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export interface AuthHookConfig<S extends Subject = Subject, R extends Resource = Resource> {
|
|
9
|
+
engine: AuthEvaluator<S, R>;
|
|
10
|
+
subject: (req: FastifyRequest) => S | Promise<S>;
|
|
11
|
+
resource: (req: FastifyRequest) => R | undefined | Promise<R | undefined>;
|
|
12
|
+
action: Action | ((req: FastifyRequest) => Action);
|
|
13
|
+
onDeny?: (req: FastifyRequest, reply: FastifyReply, decision: Decision) => void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare function createAuthHook<S extends Subject = Subject, R extends Resource = Resource>(config: AuthHookConfig<S, R>): preHandlerHookHandler;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// ─── Hook factory ─────────────────────────────────────────────────────────────
|
|
2
|
+
export function createAuthHook(config) {
|
|
3
|
+
return async (req, reply) => {
|
|
4
|
+
const subject = await config.subject(req);
|
|
5
|
+
const resource = await config.resource(req);
|
|
6
|
+
const action = typeof config.action === 'function' ? config.action(req) : config.action;
|
|
7
|
+
const decision = await config.engine.evaluate({ subject, resource, action });
|
|
8
|
+
req.authDecision = decision;
|
|
9
|
+
if (decision.allowed)
|
|
10
|
+
return;
|
|
11
|
+
if (config.onDeny) {
|
|
12
|
+
await config.onDeny(req, reply, decision);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
reply.status(403).send({ error: 'forbidden', reason: decision.reason });
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAwBA,iFAAiF;AAEjF,MAAM,UAAU,cAAc,CAG5B,MAA4B;IAC5B,OAAO,KAAK,EAAE,GAAmB,EAAE,KAAmB,EAAE,EAAE;QACxD,MAAM,OAAO,GAAI,MAAM,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC1C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QAC3C,MAAM,MAAM,GAAK,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;QAEzF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;QAE5E,GAAG,CAAC,YAAY,GAAG,QAAQ,CAAA;QAE3B,IAAI,QAAQ,CAAC,OAAO;YAAE,OAAM;QAE5B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;YACzC,OAAM;QACR,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IACzE,CAAC,CAAA;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@daltonr/authwrite-fastify",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "Fastify hooks and decorators adapter for AuthEngine.",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/richardadalton/authwrite.git",
|
|
10
|
+
"directory": "packages/fastify"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["authorization", "authz", "fastify", "plugin"],
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"main": "dist/index.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"files": ["dist", "src", "README.md", "LICENSE"],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -p tsconfig.json",
|
|
25
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
26
|
+
"prepublishOnly": "test -d dist && echo 'dist already built, skipping' || (npm run clean && npm run build)"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@daltonr/authwrite-core": "*"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"fastify": ">=4.0.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"fastify": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { FastifyRequest, FastifyReply, preHandlerHookHandler } from 'fastify'
|
|
2
|
+
import type { Action, AuthEvaluator, Decision, Subject, Resource } from '@daltonr/authwrite-core'
|
|
3
|
+
|
|
4
|
+
// ─── Request augmentation ─────────────────────────────────────────────────────
|
|
5
|
+
|
|
6
|
+
declare module 'fastify' {
|
|
7
|
+
interface FastifyRequest {
|
|
8
|
+
authDecision?: Decision
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// ─── Config ───────────────────────────────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
export interface AuthHookConfig<
|
|
15
|
+
S extends Subject = Subject,
|
|
16
|
+
R extends Resource = Resource,
|
|
17
|
+
> {
|
|
18
|
+
engine: AuthEvaluator<S, R>
|
|
19
|
+
subject: (req: FastifyRequest) => S | Promise<S>
|
|
20
|
+
resource: (req: FastifyRequest) => R | undefined | Promise<R | undefined>
|
|
21
|
+
action: Action | ((req: FastifyRequest) => Action)
|
|
22
|
+
onDeny?: (req: FastifyRequest, reply: FastifyReply, decision: Decision) => void | Promise<void>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ─── Hook factory ─────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
export function createAuthHook<
|
|
28
|
+
S extends Subject = Subject,
|
|
29
|
+
R extends Resource = Resource,
|
|
30
|
+
>(config: AuthHookConfig<S, R>): preHandlerHookHandler {
|
|
31
|
+
return async (req: FastifyRequest, reply: FastifyReply) => {
|
|
32
|
+
const subject = await config.subject(req)
|
|
33
|
+
const resource = await config.resource(req)
|
|
34
|
+
const action = typeof config.action === 'function' ? config.action(req) : config.action
|
|
35
|
+
|
|
36
|
+
const decision = await config.engine.evaluate({ subject, resource, action })
|
|
37
|
+
|
|
38
|
+
req.authDecision = decision
|
|
39
|
+
|
|
40
|
+
if (decision.allowed) return
|
|
41
|
+
|
|
42
|
+
if (config.onDeny) {
|
|
43
|
+
await config.onDeny(req, reply, decision)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
reply.status(403).send({ error: 'forbidden', reason: decision.reason })
|
|
48
|
+
}
|
|
49
|
+
}
|