authfyio-astro 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 +21 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# authfyio-astro
|
|
2
|
+
|
|
3
|
+
Astro integration for Authfyio — middleware, `Astro.locals.auth`, and JWKS verification.
|
|
4
|
+
|
|
5
|
+
> Part of [Authfyio](https://authfyio.com) — a self-hostable authentication platform.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install authfyio-astro
|
|
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
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type AuthfyioBackendClientOptions, type SessionClaims } from 'authfyio-backend';
|
|
2
|
+
export type { SessionClaims };
|
|
3
|
+
export type AstroAuthObject = {
|
|
4
|
+
userId: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
environmentId: string;
|
|
7
|
+
orgId: string | null;
|
|
8
|
+
orgRole: string | null;
|
|
9
|
+
claims: SessionClaims;
|
|
10
|
+
};
|
|
11
|
+
export type AuthfyioAstroOptions = AuthfyioBackendClientOptions & {
|
|
12
|
+
/** Glob-like patterns that require auth. Unmatched routes stay public. */
|
|
13
|
+
protectedPaths?: string[];
|
|
14
|
+
/** Where to redirect unauthed users on protected routes. Default '/sign-in'. */
|
|
15
|
+
signInUrl?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Astro integration middleware. Attaches `locals.auth` (null when signed out)
|
|
19
|
+
* and optionally 302s unauthenticated requests on protected routes to your
|
|
20
|
+
* sign-in page. Use inside `src/middleware.ts`:
|
|
21
|
+
*
|
|
22
|
+
* import { onRequest } from 'authfyio-astro';
|
|
23
|
+
* export { onRequest };
|
|
24
|
+
* // or compose:
|
|
25
|
+
* import { createAuthfyioMiddleware, sequence } from 'authfyio-astro';
|
|
26
|
+
* export const onRequest = sequence(createAuthfyioMiddleware({ baseUrl }), myOther);
|
|
27
|
+
*/
|
|
28
|
+
export declare function createAuthfyioMiddleware(opts: AuthfyioAstroOptions): (ctx: any, next: any) => Promise<Response>;
|
|
29
|
+
/** Default export helper — picks config from env vars at request time. */
|
|
30
|
+
export declare const onRequest: (ctx: any, next: any) => Promise<Response>;
|
|
31
|
+
/** Minimal sequence helper for composing Astro middlewares. */
|
|
32
|
+
export declare function sequence(...fns: Array<(ctx: any, next: any) => Promise<Response>>): (ctx: any, next: any) => Promise<Response>;
|
|
33
|
+
//# 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,eAAe,GAAG;IAC5B,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;CACvB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,4BAA4B,GAAG;IAChE,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,oBAAoB,IAKjC,KAAK,GAAG,EAAE,MAAM,GAAG,KAAG,OAAO,CAAC,QAAQ,CAAC,CA6BxE;AAED,0EAA0E;AAC1E,eAAO,MAAM,SAAS,QAhCiB,GAAG,QAAQ,GAAG,KAAG,OAAO,CAAC,QAAQ,CAkCtE,CAAC;AAiBH,+DAA+D;AAC/D,wBAAgB,QAAQ,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,IAClE,KAAK,GAAG,EAAE,MAAM,GAAG,KAAG,OAAO,CAAC,QAAQ,CAAC,CAWtD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { AuthfyioBackendClient, } from 'authfyio-backend';
|
|
2
|
+
/**
|
|
3
|
+
* Astro integration middleware. Attaches `locals.auth` (null when signed out)
|
|
4
|
+
* and optionally 302s unauthenticated requests on protected routes to your
|
|
5
|
+
* sign-in page. Use inside `src/middleware.ts`:
|
|
6
|
+
*
|
|
7
|
+
* import { onRequest } from 'authfyio-astro';
|
|
8
|
+
* export { onRequest };
|
|
9
|
+
* // or compose:
|
|
10
|
+
* import { createAuthfyioMiddleware, sequence } from 'authfyio-astro';
|
|
11
|
+
* export const onRequest = sequence(createAuthfyioMiddleware({ baseUrl }), myOther);
|
|
12
|
+
*/
|
|
13
|
+
export function createAuthfyioMiddleware(opts) {
|
|
14
|
+
const client = new AuthfyioBackendClient(opts);
|
|
15
|
+
const protectedRe = (opts.protectedPaths ?? []).map((p) => globToRegex(p));
|
|
16
|
+
const signInUrl = opts.signInUrl ?? '/sign-in';
|
|
17
|
+
return async function onRequest(ctx, next) {
|
|
18
|
+
const req = ctx.request;
|
|
19
|
+
const cookie = req.headers.get('cookie') ?? '';
|
|
20
|
+
const claims = await client
|
|
21
|
+
.getSessionFromRequest({ headers: { cookie } })
|
|
22
|
+
.catch(() => null);
|
|
23
|
+
const auth = claims
|
|
24
|
+
? {
|
|
25
|
+
userId: claims.sub,
|
|
26
|
+
sessionId: claims.sid,
|
|
27
|
+
environmentId: claims.env,
|
|
28
|
+
orgId: claims.org ?? null,
|
|
29
|
+
orgRole: claims.org_role ?? null,
|
|
30
|
+
claims,
|
|
31
|
+
}
|
|
32
|
+
: null;
|
|
33
|
+
ctx.locals = { ...(ctx.locals ?? {}), auth };
|
|
34
|
+
const pathname = new URL(req.url).pathname;
|
|
35
|
+
const isProtected = protectedRe.some((re) => re.test(pathname));
|
|
36
|
+
if (isProtected && !auth) {
|
|
37
|
+
return new Response(null, {
|
|
38
|
+
status: 302,
|
|
39
|
+
headers: { Location: `${signInUrl}?redirect_url=${encodeURIComponent(pathname)}` },
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return next();
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Default export helper — picks config from env vars at request time. */
|
|
46
|
+
export const onRequest = createAuthfyioMiddleware({
|
|
47
|
+
baseUrl: (typeof process !== 'undefined' ? process.env?.AF_API_BASE_URL : undefined) ?? '',
|
|
48
|
+
});
|
|
49
|
+
/** Tiny glob→regex — supports `*` and `(.*)`. */
|
|
50
|
+
function globToRegex(pattern) {
|
|
51
|
+
const src = pattern
|
|
52
|
+
.split(/(\(\.\*\))/g)
|
|
53
|
+
.map((seg) => {
|
|
54
|
+
if (seg === '(.*)')
|
|
55
|
+
return '.*';
|
|
56
|
+
return seg
|
|
57
|
+
.replace(/[\\^$+?.()|[\]{}]/g, '\\$&')
|
|
58
|
+
.replace(/\*/g, '[^/]*')
|
|
59
|
+
.replace(/:([A-Za-z0-9_]+)/g, '[^/]+');
|
|
60
|
+
})
|
|
61
|
+
.join('');
|
|
62
|
+
return new RegExp(`^${src}\\/?$`);
|
|
63
|
+
}
|
|
64
|
+
/** Minimal sequence helper for composing Astro middlewares. */
|
|
65
|
+
export function sequence(...fns) {
|
|
66
|
+
return async (ctx, next) => {
|
|
67
|
+
let i = -1;
|
|
68
|
+
async function runner(j) {
|
|
69
|
+
if (j <= i)
|
|
70
|
+
throw new Error('next() called twice');
|
|
71
|
+
i = j;
|
|
72
|
+
const fn = fns[j] ?? null;
|
|
73
|
+
if (!fn)
|
|
74
|
+
return next();
|
|
75
|
+
return fn(ctx, () => runner(j + 1));
|
|
76
|
+
}
|
|
77
|
+
return runner(0);
|
|
78
|
+
};
|
|
79
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "authfyio-astro",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Astro integration for Authfyio — middleware, `Astro.locals.auth`, and JWKS verification.",
|
|
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
|
+
"astro": ">=4"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"authfyio",
|
|
30
|
+
"auth",
|
|
31
|
+
"astro",
|
|
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
|
+
}
|