fix
This commit is contained in:
parent
073300d6d2
commit
02727d17fd
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { apiContext } from "service-srv";
|
||||||
|
import { user } from "dbgen";
|
||||||
|
import { session } from "utils/session";
|
||||||
|
|
||||||
|
export const _ = {
|
||||||
|
url: "/_session",
|
||||||
|
async api() {
|
||||||
|
const { req, res } = apiContext(this);
|
||||||
|
const sdata = session.get<{
|
||||||
|
user: user & {
|
||||||
|
org: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
}>(req);
|
||||||
|
if (sdata) {
|
||||||
|
let setDefaultCookie = true;
|
||||||
|
const origin = req.headers.get("origin");
|
||||||
|
if (origin) {
|
||||||
|
const url = new URL(origin);
|
||||||
|
if (url.hostname === "localhost") {
|
||||||
|
setDefaultCookie = false;
|
||||||
|
res.setHeader("set-cookie", `${session.cookieKey}=${sdata.id};`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setDefaultCookie) {
|
||||||
|
res.setHeader(
|
||||||
|
"set-cookie",
|
||||||
|
`${session.cookieKey}=${sdata.id}; SameSite=None; Secure; HttpOnly`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sdata;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { apiContext } from "service-srv";
|
||||||
|
|
||||||
|
export const _ = {
|
||||||
|
url: "/session)}",
|
||||||
|
async api() {
|
||||||
|
const { req, res } = apiContext(this);
|
||||||
|
return "This is session.ts";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,17 @@
|
||||||
|
declare module "api/session" {
|
||||||
|
export const _: {
|
||||||
|
url: string;
|
||||||
|
api(): Promise<string>;
|
||||||
|
};
|
||||||
|
}
|
||||||
declare module "exports" {
|
declare module "exports" {
|
||||||
|
export const session: {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
path: string;
|
||||||
|
args: any[];
|
||||||
|
handler: Promise<typeof import("api/session")>;
|
||||||
|
};
|
||||||
export const _web: {
|
export const _web: {
|
||||||
name: string;
|
name: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
export const session = {
|
||||||
|
name: "session",
|
||||||
|
url: "/session)}",
|
||||||
|
path: "app/srv/api/session.ts",
|
||||||
|
args: [],
|
||||||
|
handler: import("./api/session")
|
||||||
|
}
|
||||||
export const _web = {
|
export const _web = {
|
||||||
name: "_web",
|
name: "_web",
|
||||||
url: "/_web/:id/**",
|
url: "/_web/:id/**",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { prepareApiRoutes } from "./server/api-scan";
|
||||||
g.status = "init";
|
g.status = "init";
|
||||||
|
|
||||||
await createLogger();
|
await createLogger();
|
||||||
|
g.datadir = g.mode === "dev" ? ".data" : "../data";
|
||||||
g.port = parseInt(process.env.PORT || "4550");
|
g.port = parseInt(process.env.PORT || "4550");
|
||||||
g.mode = process.argv.includes("dev") ? "dev" : "prod";
|
g.mode = process.argv.includes("dev") ? "dev" : "prod";
|
||||||
g.log.info(g.mode === "dev" ? "DEVELOPMENT" : "PRODUCTION");
|
g.log.info(g.mode === "dev" ? "DEVELOPMENT" : "PRODUCTION");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { g } from "../utils/global";
|
|
||||||
|
|
||||||
const parseQueryParams = (ctx: any) => {
|
const parseQueryParams = (ctx: any) => {
|
||||||
const pageHref = ctx.req.url;
|
const pageHref = ctx.req.url;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ type SingleRoute = {
|
||||||
|
|
||||||
export const g = global as unknown as {
|
export const g = global as unknown as {
|
||||||
status: "init" | "ready";
|
status: "init" | "ready";
|
||||||
|
datadir: string;
|
||||||
db: PrismaClient;
|
db: PrismaClient;
|
||||||
dburl: string;
|
dburl: string;
|
||||||
mode: "dev" | "prod";
|
mode: "dev" | "prod";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
import { createId } from "@paralleldrive/cuid2";
|
||||||
|
import { dirAsync } from "fs-jetpack";
|
||||||
|
import lmdb, { RootDatabase, open } from "lmdb";
|
||||||
|
import { dirname, join } from "path";
|
||||||
|
import { g } from "./global";
|
||||||
|
import { dir } from "./dir";
|
||||||
|
|
||||||
|
const cuid = createId;
|
||||||
|
type SessionEntry<T> = { id: string; expired: number; data: T };
|
||||||
|
|
||||||
|
export type SRVCache<T> = ReturnType<typeof createCache<T>>;
|
||||||
|
|
||||||
|
export const createCache = <T>() => ({
|
||||||
|
lmdb: null as unknown as RootDatabase<SessionEntry<T>>,
|
||||||
|
cookieKey: "",
|
||||||
|
async init(arg: { cookieKey: string; dbname?: string }) {
|
||||||
|
const dbpath = dir(join(g.datadir, (arg.dbname || "session") + ".lmdb"));
|
||||||
|
await dirAsync(dirname(dbpath));
|
||||||
|
self(this).lmdb = open({
|
||||||
|
path: dbpath,
|
||||||
|
compression: true,
|
||||||
|
});
|
||||||
|
self(this).cookieKey = arg.cookieKey;
|
||||||
|
},
|
||||||
|
async new(data: any, expired?: Date): Promise<SessionEntry<T>> {
|
||||||
|
const s = {
|
||||||
|
id: cuid(),
|
||||||
|
expired: expired ? expired.getTime() / 1000 : 0,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
|
||||||
|
await self(this).lmdb.put(s.id, s);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
},
|
||||||
|
get<T>(req: string | Request): null | SessionEntry<T> {
|
||||||
|
let id = "";
|
||||||
|
if (typeof req === "string") {
|
||||||
|
id = req;
|
||||||
|
} else {
|
||||||
|
const cookie = req.headers.get("cookie");
|
||||||
|
if (cookie) {
|
||||||
|
id = parseCookies(cookie)[self(this).cookieKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const s = self(this).lmdb.get(id) as unknown as SessionEntry<T>;
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
if (s.expired !== 0 && Date.now() / 1000 > s.expired) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
async set(id: string, data: any): Promise<SessionEntry<T>> {
|
||||||
|
await self(this).lmdb.put(id, data);
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
del(id: string) {
|
||||||
|
return self(this).lmdb.remove(id);
|
||||||
|
},
|
||||||
|
keys() {
|
||||||
|
return new Promise<lmdb.Key[]>((resolve) => {
|
||||||
|
const keys: lmdb.Key[] = [];
|
||||||
|
self(this)
|
||||||
|
.lmdb.getKeys()
|
||||||
|
.forEach((e) => {
|
||||||
|
keys.push(e);
|
||||||
|
});
|
||||||
|
resolve(keys);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
self(this).lmdb.clearSync();
|
||||||
|
},
|
||||||
|
count() {
|
||||||
|
return self(this).lmdb.getCount();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const session = createCache();
|
||||||
|
|
||||||
|
const self = (me: Session) => me;
|
||||||
|
type Session = typeof session;
|
||||||
|
|
||||||
|
export function parseCookies(cookieHeader: string) {
|
||||||
|
const list: Record<string, string> = {};
|
||||||
|
if (!cookieHeader) return list;
|
||||||
|
|
||||||
|
cookieHeader.split(`;`).forEach(function (cookie) {
|
||||||
|
let [name, ...rest] = cookie.split(`=`);
|
||||||
|
name = name?.trim();
|
||||||
|
if (!name) return;
|
||||||
|
const value = rest.join(`=`).trim();
|
||||||
|
if (!value) return;
|
||||||
|
list[name] = decodeURIComponent(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"dbgen": [
|
||||||
|
"./node_modules/.prisma/client/index.d.ts"
|
||||||
|
],
|
||||||
"service-srv": [
|
"service-srv": [
|
||||||
"./pkgs/core/server/api-ctx.ts"
|
"./pkgs/core/server/api-ctx.ts"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue