Template
1
0

feat: initial boilerplate

This commit is contained in:
2025-08-11 20:45:41 +02:00
parent d98524254f
commit 1215a98afc
148 changed files with 6935 additions and 2060 deletions

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCy5ZoXkKP9mZTk
sKbQdSwspHZqyMH33Gby23+9ycNHMIww7djcWFfPRW4s7tu3SNaac6qVg9OI43+Z
6BPXxuh4nhQ4LX5No9iVEmcWvZtKE4ghwzsoU0llT7+aKl9UYvgqU1YX4zyfiyo2
bW0nVPasEHTyjLCVPK5BKlq+UmuyJTVcduALDnVETpUefu5Vca6tIRXsOovvAf5b
zmcxPccaXIatR/AeipxT0YWoInn8dxD3kyFgTPXtinuBZxvp6MUeSs5IE8OJRJRP
PEo1MQ9HFw9aYRIn9uIkbARbNZMGz77zB1+0TrPGyKOB5lLReWGMUFAJhjLrnTsY
z19se4kNAgMBAAECgf9QkG6A6ViiHIMnUskIDeP5Xir19d9kbGwrcn0F2OXYaX+l
Oot9w3KM6loRJx380/zk/e0Uch1MeZ2fyqQRUmAGQIzkXUm6LUWIekYQN6vZ3JlP
YA2/M+otdd8Tpws9hFSDMUlx0SP3GAi0cE48xdBkVAT0NjZ3Jjor7Wv6GLe//Kzg
1OVrbPAA/+RrPB+BQn5nmZFT0aLuLpyxB4f4ArHG/8DEBY49Syy7/3Ke0kfHMnhl
5Eg5Yau89wSLqEoUSuQvNixu/5nTTQ6v1VYPVG8D1hn773SbNoY9o5vZOPRl1P0q
9YC/qpzPJkm/A5TZLsoalIxuGTdwts+DaEeoKmECgYEA5CddLQbMNu9kYElxpSA3
xXoTL71ZBCQsWExmJrcGe2lQhGO40lF8jE6QnEvMt0mp8Dg9n2ih4J87+2Ozb0fp
2G2ilNeMxM7keywA/+Cwg71QyImppU0lQ5PYLv+pllfxN8FPpLBluy7rDahzphkn
1rijqI5d4bHNG6IgD2ynteECgYEAyLs2eBWxX39Jff3OdpSVmHf7NtacbtsUf1qM
RJSvLsiSwKn39n1+Y6ebzftxm/XD/j8FbN8XvMZMI4OrlfzP+YJaTybIbHrLzCE2
B5E9j0GbJRhJ/D3l9FQBGdY4g5yC4mgbncXURQqqQTtKk2d+ixZSrw8iyDGN+aMJ
ybqZoK0CgYALb6GvARk5Y7R/Uw8cPMou3tiZWv9cQsfqQSIZrLDpfLTpfeokuKrq
iYGcI/yF725SOS91jxQWI0Upa6zx1gP1skEk/szyjIBNYD5IlSWj5NhoxOW5AG3u
vjlm2a/RdmUD62+njKP8xvRHQftSBw7FJ4okh8ZS6suiJ/U9cK/TYQKBgFg+jTyP
dNGhuKJN0NUqjvVfUa4S/ORzJXizStTfdIAhpvpR/nN7SfPvfDw6nQBOM+JyvCTX
kqznlBNM0EL4yElNN/xx9UxTU4Ki2wjKngB7fAP7wJLGd3BI+c7s8R1S0etMj091
59KOVLimoytYJTZqEuFoywatWlfzh9sKUH1lAoGBAID6mqGL3SZhh+i2/kAytfzw
UswTQqA0CCBTzN/Eo1QozmUVTLQPj8rBchNSoiSc92y+lPIL8ePdU7imRB77i+9D
9MSmc5u3ACACOSkwF0JCEGN+Rju4HR5wwm3h6Kvf/FQ3yvSEOKAWhqXIY95qtYTU
j3O+iJbY32pbQsawIAkw
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsuWaF5Cj/ZmU5LCm0HUs
LKR2asjB99xm8tt/vcnDRzCMMO3Y3FhXz0VuLO7bt0jWmnOqlYPTiON/megT18bo
eJ4UOC1+TaPYlRJnFr2bShOIIcM7KFNJZU+/mipfVGL4KlNWF+M8n4sqNm1tJ1T2
rBB08oywlTyuQSpavlJrsiU1XHbgCw51RE6VHn7uVXGurSEV7DqL7wH+W85nMT3H
GlyGrUfwHoqcU9GFqCJ5/HcQ95MhYEz17Yp7gWcb6ejFHkrOSBPDiUSUTzxKNTEP
RxcPWmESJ/biJGwEWzWTBs++8wdftE6zxsijgeZS0XlhjFBQCYYy6507GM9fbHuJ
DQIDAQAB
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,87 @@
import { Auth, ResolvedSession } from "@valkyr/auth";
import z from "zod";
import { db } from "~libraries/read-store/database.ts";
import { config } from "./config.ts";
export const auth = new Auth(
{
settings: {
algorithm: "RS256",
privateKey: config.privateKey,
publicKey: config.publicKey,
issuer: "https://balto.health",
audience: "https://balto.health",
},
session: z.object({
accountId: z.string(),
}),
permissions: {
admin: ["create", "read", "update", "delete"],
organization: ["create", "read", "update", "delete"],
consultant: ["create", "read", "update", "delete"],
task: ["create", "update", "read", "delete"],
} as const,
guards: [],
},
{
roles: {
async add(role) {
await db.collection("roles").insertOne(role);
},
async getById(id) {
const role = await db.collection("roles").findOne({ id });
if (role === null) {
return undefined;
}
return role;
},
async getBySession({ accountId }) {
const account = await db.collection("accounts").findOne({ id: accountId });
if (account === null) {
return [];
}
return db
.collection("roles")
.find({ id: { $in: account.roles } })
.toArray();
},
async setPermissions() {
throw new Error("MongoRolesProvider > .setPermissions is managed by Role aggregate projections");
},
async delete(id) {
await db.collection("roles").deleteOne({ id });
},
async assignAccount(roleId: string, accountId: string): Promise<void> {
await db.collection("accounts").updateOne(
{ id: accountId },
{
$push: {
roles: roleId,
},
},
);
},
async removeAccount(roleId: string, accountId: string): Promise<void> {
await db.collection("roles").updateOne(
{ id: accountId },
{
$pull: {
roles: roleId,
},
},
);
},
},
},
);
export type Session = ResolvedSession<typeof auth>;
export type Permissions = (typeof auth)["$permissions"];

View File

@@ -0,0 +1,25 @@
import { readFile } from "node:fs/promises";
import { resolve } from "node:path";
import type { SerializeOptions } from "cookie";
import { getEnvironmentVariable, toBoolean } from "~libraries/config/mod.ts";
export const config = {
privateKey: getEnvironmentVariable(
"AUTH_PRIVATE_KEY",
await readFile(resolve(import.meta.dirname!, ".keys", "private"), "utf-8"),
),
publicKey: getEnvironmentVariable(
"AUTH_PUBLIC_KEY",
await readFile(resolve(import.meta.dirname!, ".keys", "public"), "utf-8"),
),
cookie: (maxAge: number) =>
({
httpOnly: true,
secure: getEnvironmentVariable("AUTH_COOKIE_SECURE", toBoolean, "false"), // Set to true for HTTPS in production
maxAge,
path: "/",
sameSite: "strict",
}) satisfies SerializeOptions,
};

View File

@@ -0,0 +1,6 @@
import { auth } from "./auth.ts";
export * from "./auth.ts";
export * from "./config.ts";
export type Auth = typeof auth;