@contentrail/cloudflare 0.2.2 → 0.2.4
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 +2 -2
- package/dist/auth/password.d.ts +36 -0
- package/dist/auth/password.d.ts.map +1 -0
- package/dist/auth/password.js +95 -0
- package/dist/auth/password.js.map +1 -0
- package/dist/auth/session.d.ts +15 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +91 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/pages/client.d.ts +8 -0
- package/dist/pages/client.d.ts.map +1 -1
- package/dist/pages/client.js +18 -0
- package/dist/pages/client.js.map +1 -1
- package/dist/pages/site-handler.d.ts +9 -1
- package/dist/pages/site-handler.d.ts.map +1 -1
- package/dist/pages/site-handler.js +106 -2
- package/dist/pages/site-handler.js.map +1 -1
- package/dist/pages/templates.d.ts +2 -2
- package/dist/pages/templates.d.ts.map +1 -1
- package/dist/pages/templates.js +67 -14
- package/dist/pages/templates.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -18,10 +18,10 @@ pnpm install
|
|
|
18
18
|
pnpm --filter @contentrail/cloudflare build
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
### From npm (`0.2.
|
|
21
|
+
### From npm (`0.2.4`)
|
|
22
22
|
|
|
23
23
|
```sh
|
|
24
|
-
pnpm add @contentrail/core@0.2.
|
|
24
|
+
pnpm add @contentrail/core@0.2.4 @contentrail/publisher@0.2.4 @contentrail/cloudflare@0.2.4 zod@^4.6.7
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## ADR 011b summary
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type SessionSecrets } from "./session.js";
|
|
2
|
+
import type { Authenticator, Identity } from "./types.js";
|
|
3
|
+
export interface PasswordAuthOptions extends SessionSecrets {
|
|
4
|
+
readonly username: string;
|
|
5
|
+
readonly password: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Username/password admin auth. Sessions are HS256 JWTs (Bearer or cookie).
|
|
9
|
+
* Prefer this for small self-hosted sites; Cloudflare Access remains optional.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createPasswordAuthenticator(options: PasswordAuthOptions): Authenticator;
|
|
12
|
+
export interface PasswordLoginInput {
|
|
13
|
+
readonly username: string;
|
|
14
|
+
readonly password: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function loginWithPassword(options: PasswordAuthOptions, input: PasswordLoginInput): Promise<{
|
|
17
|
+
ok: true;
|
|
18
|
+
token: string;
|
|
19
|
+
identity: Identity;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Prefer password auth when admin credentials are configured.
|
|
25
|
+
* Fall back to Access when Access team+AUD are set and password is not.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createPagesAuthenticator(env: {
|
|
28
|
+
readonly CONTENTRAIL_ADMIN_USERNAME?: string;
|
|
29
|
+
readonly CONTENTRAIL_ADMIN_PASSWORD?: string;
|
|
30
|
+
readonly CONTENTRAIL_SESSION_SECRET?: string;
|
|
31
|
+
readonly CONTENTRAIL_ACCESS_TEAM_DOMAIN?: string;
|
|
32
|
+
readonly CONTENTRAIL_ACCESS_AUD?: string;
|
|
33
|
+
readonly accessAuthenticator?: Authenticator;
|
|
34
|
+
readonly passwordAuthenticator?: Authenticator;
|
|
35
|
+
}): Authenticator;
|
|
36
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAkBD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,mBAAmB,GAC3B,aAAa,CA0Bf;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,mBAAmB,EAC5B,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,CAgB1E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE;IAC5C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IAC7C,QAAQ,CAAC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACjD,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,CAAC;IAC7C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,aAAa,CAAC;CAChD,GAAG,aAAa,CA+BhB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createSessionToken, readSessionTokenFromRequest, verifySessionToken, } from "./session.js";
|
|
2
|
+
/** Workers-safe compare (no node:crypto). Length is normalized via SHA-256. */
|
|
3
|
+
async function safeEqualString(left, right) {
|
|
4
|
+
const enc = new TextEncoder();
|
|
5
|
+
const [leftDigest, rightDigest] = await Promise.all([
|
|
6
|
+
crypto.subtle.digest("SHA-256", enc.encode(left)),
|
|
7
|
+
crypto.subtle.digest("SHA-256", enc.encode(right)),
|
|
8
|
+
]);
|
|
9
|
+
const a = new Uint8Array(leftDigest);
|
|
10
|
+
const b = new Uint8Array(rightDigest);
|
|
11
|
+
let out = 0;
|
|
12
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
13
|
+
out |= a[i] ^ b[i];
|
|
14
|
+
}
|
|
15
|
+
return out === 0;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Username/password admin auth. Sessions are HS256 JWTs (Bearer or cookie).
|
|
19
|
+
* Prefer this for small self-hosted sites; Cloudflare Access remains optional.
|
|
20
|
+
*/
|
|
21
|
+
export function createPasswordAuthenticator(options) {
|
|
22
|
+
return {
|
|
23
|
+
async authenticate(request) {
|
|
24
|
+
const token = readSessionTokenFromRequest(request);
|
|
25
|
+
if (token === null) {
|
|
26
|
+
return {
|
|
27
|
+
ok: false,
|
|
28
|
+
status: 401,
|
|
29
|
+
code: "MISSING_CREDENTIAL",
|
|
30
|
+
message: "Missing admin session. Sign in with username and password.",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const identity = await verifySessionToken(token, {
|
|
34
|
+
sessionSecret: options.sessionSecret,
|
|
35
|
+
});
|
|
36
|
+
if (identity === null) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
status: 401,
|
|
40
|
+
code: "MALFORMED_CREDENTIAL",
|
|
41
|
+
message: "Admin session is invalid or expired.",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { ok: true, identity };
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export async function loginWithPassword(options, input) {
|
|
49
|
+
const userOk = await safeEqualString(input.username, options.username);
|
|
50
|
+
const passOk = await safeEqualString(input.password, options.password);
|
|
51
|
+
if (!userOk || !passOk) {
|
|
52
|
+
return { ok: false };
|
|
53
|
+
}
|
|
54
|
+
const identity = {
|
|
55
|
+
subject: `password:${options.username}`,
|
|
56
|
+
issuer: "contentrail:password",
|
|
57
|
+
audience: "contentrail:admin",
|
|
58
|
+
...(options.username.includes("@") ? { email: options.username } : {}),
|
|
59
|
+
};
|
|
60
|
+
const token = await createSessionToken(identity, {
|
|
61
|
+
sessionSecret: options.sessionSecret,
|
|
62
|
+
});
|
|
63
|
+
return { ok: true, token, identity };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Prefer password auth when admin credentials are configured.
|
|
67
|
+
* Fall back to Access when Access team+AUD are set and password is not.
|
|
68
|
+
*/
|
|
69
|
+
export function createPagesAuthenticator(env) {
|
|
70
|
+
const user = env.CONTENTRAIL_ADMIN_USERNAME?.trim() ?? "";
|
|
71
|
+
const password = env.CONTENTRAIL_ADMIN_PASSWORD ?? "";
|
|
72
|
+
const sessionSecret = env.CONTENTRAIL_SESSION_SECRET?.trim() ?? "";
|
|
73
|
+
if (user !== "" && password !== "" && sessionSecret !== "") {
|
|
74
|
+
return (env.passwordAuthenticator ??
|
|
75
|
+
createPasswordAuthenticator({
|
|
76
|
+
username: user,
|
|
77
|
+
password,
|
|
78
|
+
sessionSecret,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
if (env.accessAuthenticator !== undefined) {
|
|
82
|
+
return env.accessAuthenticator;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
async authenticate() {
|
|
86
|
+
return {
|
|
87
|
+
ok: false,
|
|
88
|
+
status: 401,
|
|
89
|
+
code: "KEY_UNAVAILABLE",
|
|
90
|
+
message: "Admin auth is not configured. Set CONTENTRAIL_ADMIN_USERNAME, CONTENTRAIL_ADMIN_PASSWORD, and CONTENTRAIL_SESSION_SECRET (or Cloudflare Access).",
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Identity } from "./types.js";
|
|
2
|
+
export declare const SESSION_COOKIE_NAME = "contentrail_session";
|
|
3
|
+
export declare const SESSION_TTL_SECONDS: number;
|
|
4
|
+
export interface SessionSecrets {
|
|
5
|
+
readonly sessionSecret: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createSessionToken(identity: Identity, secrets: SessionSecrets, ttlSeconds?: number): Promise<string>;
|
|
8
|
+
export declare function verifySessionToken(token: string, secrets: SessionSecrets): Promise<Identity | null>;
|
|
9
|
+
export declare function readSessionTokenFromRequest(request: Request): string | null;
|
|
10
|
+
export declare function sessionCookieHeader(token: string, options?: {
|
|
11
|
+
readonly maxAgeSeconds?: number;
|
|
12
|
+
readonly secure?: boolean;
|
|
13
|
+
}): string;
|
|
14
|
+
export declare function clearSessionCookieHeader(secure?: boolean): string;
|
|
15
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD,eAAO,MAAM,mBAAmB,QAAe,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAMD,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,cAAc,EACvB,UAAU,SAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAyB1B;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAoB3E;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GACvE,MAAM,CAcR;AAED,wBAAgB,wBAAwB,CAAC,MAAM,UAAO,GAAG,MAAM,CAY9D"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as jose from "jose";
|
|
2
|
+
export const SESSION_COOKIE_NAME = "contentrail_session";
|
|
3
|
+
export const SESSION_TTL_SECONDS = 60 * 60 * 12;
|
|
4
|
+
function secretKey(secret) {
|
|
5
|
+
return new TextEncoder().encode(secret);
|
|
6
|
+
}
|
|
7
|
+
export async function createSessionToken(identity, secrets, ttlSeconds = SESSION_TTL_SECONDS) {
|
|
8
|
+
return new jose.SignJWT({
|
|
9
|
+
email: identity.email,
|
|
10
|
+
})
|
|
11
|
+
.setProtectedHeader({ alg: "HS256" })
|
|
12
|
+
.setSubject(identity.subject)
|
|
13
|
+
.setIssuer("contentrail:password")
|
|
14
|
+
.setAudience("contentrail:admin")
|
|
15
|
+
.setIssuedAt()
|
|
16
|
+
.setExpirationTime(`${ttlSeconds}s`)
|
|
17
|
+
.sign(secretKey(secrets.sessionSecret));
|
|
18
|
+
}
|
|
19
|
+
export async function verifySessionToken(token, secrets) {
|
|
20
|
+
try {
|
|
21
|
+
const { payload } = await jose.jwtVerify(token, secretKey(secrets.sessionSecret), {
|
|
22
|
+
issuer: "contentrail:password",
|
|
23
|
+
audience: "contentrail:admin",
|
|
24
|
+
clockTolerance: 5,
|
|
25
|
+
});
|
|
26
|
+
const subject = payload.sub;
|
|
27
|
+
if (typeof subject !== "string" || subject.trim() === "") {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const email = typeof payload.email === "string" ? payload.email : undefined;
|
|
31
|
+
return {
|
|
32
|
+
subject,
|
|
33
|
+
issuer: "contentrail:password",
|
|
34
|
+
audience: "contentrail:admin",
|
|
35
|
+
...(email !== undefined ? { email } : {}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function readSessionTokenFromRequest(request) {
|
|
43
|
+
const authorization = request.headers.get("Authorization");
|
|
44
|
+
if (authorization !== null) {
|
|
45
|
+
const match = /^Bearer\s+(\S+)/i.exec(authorization);
|
|
46
|
+
if (match?.[1]) {
|
|
47
|
+
return match[1];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const cookie = request.headers.get("Cookie");
|
|
51
|
+
if (cookie === null || cookie.trim() === "") {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
for (const part of cookie.split(";")) {
|
|
55
|
+
const trimmed = part.trim();
|
|
56
|
+
if (trimmed.startsWith(`${SESSION_COOKIE_NAME}=`)) {
|
|
57
|
+
const value = trimmed.slice(SESSION_COOKIE_NAME.length + 1);
|
|
58
|
+
return value === "" ? null : decodeURIComponent(value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
export function sessionCookieHeader(token, options) {
|
|
64
|
+
const maxAge = options?.maxAgeSeconds ?? SESSION_TTL_SECONDS;
|
|
65
|
+
const secure = options?.secure !== false;
|
|
66
|
+
const parts = [
|
|
67
|
+
`${SESSION_COOKIE_NAME}=${encodeURIComponent(token)}`,
|
|
68
|
+
"Path=/",
|
|
69
|
+
"HttpOnly",
|
|
70
|
+
"SameSite=Lax",
|
|
71
|
+
`Max-Age=${maxAge}`,
|
|
72
|
+
];
|
|
73
|
+
if (secure) {
|
|
74
|
+
parts.push("Secure");
|
|
75
|
+
}
|
|
76
|
+
return parts.join("; ");
|
|
77
|
+
}
|
|
78
|
+
export function clearSessionCookieHeader(secure = true) {
|
|
79
|
+
const parts = [
|
|
80
|
+
`${SESSION_COOKIE_NAME}=`,
|
|
81
|
+
"Path=/",
|
|
82
|
+
"HttpOnly",
|
|
83
|
+
"SameSite=Lax",
|
|
84
|
+
"Max-Age=0",
|
|
85
|
+
];
|
|
86
|
+
if (secure) {
|
|
87
|
+
parts.push("Secure");
|
|
88
|
+
}
|
|
89
|
+
return parts.join("; ");
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Do not import from browser bundles. Secrets stay in Worker bindings.
|
|
4
4
|
*/
|
|
5
5
|
export { createCloudflareAccessAuthenticator, type CloudflareAccessOptions, } from "./auth/access.js";
|
|
6
|
+
export { createPasswordAuthenticator, createPagesAuthenticator, loginWithPassword, type PasswordAuthOptions, type PasswordLoginInput, } from "./auth/password.js";
|
|
7
|
+
export { SESSION_COOKIE_NAME, clearSessionCookieHeader, createSessionToken, readSessionTokenFromRequest, sessionCookieHeader, verifySessionToken, } from "./auth/session.js";
|
|
6
8
|
export type { AuthenticationFailure, AuthenticationFailureCode, AuthenticationResult, AuthenticationSuccess, Authenticator, Identity, } from "./auth/types.js";
|
|
7
9
|
export { createSiteAuthorizer, type AccessibleSiteSummary, type AuthorizationFailure, type AuthorizationResult, type AuthorizationSuccess, type SiteAuthorizer, type SiteAuthorizationConfig, type SiteBinding, type SitePermission, } from "./authz/sites.js";
|
|
8
10
|
export { createPublishFetchHandler, type PublishApiOptions, } from "./api/handler.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,mCAAmC,EACnC,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACb,QAAQ,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,yBAAyB,EACzB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,mCAAmC,EACnC,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACb,QAAQ,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,yBAAyB,EACzB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EACL,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Do not import from browser bundles. Secrets stay in Worker bindings.
|
|
4
4
|
*/
|
|
5
5
|
export { createCloudflareAccessAuthenticator, } from "./auth/access.js";
|
|
6
|
+
export { createPasswordAuthenticator, createPagesAuthenticator, loginWithPassword, } from "./auth/password.js";
|
|
7
|
+
export { SESSION_COOKIE_NAME, clearSessionCookieHeader, createSessionToken, readSessionTokenFromRequest, sessionCookieHeader, verifySessionToken, } from "./auth/session.js";
|
|
6
8
|
export { createSiteAuthorizer, } from "./authz/sites.js";
|
|
7
9
|
export { createPublishFetchHandler, } from "./api/handler.js";
|
|
8
10
|
export { createMemoryRateLimiter, } from "./api/rate-limit.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,mCAAmC,GAEpC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,mCAAmC,GAEpC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,2BAA2B,EAC3B,wBAAwB,EACxB,iBAAiB,GAGlB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EACL,oBAAoB,GASrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,yBAAyB,GAE1B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,GAExB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EACL,2BAA2B,GAI5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,GAEvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/pages/client.d.ts
CHANGED
|
@@ -56,6 +56,14 @@ export declare function createCloudflarePagesClient(options: CloudflarePagesClie
|
|
|
56
56
|
};
|
|
57
57
|
};
|
|
58
58
|
}[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Upsert production env vars. Secrets use type secret_text.
|
|
61
|
+
* Values are sent to Cloudflare only — never logged by this client.
|
|
62
|
+
*/
|
|
63
|
+
upsertEnvironmentVariables(accountId: string, projectName: string, vars: Readonly<Record<string, {
|
|
64
|
+
readonly value: string;
|
|
65
|
+
readonly secret?: boolean;
|
|
66
|
+
}>>): Promise<void>;
|
|
59
67
|
planProject: (accountId: string, input: PagesProjectInput) => Promise<PlannedPagesAction[]>;
|
|
60
68
|
applyProjectPlan(accountId: string, input: PagesProjectInput, optionsApply: {
|
|
61
69
|
confirm: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/pages/client.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;CAM7D;AAmBD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B;;;;;;;YAwGN,MAAM;cAAQ,MAAM;;4BAGzB,MAAM;cACC,MAAM;YAAM,MAAM;;4BApEd,MAAM,QAAQ,MAAM;+BA4E5B,MAAM,eAAe,MAAM;YAG5C,MAAM;uBACK;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;6BAC5B;YAAE,QAAQ,CAAC,EAAE;gBAAE,WAAW,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE;;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/pages/client.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE;QACb,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;CAM7D;AAmBD;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B;;;;;;;YAwGN,MAAM;cAAQ,MAAM;;4BAGzB,MAAM;cACC,MAAM;YAAM,MAAM;;4BApEd,MAAM,QAAQ,MAAM;+BA4E5B,MAAM,eAAe,MAAM;YAG5C,MAAM;uBACK;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE;6BAC5B;YAAE,QAAQ,CAAC,EAAE;gBAAE,WAAW,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE;;IAQlE;;;OAGG;0CAEU,MAAM,eACJ,MAAM,QACb,QAAQ,CACZ,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CACtE,GACA,OAAO,CAAC,IAAI,CAAC;6BA3FL,MAAM,SACV,iBAAiB,KACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC;gCAiHjB,MAAM,SACV,iBAAiB,gBACV;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAClD,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,kBAAkB,EAAE,CAAA;KAAE,CAAC;EAkDlE"}
|
package/dist/pages/client.js
CHANGED
|
@@ -109,6 +109,24 @@ export function createCloudflarePagesClient(options) {
|
|
|
109
109
|
listDeployments(accountId, projectName) {
|
|
110
110
|
return request("GET", `/accounts/${encodeURIComponent(accountId)}/pages/projects/${encodeURIComponent(projectName)}/deployments`);
|
|
111
111
|
},
|
|
112
|
+
/**
|
|
113
|
+
* Upsert production env vars. Secrets use type secret_text.
|
|
114
|
+
* Values are sent to Cloudflare only — never logged by this client.
|
|
115
|
+
*/
|
|
116
|
+
async upsertEnvironmentVariables(accountId, projectName, vars) {
|
|
117
|
+
const env_vars = Object.fromEntries(Object.entries(vars).map(([key, entry]) => [
|
|
118
|
+
key,
|
|
119
|
+
{
|
|
120
|
+
type: entry.secret === true ? "secret_text" : "plain_text",
|
|
121
|
+
value: entry.value,
|
|
122
|
+
},
|
|
123
|
+
]));
|
|
124
|
+
await request("PATCH", `/accounts/${encodeURIComponent(accountId)}/pages/projects/${encodeURIComponent(projectName)}`, {
|
|
125
|
+
deployment_configs: {
|
|
126
|
+
production: { env_vars },
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
},
|
|
112
130
|
planProject,
|
|
113
131
|
async applyProjectPlan(accountId, input, optionsApply) {
|
|
114
132
|
const actions = await planProject(accountId, input);
|
package/dist/pages/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/pages/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/pages/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
+
import { type PasswordAuthOptions } from "../auth/password.js";
|
|
1
2
|
import { type PublishApiOptions } from "../api/handler.js";
|
|
2
3
|
export interface PagesSiteHandlerOptions extends PublishApiOptions {
|
|
3
4
|
/** Server-bound site id. Never taken from the URL. */
|
|
4
5
|
readonly siteId: string;
|
|
6
|
+
/**
|
|
7
|
+
* Username/password admin login. When set, POST /api/login issues a session.
|
|
8
|
+
* Prefer this over Cloudflare Access for simple sites.
|
|
9
|
+
*/
|
|
10
|
+
readonly passwordAuth?: PasswordAuthOptions;
|
|
5
11
|
}
|
|
6
12
|
/**
|
|
7
13
|
* Pages Functions fetch adapter.
|
|
8
14
|
*
|
|
9
15
|
* Maps self-hosted routes onto the existing Worker publisher:
|
|
10
16
|
* - GET /api/health
|
|
17
|
+
* - POST /api/login | POST /api/logout
|
|
11
18
|
* - GET /api/content/:collection
|
|
12
19
|
* - GET /api/content/:collection/:id
|
|
13
20
|
* - POST /api/publish
|
|
14
21
|
* - GET /api/publish/status?collection=
|
|
15
22
|
*
|
|
16
23
|
* `/v1/*` continues to work for the Worker-shaped API.
|
|
17
|
-
* Static `/admin` HTML is
|
|
24
|
+
* Static `/admin` HTML is gated by the editor login UI + /api auth
|
|
25
|
+
* (Cloudflare Access remains optional).
|
|
18
26
|
*/
|
|
19
27
|
export declare function createPagesSiteHandler(options: PagesSiteHandlerOptions): (request: Request) => Promise<Response>;
|
|
20
28
|
//# sourceMappingURL=site-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-handler.d.ts","sourceRoot":"","sources":["../../src/pages/site-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"site-handler.d.ts","sourceRoot":"","sources":["../../src/pages/site-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CAC7C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAoEzC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { loginWithPassword, } from "../auth/password.js";
|
|
2
|
+
import { clearSessionCookieHeader, sessionCookieHeader, } from "../auth/session.js";
|
|
1
3
|
import { applyCors, getRequestId, jsonResponse } from "../api/http.js";
|
|
2
4
|
import { createPublishFetchHandler, } from "../api/handler.js";
|
|
3
5
|
import { checkMutationOrigin } from "./csrf.js";
|
|
@@ -6,20 +8,47 @@ import { checkMutationOrigin } from "./csrf.js";
|
|
|
6
8
|
*
|
|
7
9
|
* Maps self-hosted routes onto the existing Worker publisher:
|
|
8
10
|
* - GET /api/health
|
|
11
|
+
* - POST /api/login | POST /api/logout
|
|
9
12
|
* - GET /api/content/:collection
|
|
10
13
|
* - GET /api/content/:collection/:id
|
|
11
14
|
* - POST /api/publish
|
|
12
15
|
* - GET /api/publish/status?collection=
|
|
13
16
|
*
|
|
14
17
|
* `/v1/*` continues to work for the Worker-shaped API.
|
|
15
|
-
* Static `/admin` HTML is
|
|
18
|
+
* Static `/admin` HTML is gated by the editor login UI + /api auth
|
|
19
|
+
* (Cloudflare Access remains optional).
|
|
16
20
|
*/
|
|
17
21
|
export function createPagesSiteHandler(options) {
|
|
18
22
|
const inner = createPublishFetchHandler(options);
|
|
19
23
|
const corsAllowedOrigins = options.corsAllowedOrigins ?? [];
|
|
20
24
|
return async (request) => {
|
|
21
25
|
const requestId = getRequestId(request);
|
|
22
|
-
const respond = (status, body) =>
|
|
26
|
+
const respond = (status, body, init) => {
|
|
27
|
+
const base = applyCors(jsonResponse(status, body, { requestId }), request, corsAllowedOrigins);
|
|
28
|
+
if (init?.headers === undefined) {
|
|
29
|
+
return base;
|
|
30
|
+
}
|
|
31
|
+
const headers = new Headers(base.headers);
|
|
32
|
+
const extra = new Headers(init.headers);
|
|
33
|
+
extra.forEach((value, key) => {
|
|
34
|
+
headers.append(key, value);
|
|
35
|
+
});
|
|
36
|
+
return new Response(base.body, {
|
|
37
|
+
status: base.status,
|
|
38
|
+
statusText: base.statusText,
|
|
39
|
+
headers,
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const url = new URL(request.url);
|
|
43
|
+
if (url.pathname === "/api/login" &&
|
|
44
|
+
request.method.toUpperCase() === "POST") {
|
|
45
|
+
return handleLogin(request, options, respond, requestId);
|
|
46
|
+
}
|
|
47
|
+
if (url.pathname === "/api/logout" &&
|
|
48
|
+
request.method.toUpperCase() === "POST") {
|
|
49
|
+
const secure = url.protocol === "https:";
|
|
50
|
+
return respond(200, { ok: true }, { headers: { "Set-Cookie": clearSessionCookieHeader(secure) } });
|
|
51
|
+
}
|
|
23
52
|
const method = request.method.toUpperCase();
|
|
24
53
|
if (method === "POST" ||
|
|
25
54
|
method === "PUT" ||
|
|
@@ -40,6 +69,81 @@ export function createPagesSiteHandler(options) {
|
|
|
40
69
|
return inner(mapped);
|
|
41
70
|
};
|
|
42
71
|
}
|
|
72
|
+
async function handleLogin(request, options, respond, requestId) {
|
|
73
|
+
if (options.passwordAuth === undefined) {
|
|
74
|
+
return respond(503, {
|
|
75
|
+
error: {
|
|
76
|
+
code: "PASSWORD_AUTH_DISABLED",
|
|
77
|
+
message: "Password login is not configured. Set CONTENTRAIL_ADMIN_USERNAME, CONTENTRAIL_ADMIN_PASSWORD, and CONTENTRAIL_SESSION_SECRET.",
|
|
78
|
+
},
|
|
79
|
+
requestId,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const csrf = checkMutationOrigin(request, options.corsAllowedOrigins ?? []);
|
|
83
|
+
if (!csrf.ok) {
|
|
84
|
+
return respond(403, {
|
|
85
|
+
error: { code: "CSRF", message: csrf.message },
|
|
86
|
+
requestId,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
let body;
|
|
90
|
+
try {
|
|
91
|
+
body = await request.json();
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return respond(400, {
|
|
95
|
+
error: {
|
|
96
|
+
code: "INVALID_JSON",
|
|
97
|
+
message: "Request body is not valid JSON.",
|
|
98
|
+
},
|
|
99
|
+
requestId,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (body === null || typeof body !== "object") {
|
|
103
|
+
return respond(400, {
|
|
104
|
+
error: { code: "INVALID_BODY", message: "JSON object required." },
|
|
105
|
+
requestId,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const record = body;
|
|
109
|
+
const username = typeof record.username === "string" ? record.username : "";
|
|
110
|
+
const password = typeof record.password === "string" ? record.password : "";
|
|
111
|
+
if (username.trim() === "" || password === "") {
|
|
112
|
+
return respond(400, {
|
|
113
|
+
error: {
|
|
114
|
+
code: "INVALID_BODY",
|
|
115
|
+
message: 'Fields "username" and "password" are required.',
|
|
116
|
+
},
|
|
117
|
+
requestId,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const result = await loginWithPassword(options.passwordAuth, {
|
|
121
|
+
username,
|
|
122
|
+
password,
|
|
123
|
+
});
|
|
124
|
+
if (!result.ok) {
|
|
125
|
+
return respond(401, {
|
|
126
|
+
error: {
|
|
127
|
+
code: "INVALID_CREDENTIALS",
|
|
128
|
+
message: "Invalid username or password.",
|
|
129
|
+
},
|
|
130
|
+
requestId,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const secure = new URL(request.url).protocol === "https:";
|
|
134
|
+
return respond(200, {
|
|
135
|
+
ok: true,
|
|
136
|
+
token: result.token,
|
|
137
|
+
identity: {
|
|
138
|
+
subject: result.identity.subject,
|
|
139
|
+
...(result.identity.email !== undefined
|
|
140
|
+
? { email: result.identity.email }
|
|
141
|
+
: {}),
|
|
142
|
+
},
|
|
143
|
+
}, {
|
|
144
|
+
headers: { "Set-Cookie": sessionCookieHeader(result.token, { secure }) },
|
|
145
|
+
});
|
|
146
|
+
}
|
|
43
147
|
async function mapPagesRequest(request, siteId, respond) {
|
|
44
148
|
const url = new URL(request.url);
|
|
45
149
|
if (url.pathname === "/api/health") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-handler.js","sourceRoot":"","sources":["../../src/pages/site-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACL,yBAAyB,GAE1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"site-handler.js","sourceRoot":"","sources":["../../src/pages/site-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Source templates for Cloudflare Pages Functions.
|
|
3
3
|
* Secrets are named only — never inlined.
|
|
4
4
|
*/
|
|
5
|
-
export declare const PAGES_DEV_VARS_EXAMPLE = "# Local Pages Functions secrets (gitignored as .dev.vars).\n# Copy to .dev.vars and fill values. Never commit real secrets.\n# Do not prefix secrets with PUBLIC_ or VITE_.\n\
|
|
5
|
+
export declare const PAGES_DEV_VARS_EXAMPLE = "# Local Pages Functions secrets (gitignored as .dev.vars).\n# Copy to .dev.vars and fill values. Never commit real secrets.\n# Do not prefix secrets with PUBLIC_ or VITE_.\n\n# Default: username/password admin (no Zero Trust required)\nCONTENTRAIL_ADMIN_USERNAME=admin\nCONTENTRAIL_ADMIN_PASSWORD=\nCONTENTRAIL_SESSION_SECRET=\n\n# Site + Git publish\nCONTENTRAIL_SITE_ID=site\nCONTENTRAIL_GIT_OWNER=\nCONTENTRAIL_GIT_REPO=\nCONTENTRAIL_GIT_BRANCH=main\nCONTENTRAIL_CONTENT_ROOT=content\nCONTENTRAIL_ADMIN_ORIGIN=http://localhost:8788\nCONTENTRAIL_GITHUB_TOKEN=\n\n# Optional: Cloudflare Access instead of (or in addition to) password auth\n# CONTENTRAIL_ACCESS_TEAM_DOMAIN=\n# CONTENTRAIL_ACCESS_AUD=\n";
|
|
6
6
|
export declare function pagesApiFunctionSource(collectionsImport: string): string;
|
|
7
|
-
export declare const PAGES_MIDDLEWARE_SOURCE = "/**\n *
|
|
7
|
+
export declare const PAGES_MIDDLEWARE_SOURCE = "/**\n * Early reject for /api without a session cookie, Bearer token, or Access JWT.\n * /api/login and /api/health stay public. Static /admin HTML shows the login UI.\n */\nexport const onRequest: PagesFunction = async (context) => {\n const url = new URL(context.request.url);\n if (\n url.pathname.startsWith(\"/api/\") &&\n url.pathname !== \"/api/health\" &&\n url.pathname !== \"/api/login\" &&\n context.request.method !== \"OPTIONS\"\n ) {\n const access = context.request.headers.get(\"Cf-Access-Jwt-Assertion\");\n const authorization = context.request.headers.get(\"Authorization\");\n const cookie = context.request.headers.get(\"Cookie\") ?? \"\";\n const hasBearer =\n authorization !== null && /^Bearer\\s+\\S+/i.test(authorization);\n const hasSession = /(?:^|;\\s*)contentrail_session=/.test(cookie);\n if (\n (access === null || access.trim() === \"\") &&\n !hasBearer &&\n !hasSession\n ) {\n return new Response(\n JSON.stringify({\n error: {\n code: \"MISSING_CREDENTIAL\",\n message: \"Missing admin session. Sign in at /admin.\",\n },\n }),\n { status: 401, headers: { \"content-type\": \"application/json\" } },\n );\n }\n }\n return context.next();\n};\n";
|
|
8
8
|
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/pages/templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/pages/templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB,osBAqBlC,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAuGxE;AAED,eAAO,MAAM,uBAAuB,oyCAoCnC,CAAC"}
|
package/dist/pages/templates.js
CHANGED
|
@@ -6,24 +6,34 @@ export const PAGES_DEV_VARS_EXAMPLE = `# Local Pages Functions secrets (gitignor
|
|
|
6
6
|
# Copy to .dev.vars and fill values. Never commit real secrets.
|
|
7
7
|
# Do not prefix secrets with PUBLIC_ or VITE_.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
# Default: username/password admin (no Zero Trust required)
|
|
10
|
+
CONTENTRAIL_ADMIN_USERNAME=admin
|
|
11
|
+
CONTENTRAIL_ADMIN_PASSWORD=
|
|
12
|
+
CONTENTRAIL_SESSION_SECRET=
|
|
13
|
+
|
|
14
|
+
# Site + Git publish
|
|
15
|
+
CONTENTRAIL_SITE_ID=site
|
|
12
16
|
CONTENTRAIL_GIT_OWNER=
|
|
13
17
|
CONTENTRAIL_GIT_REPO=
|
|
14
18
|
CONTENTRAIL_GIT_BRANCH=main
|
|
15
19
|
CONTENTRAIL_CONTENT_ROOT=content
|
|
16
|
-
CONTENTRAIL_ADMIN_ORIGIN=http://localhost:
|
|
20
|
+
CONTENTRAIL_ADMIN_ORIGIN=http://localhost:8788
|
|
17
21
|
CONTENTRAIL_GITHUB_TOKEN=
|
|
22
|
+
|
|
23
|
+
# Optional: Cloudflare Access instead of (or in addition to) password auth
|
|
24
|
+
# CONTENTRAIL_ACCESS_TEAM_DOMAIN=
|
|
25
|
+
# CONTENTRAIL_ACCESS_AUD=
|
|
18
26
|
`;
|
|
19
27
|
export function pagesApiFunctionSource(collectionsImport) {
|
|
20
28
|
return `/**
|
|
21
29
|
* ContentRail Pages Functions API.
|
|
22
30
|
* Server-only. Secrets come from Pages bindings / .dev.vars — never PUBLIC_* or VITE_*.
|
|
31
|
+
* Default auth: username/password session. Cloudflare Access is optional.
|
|
23
32
|
*/
|
|
24
33
|
import {
|
|
25
34
|
createCloudflareAccessAuthenticator,
|
|
26
35
|
createPagesSiteHandler,
|
|
36
|
+
createPasswordAuthenticator,
|
|
27
37
|
createSiteAuthorizer,
|
|
28
38
|
} from "@contentrail/cloudflare";
|
|
29
39
|
import {
|
|
@@ -34,8 +44,11 @@ import {
|
|
|
34
44
|
${collectionsImport}
|
|
35
45
|
|
|
36
46
|
interface Env {
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
CONTENTRAIL_ADMIN_USERNAME?: string;
|
|
48
|
+
CONTENTRAIL_ADMIN_PASSWORD?: string;
|
|
49
|
+
CONTENTRAIL_SESSION_SECRET?: string;
|
|
50
|
+
CONTENTRAIL_ACCESS_TEAM_DOMAIN?: string;
|
|
51
|
+
CONTENTRAIL_ACCESS_AUD?: string;
|
|
39
52
|
CONTENTRAIL_SITE_ID: string;
|
|
40
53
|
CONTENTRAIL_GIT_OWNER: string;
|
|
41
54
|
CONTENTRAIL_GIT_REPO: string;
|
|
@@ -47,12 +60,45 @@ interface Env {
|
|
|
47
60
|
|
|
48
61
|
export const onRequest: PagesFunction<Env> = async (context) => {
|
|
49
62
|
const env = context.env;
|
|
63
|
+
const passwordReady =
|
|
64
|
+
Boolean(env.CONTENTRAIL_ADMIN_USERNAME?.trim()) &&
|
|
65
|
+
Boolean(env.CONTENTRAIL_ADMIN_PASSWORD) &&
|
|
66
|
+
Boolean(env.CONTENTRAIL_SESSION_SECRET?.trim());
|
|
67
|
+
const accessReady =
|
|
68
|
+
Boolean(env.CONTENTRAIL_ACCESS_TEAM_DOMAIN?.trim()) &&
|
|
69
|
+
Boolean(env.CONTENTRAIL_ACCESS_AUD?.trim());
|
|
70
|
+
|
|
71
|
+
const passwordAuth = passwordReady
|
|
72
|
+
? {
|
|
73
|
+
username: env.CONTENTRAIL_ADMIN_USERNAME!.trim(),
|
|
74
|
+
password: env.CONTENTRAIL_ADMIN_PASSWORD!,
|
|
75
|
+
sessionSecret: env.CONTENTRAIL_SESSION_SECRET!.trim(),
|
|
76
|
+
}
|
|
77
|
+
: undefined;
|
|
78
|
+
|
|
79
|
+
const authenticator = passwordReady
|
|
80
|
+
? createPasswordAuthenticator(passwordAuth!)
|
|
81
|
+
: accessReady
|
|
82
|
+
? createCloudflareAccessAuthenticator({
|
|
83
|
+
teamDomain: env.CONTENTRAIL_ACCESS_TEAM_DOMAIN!,
|
|
84
|
+
audience: env.CONTENTRAIL_ACCESS_AUD!,
|
|
85
|
+
})
|
|
86
|
+
: {
|
|
87
|
+
async authenticate() {
|
|
88
|
+
return {
|
|
89
|
+
ok: false as const,
|
|
90
|
+
status: 401 as const,
|
|
91
|
+
code: "KEY_UNAVAILABLE" as const,
|
|
92
|
+
message:
|
|
93
|
+
"Configure CONTENTRAIL_ADMIN_USERNAME/PASSWORD/SESSION_SECRET (recommended) or Cloudflare Access.",
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
50
98
|
const handler = createPagesSiteHandler({
|
|
51
99
|
siteId: env.CONTENTRAIL_SITE_ID,
|
|
52
|
-
authenticator
|
|
53
|
-
|
|
54
|
-
audience: env.CONTENTRAIL_ACCESS_AUD,
|
|
55
|
-
}),
|
|
100
|
+
authenticator,
|
|
101
|
+
...(passwordAuth !== undefined ? { passwordAuth } : {}),
|
|
56
102
|
authorizer: createSiteAuthorizer({
|
|
57
103
|
sites: {
|
|
58
104
|
[env.CONTENTRAIL_SITE_ID]: {
|
|
@@ -83,26 +129,33 @@ export const onRequest: PagesFunction<Env> = async (context) => {
|
|
|
83
129
|
`;
|
|
84
130
|
}
|
|
85
131
|
export const PAGES_MIDDLEWARE_SOURCE = `/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
132
|
+
* Early reject for /api without a session cookie, Bearer token, or Access JWT.
|
|
133
|
+
* /api/login and /api/health stay public. Static /admin HTML shows the login UI.
|
|
88
134
|
*/
|
|
89
135
|
export const onRequest: PagesFunction = async (context) => {
|
|
90
136
|
const url = new URL(context.request.url);
|
|
91
137
|
if (
|
|
92
138
|
url.pathname.startsWith("/api/") &&
|
|
93
139
|
url.pathname !== "/api/health" &&
|
|
140
|
+
url.pathname !== "/api/login" &&
|
|
94
141
|
context.request.method !== "OPTIONS"
|
|
95
142
|
) {
|
|
96
143
|
const access = context.request.headers.get("Cf-Access-Jwt-Assertion");
|
|
97
144
|
const authorization = context.request.headers.get("Authorization");
|
|
145
|
+
const cookie = context.request.headers.get("Cookie") ?? "";
|
|
98
146
|
const hasBearer =
|
|
99
147
|
authorization !== null && /^Bearer\\s+\\S+/i.test(authorization);
|
|
100
|
-
|
|
148
|
+
const hasSession = /(?:^|;\\s*)contentrail_session=/.test(cookie);
|
|
149
|
+
if (
|
|
150
|
+
(access === null || access.trim() === "") &&
|
|
151
|
+
!hasBearer &&
|
|
152
|
+
!hasSession
|
|
153
|
+
) {
|
|
101
154
|
return new Response(
|
|
102
155
|
JSON.stringify({
|
|
103
156
|
error: {
|
|
104
157
|
code: "MISSING_CREDENTIAL",
|
|
105
|
-
message: "Missing
|
|
158
|
+
message: "Missing admin session. Sign in at /admin.",
|
|
106
159
|
},
|
|
107
160
|
}),
|
|
108
161
|
{ status: 401, headers: { "content-type": "application/json" } },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/pages/templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/pages/templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBrC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,iBAAyB;IAC9D,OAAO;;;;;;;;;;;;;;;;EAgBP,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqFlB,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCtC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentrail/cloudflare",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Server-only Cloudflare Worker and Pages Functions publishing API with Access auth and Pages setup helpers.",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"jose": "^6.2.14",
|
|
32
|
-
"@contentrail/core": "0.2.
|
|
33
|
-
"@contentrail/publisher": "0.2.
|
|
32
|
+
"@contentrail/core": "0.2.4",
|
|
33
|
+
"@contentrail/publisher": "0.2.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^22.20.5",
|