authfyio-express 0.2.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/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # authfyio-express
2
+
3
+ Express middleware for Authfyio — protect routes, inject the auth context, verify session JWTs.
4
+
5
+ > Part of [Authfyio](https://authfyio.com) — a self-hostable authentication platform.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install authfyio-express
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ See the full guide at **https://authfyio.com/docs**.
16
+
17
+ Point the SDK at your Authfyio instance via the same-origin proxy (`/api/af`) or set `AF_API_BASE_URL` for server-side calls.
18
+
19
+ ## License
20
+
21
+ MIT
@@ -0,0 +1,28 @@
1
+ import { type AuthfyioBackendClientOptions, type SessionClaims } from 'authfyio-backend';
2
+ export type { SessionClaims };
3
+ export type ExpressAuthObject = {
4
+ userId: string;
5
+ sessionId: string;
6
+ environmentId: string;
7
+ orgId: string | null;
8
+ orgRole: string | null;
9
+ claims: SessionClaims;
10
+ getToken(): string;
11
+ };
12
+ export type RequireAuthOptions = AuthfyioBackendClientOptions;
13
+ /**
14
+ * Express middleware that requires a valid Authfyio session. Attaches a
15
+ * typed `req.auth` object on success; responds 401 on failure.
16
+ *
17
+ * import { requireAuth } from 'authfyio-express';
18
+ * app.use('/api/private', requireAuth({ baseUrl: process.env.AF_API_BASE_URL! }));
19
+ * app.get('/api/private/me', (req, res) => res.json(req.auth.userId));
20
+ */
21
+ export declare function requireAuth(opts: RequireAuthOptions): (req: any, res: any, next: any) => Promise<void>;
22
+ /**
23
+ * Non-blocking variant — sets `req.auth` when a session is present, leaves it
24
+ * `null` otherwise. Use when a handler serves both anonymous and signed-in
25
+ * traffic.
26
+ */
27
+ export declare function withAuth(opts: RequireAuthOptions): (req: any, _res: any, next: any) => Promise<void>;
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,IAAI,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AAE9D;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,kBAAkB,IAE3B,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,mBAerD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,kBAAkB,IAExB,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE,MAAM,GAAG,mBAWtD"}
package/dist/index.js ADDED
@@ -0,0 +1,73 @@
1
+ import { AuthfyioBackendClient, } from 'authfyio-backend';
2
+ /**
3
+ * Express middleware that requires a valid Authfyio session. Attaches a
4
+ * typed `req.auth` object on success; responds 401 on failure.
5
+ *
6
+ * import { requireAuth } from 'authfyio-express';
7
+ * app.use('/api/private', requireAuth({ baseUrl: process.env.AF_API_BASE_URL! }));
8
+ * app.get('/api/private/me', (req, res) => res.json(req.auth.userId));
9
+ */
10
+ export function requireAuth(opts) {
11
+ const client = new AuthfyioBackendClient(opts);
12
+ return async function (req, res, next) {
13
+ try {
14
+ const cookie = req.headers?.cookie ?? '';
15
+ const claims = await client.getSessionFromRequest({ headers: { cookie } });
16
+ if (!claims) {
17
+ res.status(401).json({ error: 'unauthorized' });
18
+ return;
19
+ }
20
+ const token = extractSessionCookie(cookie);
21
+ req.auth = buildAuth(claims, token ?? '');
22
+ next();
23
+ }
24
+ catch {
25
+ res.status(401).json({ error: 'unauthorized' });
26
+ }
27
+ };
28
+ }
29
+ /**
30
+ * Non-blocking variant — sets `req.auth` when a session is present, leaves it
31
+ * `null` otherwise. Use when a handler serves both anonymous and signed-in
32
+ * traffic.
33
+ */
34
+ export function withAuth(opts) {
35
+ const client = new AuthfyioBackendClient(opts);
36
+ return async function (req, _res, next) {
37
+ try {
38
+ const cookie = req.headers?.cookie ?? '';
39
+ const claims = await client.getSessionFromRequest({ headers: { cookie } });
40
+ const token = extractSessionCookie(cookie);
41
+ req.auth = claims ? buildAuth(claims, token ?? '') : null;
42
+ }
43
+ catch {
44
+ req.auth = null;
45
+ }
46
+ next();
47
+ };
48
+ }
49
+ function buildAuth(claims, token) {
50
+ return {
51
+ userId: claims.sub,
52
+ sessionId: claims.sid,
53
+ environmentId: claims.env,
54
+ orgId: claims.org ?? null,
55
+ orgRole: claims.org_role ?? null,
56
+ claims,
57
+ getToken: () => token,
58
+ };
59
+ }
60
+ function extractSessionCookie(cookieHeader) {
61
+ if (!cookieHeader)
62
+ return null;
63
+ for (const pair of cookieHeader.split(';')) {
64
+ const eq = pair.indexOf('=');
65
+ if (eq < 0)
66
+ continue;
67
+ const k = pair.slice(0, eq).trim();
68
+ const v = pair.slice(eq + 1).trim();
69
+ if (k === '__session')
70
+ return decodeURIComponent(v);
71
+ }
72
+ return null;
73
+ }
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "authfyio-express",
3
+ "version": "0.2.1",
4
+ "description": "Express middleware for Authfyio — protect routes, inject the auth context, verify session JWTs.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "typecheck": "tsc -p tsconfig.build.json --noEmit",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "peerDependencies": {
25
+ "authfyio-backend": "^0.2.0",
26
+ "express": ">=4"
27
+ },
28
+ "keywords": [
29
+ "authfyio",
30
+ "auth",
31
+ "express",
32
+ "middleware"
33
+ ],
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "homepage": "https://authfyio.com/docs",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/authfyio/authfyio.git"
41
+ }
42
+ }