Create CET-6 90-day check-in site
This commit is contained in:
commit
5c63f9f120
109 files changed
+19290
No files matched your search
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 OpenAI
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,230 @@
|
||||
// Vendored from @openai/sites-vite-plugin 0.2.0 (openai/sites#9).
|
||||
// See sites-vite-plugin.LICENSE for the upstream MIT license.
|
||||
import { access, cp, mkdir, rm } from "node:fs/promises";
|
||||
import type { IncomingMessage, ServerResponse } from "node:http";
|
||||
import { resolve } from "node:path";
|
||||
import type { Plugin } from "vite";
|
||||
|
||||
const localUserId = "local_seedy";
|
||||
const localEmail = "seedy@sites.test";
|
||||
const localFullName = "Seedy";
|
||||
const localCookieName = "__sites_local_auth";
|
||||
const localHosts = new Set(["localhost", "127.0.0.1", "::1"]);
|
||||
const localAddresses = new Set(["127.0.0.1", "::1", "::ffff:127.0.0.1"]);
|
||||
const authPaths = new Set([
|
||||
"/signin-with-chatgpt",
|
||||
"/signout-with-chatgpt",
|
||||
"/callback",
|
||||
]);
|
||||
|
||||
async function exists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await access(path);
|
||||
return true;
|
||||
} catch (error) {
|
||||
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
||||
return false;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export function sites({ mockAuth = true } = {}): Plugin {
|
||||
let root = process.cwd();
|
||||
let command: "build" | "serve" = "build";
|
||||
|
||||
return {
|
||||
name: "sites",
|
||||
configResolved(config) {
|
||||
root = config.root;
|
||||
command = config.command;
|
||||
},
|
||||
configureServer(server) {
|
||||
if (!mockAuth) return;
|
||||
const secure = Boolean(server.config.server.https);
|
||||
|
||||
server.config.logger.info(`Sites local sign-in: ${localEmail}`);
|
||||
server.middlewares.use((request, response, next) => {
|
||||
for (const name of Object.keys(request.headers)) {
|
||||
if (name.startsWith("oai-authenticated-user-")) {
|
||||
removeHeader(request, name);
|
||||
}
|
||||
}
|
||||
|
||||
let authority: URL;
|
||||
let url: URL;
|
||||
try {
|
||||
authority = new URL(
|
||||
`${secure ? "https" : "http"}://${request.headers.host}`,
|
||||
);
|
||||
url = new URL(request.url ?? "/", authority);
|
||||
} catch {
|
||||
if (authPaths.has((request.url ?? "/").split("?")[0])) {
|
||||
respond(response, 403);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const hostname = authority.hostname
|
||||
.replace(/^\[|\]$/g, "")
|
||||
.toLowerCase();
|
||||
if (
|
||||
!localHosts.has(hostname) ||
|
||||
!localAddresses.has(request.socket.remoteAddress ?? "") ||
|
||||
url.origin !== authority.origin
|
||||
) {
|
||||
if (authPaths.has(url.pathname)) respond(response, 403);
|
||||
else next();
|
||||
return;
|
||||
}
|
||||
|
||||
const cookies = (request.headers.cookie ?? "")
|
||||
.split(";")
|
||||
.map((cookie) => cookie.trim())
|
||||
.filter(Boolean);
|
||||
const signInCookies = cookies
|
||||
.filter((cookie) => cookie.startsWith(`${localCookieName}=`))
|
||||
.map((cookie) => cookie.slice(localCookieName.length + 1));
|
||||
const applicationCookies = cookies.filter(
|
||||
(cookie) => !cookie.startsWith(`${localCookieName}=`),
|
||||
);
|
||||
if (applicationCookies.length !== cookies.length) {
|
||||
removeHeader(request, "cookie");
|
||||
if (applicationCookies.length) {
|
||||
setHeader(request, "cookie", applicationCookies.join("; "));
|
||||
}
|
||||
}
|
||||
|
||||
if (url.pathname === "/callback") {
|
||||
respond(response, 501);
|
||||
return;
|
||||
}
|
||||
|
||||
const signIn = url.pathname === "/signin-with-chatgpt";
|
||||
const signOut = url.pathname === "/signout-with-chatgpt";
|
||||
if (!signIn && !signOut) {
|
||||
if (signInCookies.length === 1 && signInCookies[0] === "1") {
|
||||
setHeader(request, "oai-authenticated-user-id", localUserId);
|
||||
setHeader(request, "oai-authenticated-user-email", localEmail);
|
||||
setHeader(
|
||||
request,
|
||||
"oai-authenticated-user-full-name",
|
||||
localFullName,
|
||||
);
|
||||
setHeader(
|
||||
request,
|
||||
"oai-authenticated-user-full-name-encoding",
|
||||
"percent-encoded-utf-8",
|
||||
);
|
||||
}
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
(request.headers.origin && request.headers.origin !== url.origin) ||
|
||||
request.headers["sec-fetch-site"] === "cross-site"
|
||||
) {
|
||||
respond(response, 403);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
request.headers["next-router-prefetch"] !== undefined ||
|
||||
request.headers["x-middleware-prefetch"] === "1" ||
|
||||
[request.headers.purpose, request.headers["sec-purpose"]].some(
|
||||
(value) =>
|
||||
typeof value === "string" &&
|
||||
value
|
||||
.split(/[;,]/)
|
||||
.some((part) => part.trim().toLowerCase() === "prefetch"),
|
||||
)
|
||||
) {
|
||||
respond(response, 204);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
request.method !== "GET" &&
|
||||
(!signOut || request.method !== "POST")
|
||||
) {
|
||||
response.setHeader("Allow", signIn ? "GET" : "GET, POST");
|
||||
respond(response, 405);
|
||||
return;
|
||||
}
|
||||
|
||||
response.statusCode = request.method === "POST" ? 303 : 302;
|
||||
response.setHeader("Cache-Control", "private, no-store");
|
||||
response.setHeader(
|
||||
"Location",
|
||||
safeReturn(url.searchParams.get("return_to")),
|
||||
);
|
||||
response.setHeader(
|
||||
"Set-Cookie",
|
||||
`${localCookieName}=${signIn ? "1" : ""}; Path=/; ${
|
||||
signOut ? "Max-Age=0; " : ""
|
||||
}HttpOnly; SameSite=Lax${secure ? "; Secure" : ""}`,
|
||||
);
|
||||
response.end();
|
||||
});
|
||||
},
|
||||
async closeBundle() {
|
||||
if (command !== "build") return;
|
||||
|
||||
const outputDirectory = resolve(root, "dist", ".openai");
|
||||
const hostingConfig = resolve(root, ".openai", "hosting.json");
|
||||
const drizzleSource = resolve(root, "drizzle");
|
||||
|
||||
await rm(outputDirectory, { recursive: true, force: true });
|
||||
await mkdir(outputDirectory, { recursive: true });
|
||||
|
||||
await cp(hostingConfig, resolve(outputDirectory, "hosting.json"));
|
||||
if (await exists(drizzleSource)) {
|
||||
await cp(drizzleSource, resolve(outputDirectory, "drizzle"), {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function removeHeader(request: IncomingMessage, name: string): void {
|
||||
delete request.headers[name];
|
||||
for (let index = request.rawHeaders.length - 2; index >= 0; index -= 2) {
|
||||
if (request.rawHeaders[index]?.toLowerCase() === name) {
|
||||
request.rawHeaders.splice(index, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setHeader(
|
||||
request: IncomingMessage,
|
||||
name: string,
|
||||
value: string,
|
||||
): void {
|
||||
removeHeader(request, name);
|
||||
request.headers[name] = value;
|
||||
request.rawHeaders.push(name, value);
|
||||
}
|
||||
|
||||
function respond(response: ServerResponse, status: number): void {
|
||||
response.statusCode = status;
|
||||
response.setHeader("Cache-Control", "private, no-store");
|
||||
response.end();
|
||||
}
|
||||
|
||||
function safeReturn(value: string | null): string {
|
||||
if (!value?.startsWith("/") || value.startsWith("//")) return "/";
|
||||
|
||||
try {
|
||||
const url = new URL(value, "http://localhost");
|
||||
if (url.origin !== "http://localhost" || authPaths.has(url.pathname)) {
|
||||
return "/";
|
||||
}
|
||||
return `${url.pathname}${url.search}${url.hash}`;
|
||||
} catch {
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user