Merge branch 'Lokowitz-fix-crowdsec-config'

This commit is contained in:
Owen 2025-04-07 21:15:47 -04:00
commit 0450f62108
No known key found for this signature in database
GPG key ID: 8271FDFFD9E0CCBD
179 changed files with 1099 additions and 579 deletions

View file

@ -7,7 +7,7 @@ RUN npm ci
COPY . .
RUN npx drizzle-kit generate --dialect sqlite --schema ./server/db/schema.ts --out init
RUN npx drizzle-kit generate --dialect sqlite --schema ./server/db/schemas/ --out init
RUN npm run build
@ -16,7 +16,7 @@ FROM node:20-alpine AS runner
WORKDIR /app
# Curl used for the health checks
RUN apk add --no-cache curl
RUN apk add --no-cache curl
COPY package.json package-lock.json ./
RUN npm ci --only=production && npm cache clean --force

View file

@ -18,6 +18,9 @@ server:
internal_hostname: "pangolin"
session_cookie_name: "p_session_token"
resource_access_token_param: "p_token"
resource_access_token_headers:
id: "P-Access-Token-Id"
token: "P-Access-Token"
resource_session_request_param: "p_session_request"
traefik:
@ -35,7 +38,7 @@ gerbil:
rate_limits:
global:
window_minutes: 1
max_requests: 100
max_requests: 500
users:
server_admin:

View file

@ -4,10 +4,10 @@ import path from "path";
export default defineConfig({
dialect: "sqlite",
schema: path.join("server", "db", "schema.ts"),
schema: path.join("server", "db", "schemas"),
out: path.join("server", "migrations"),
verbose: true,
dbCredentials: {
url: path.join(APP_PATH, "db", "db.sqlite"),
},
url: path.join(APP_PATH, "db", "db.sqlite")
}
});

View file

@ -18,6 +18,9 @@ server:
internal_hostname: "pangolin"
session_cookie_name: "p_session_token"
resource_access_token_param: "p_token"
resource_access_token_headers:
id: "P-Access-Token-Id"
token: "P-Access-Token"
resource_session_request_param: "p_session_request"
cors:
origins: ["https://{{.DashboardDomain}}"]

View file

@ -0,0 +1,6 @@
listen_addr: 0.0.0.0:7422
appsec_config: crowdsecurity/appsec-default
name: myAppSecComponent
source: appsec
labels:
type: appsec

View file

@ -0,0 +1,5 @@
poll_without_inotify: false
filenames:
- /var/log/traefik/*.log
labels:
type: traefik

View file

@ -1,18 +0,0 @@
filenames:
- /var/log/auth.log
- /var/log/syslog
labels:
type: syslog
---
poll_without_inotify: false
filenames:
- /var/log/traefik/*.log
labels:
type: traefik
---
listen_addr: 0.0.0.0:7422
appsec_config: crowdsecurity/appsec-default
name: myAppSecComponent
source: appsec
labels:
type: appsec

View file

@ -7,7 +7,6 @@ services:
COLLECTIONS: crowdsecurity/traefik crowdsecurity/appsec-virtual-patching crowdsecurity/appsec-generic-rules
ENROLL_INSTANCE_NAME: "pangolin-crowdsec"
PARSERS: crowdsecurity/whitelists
ACQUIRE_FILES: "/var/log/traefik/*.log"
ENROLL_TAGS: docker
healthcheck:
test: ["CMD", "cscli", "capi", "status"]
@ -18,13 +17,8 @@ services:
- ./config/crowdsec:/etc/crowdsec # crowdsec config
- ./config/crowdsec/db:/var/lib/crowdsec/data # crowdsec db
# log bind mounts into crowdsec
- ./config/crowdsec_logs/auth.log:/var/log/auth.log:ro # auth.log
- ./config/crowdsec_logs/syslog:/var/log/syslog:ro # syslog
- ./config/crowdsec_logs:/var/log # crowdsec logs
- ./config/traefik/logs:/var/log/traefik # traefik logs
ports:
- 6060:6060 # metrics endpoint for prometheus
expose:
- 6060 # metrics endpoint for prometheus
restart: unless-stopped
command: -t # Add test config flag to verify configuration
command: -t # Add test config flag to verify configuration

View file

@ -25,7 +25,7 @@ func installCrowdsec(config Config) error {
}
os.MkdirAll("config/crowdsec/db", 0755)
os.MkdirAll("config/crowdsec_logs/syslog", 0755)
os.MkdirAll("config/crowdsec/acquis.d", 0755)
os.MkdirAll("config/traefik/logs", 0755)
if err := copyDockerService("config/crowdsec/docker-compose.yml", "docker-compose.yml", "crowdsec"); err != nil {

View file

@ -14,7 +14,7 @@ import { logIncomingMiddleware } from "./middlewares/logIncoming";
import { csrfProtectionMiddleware } from "./middlewares/csrfProtection";
import helmet from "helmet";
const dev = process.env.ENVIRONMENT !== "prod";
const dev = config.isDev;
const externalPort = config.getRawConfig().server.external_port;
export function createApiServer() {

View file

@ -1,6 +1,6 @@
import { Request } from "express";
import { db } from "@server/db";
import { userActions, roleActions, userOrgs } from "@server/db/schema";
import { userActions, roleActions, userOrgs } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
@ -63,6 +63,7 @@ export enum ActionsEnum {
listResourceRules = "listResourceRules",
updateResourceRule = "updateResourceRule",
listOrgDomains = "listOrgDomains",
createNewt = "createNewt",
}
export async function checkUserActionPermission(

View file

@ -1,6 +1,6 @@
import db from "@server/db";
import { and, eq } from "drizzle-orm";
import { roleResources, userResources } from "@server/db/schema";
import { roleResources, userResources } from "@server/db/schemas";
export async function canUserAccessResource({
userId,

View file

@ -1,5 +1,5 @@
import db from "@server/db";
import { UserInvite, userInvites } from "@server/db/schema";
import { UserInvite, userInvites } from "@server/db/schemas";
import { isWithinExpirationDate } from "oslo";
import { verifyPassword } from "./password";
import { eq } from "drizzle-orm";

View file

@ -1,5 +1,5 @@
import { db } from '@server/db';
import { limitsTable } from '@server/db/schema';
import { limitsTable } from '@server/db/schemas';
import { and, eq } from 'drizzle-orm';
import createHttpError from 'http-errors';
import HttpCode from '@server/types/HttpCode';
@ -37,4 +37,4 @@ export async function checkOrgLimit({ orgId, limitName, currentValue, increment
}
throw createHttpError(HttpCode.INTERNAL_SERVER_ERROR, 'Unknown error occurred while checking limit');
}
}
}

View file

@ -1,5 +1,5 @@
import db from "@server/db";
import { resourceOtp } from "@server/db/schema";
import { resourceOtp } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import { createDate, isWithinExpirationDate, TimeSpan } from "oslo";
import { alphabet, generateRandomString, sha256 } from "oslo/crypto";

View file

@ -1,7 +1,7 @@
import { TimeSpan, createDate } from "oslo";
import { generateRandomString, alphabet } from "oslo/crypto";
import db from "@server/db";
import { users, emailVerificationCodes } from "@server/db/schema";
import { users, emailVerificationCodes } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { sendEmail } from "@server/emails";
import config from "@server/lib/config";

View file

@ -9,7 +9,7 @@ import {
sessions,
User,
users
} from "@server/db/schema";
} from "@server/db/schemas";
import db from "@server/db";
import { eq, inArray } from "drizzle-orm";
import config from "@server/lib/config";

View file

@ -2,7 +2,7 @@ import {
encodeHexLowerCase,
} from "@oslojs/encoding";
import { sha256 } from "@oslojs/crypto/sha2";
import { Newt, newts, newtSessions, NewtSession } from "@server/db/schema";
import { Newt, newts, newtSessions, NewtSession } from "@server/db/schemas";
import db from "@server/db";
import { eq } from "drizzle-orm";

View file

@ -1,6 +1,6 @@
import { encodeHexLowerCase } from "@oslojs/encoding";
import { sha256 } from "@oslojs/crypto/sha2";
import { resourceSessions, ResourceSession } from "@server/db/schema";
import { resourceSessions, ResourceSession } from "@server/db/schemas";
import db from "@server/db";
import { eq, and } from "drizzle-orm";
import config from "@server/lib/config";

View file

@ -1,6 +1,6 @@
import { verify } from "@node-rs/argon2";
import db from "@server/db";
import { twoFactorBackupCodes } from "@server/db/schema";
import { twoFactorBackupCodes } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { decodeHex } from "oslo/encoding";
import { TOTPController } from "oslo/otp";

View file

@ -3,53 +3,95 @@ import {
Resource,
ResourceAccessToken,
resourceAccessToken,
} from "@server/db/schema";
resources
} from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import { isWithinExpirationDate } from "oslo";
import { verifyPassword } from "./password";
import { encodeHexLowerCase } from "@oslojs/encoding";
import { sha256 } from "@oslojs/crypto/sha2";
export async function verifyResourceAccessToken({
resource,
accessToken,
accessTokenId,
accessToken
resourceId
}: {
resource: Resource;
accessTokenId: string;
accessToken: string;
accessTokenId?: string;
resourceId?: number; // IF THIS IS NOT SET, THE TOKEN IS VALID FOR ALL RESOURCES
}): Promise<{
valid: boolean;
error?: string;
tokenItem?: ResourceAccessToken;
resource?: Resource;
}> {
const [result] = await db
.select()
.from(resourceAccessToken)
.where(
and(
eq(resourceAccessToken.resourceId, resource.resourceId),
eq(resourceAccessToken.accessTokenId, accessTokenId)
)
)
.limit(1);
const accessTokenHash = encodeHexLowerCase(
sha256(new TextEncoder().encode(accessToken))
);
const tokenItem = result;
let tokenItem: ResourceAccessToken | undefined;
let resource: Resource | undefined;
if (!tokenItem) {
if (!accessTokenId) {
const [res] = await db
.select()
.from(resourceAccessToken)
.where(and(eq(resourceAccessToken.tokenHash, accessTokenHash)))
.innerJoin(
resources,
eq(resourceAccessToken.resourceId, resources.resourceId)
);
tokenItem = res?.resourceAccessToken;
resource = res?.resources;
} else {
const [res] = await db
.select()
.from(resourceAccessToken)
.where(and(eq(resourceAccessToken.accessTokenId, accessTokenId)))
.innerJoin(
resources,
eq(resourceAccessToken.resourceId, resources.resourceId)
);
if (res && res.resourceAccessToken) {
if (res.resourceAccessToken.tokenHash?.startsWith("$argon")) {
const validCode = await verifyPassword(
accessToken,
res.resourceAccessToken.tokenHash
);
if (!validCode) {
return {
valid: false,
error: "Invalid access token"
};
}
} else {
const tokenHash = encodeHexLowerCase(
sha256(new TextEncoder().encode(accessToken))
);
if (res.resourceAccessToken.tokenHash !== tokenHash) {
return {
valid: false,
error: "Invalid access token"
};
}
}
}
tokenItem = res?.resourceAccessToken;
resource = res?.resources;
}
if (!tokenItem || !resource) {
return {
valid: false,
error: "Access token does not exist for resource"
};
}
const validCode = await verifyPassword(accessToken, tokenItem.tokenHash);
if (!validCode) {
return {
valid: false,
error: "Invalid access token"
};
}
if (
tokenItem.expiresAt &&
!isWithinExpirationDate(new Date(tokenItem.expiresAt))
@ -60,8 +102,16 @@ export async function verifyResourceAccessToken({
};
}
if (resourceId && resource.resourceId !== resourceId) {
return {
valid: false,
error: "Resource ID does not match"
};
}
return {
valid: true,
tokenItem
tokenItem,
resource
};
}

View file

@ -1,6 +1,6 @@
import { drizzle } from "drizzle-orm/better-sqlite3";
import Database from "better-sqlite3";
import * as schema from "@server/db/schema";
import * as schema from "@server/db/schemas";
import path from "path";
import fs from "fs/promises";
import { APP_PATH } from "@server/lib/consts";

View file

@ -1,7 +1,7 @@
import { join } from "path";
import { readFileSync } from "fs";
import { db } from "@server/db";
import { exitNodes, sites } from "./schema";
import { exitNodes, sites } from "./schemas/schema";
import { eq, and } from "drizzle-orm";
import { __DIRNAME } from "@server/lib/consts";

View file

@ -0,0 +1 @@
export * from "./schema";

View file

@ -76,7 +76,8 @@ export const resources = sqliteTable("resources", {
isBaseDomain: integer("isBaseDomain", { mode: "boolean" }),
applyRules: integer("applyRules", { mode: "boolean" })
.notNull()
.default(false)
.default(false),
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true)
});
export const targets = sqliteTable("targets", {

View file

@ -2,7 +2,7 @@ import { runSetupFunctions } from "./setup";
import { createApiServer } from "./apiServer";
import { createNextServer } from "./nextServer";
import { createInternalServer } from "./internalServer";
import { Session, User, UserOrg } from "./db/schema";
import { Session, User, UserOrg } from "./db/schemas/schema";
async function startServers() {
await runSetupFunctions();

View file

@ -1,6 +1,6 @@
import db from "@server/db";
import { and, eq } from "drizzle-orm";
import { roleResources, userResources } from "@server/db/schema";
import { roleResources, userResources } from "@server/db/schemas";
export async function canUserAccessResource({
userId,

View file

@ -11,7 +11,7 @@ import {
import { passwordSchema } from "@server/auth/passwordSchema";
import stoi from "./stoi";
import db from "@server/db";
import { SupporterKey, supporterKey } from "@server/db/schema";
import { SupporterKey, supporterKey } from "@server/db/schemas";
import { suppressDeprecationWarnings } from "moment";
import { eq } from "drizzle-orm";
@ -66,6 +66,10 @@ const configSchema = z.object({
internal_hostname: z.string().transform((url) => url.toLowerCase()),
session_cookie_name: z.string(),
resource_access_token_param: z.string(),
resource_access_token_headers: z.object({
id: z.string(),
token: z.string()
}),
resource_session_request_param: z.string(),
dashboard_session_length_hours: z
.number()
@ -163,6 +167,8 @@ export class Config {
supporterHiddenUntil: number | null = null;
isDev: boolean = process.env.ENVIRONMENT !== "prod";
constructor() {
this.loadConfig();
}
@ -237,6 +243,10 @@ export class Config {
: "false";
process.env.RESOURCE_ACCESS_TOKEN_PARAM =
parsedConfig.data.server.resource_access_token_param;
process.env.RESOURCE_ACCESS_TOKEN_HEADERS_ID =
parsedConfig.data.server.resource_access_token_headers.id;
process.env.RESOURCE_ACCESS_TOKEN_HEADERS_TOKEN =
parsedConfig.data.server.resource_access_token_headers.token;
process.env.RESOURCE_SESSION_REQUEST_PARAM =
parsedConfig.data.server.resource_session_request_param;
process.env.FLAGS_ALLOW_BASE_DOMAIN_RESOURCES = parsedConfig.data.flags
@ -245,7 +255,9 @@ export class Config {
: "false";
process.env.DASHBOARD_URL = parsedConfig.data.app.dashboard_url;
this.checkSupporterKey();
if (!this.isDev) {
this.checkSupporterKey();
}
this.rawConfig = parsedConfig.data;
}
@ -331,13 +343,13 @@ export class Config {
// update the supporter key in the database
await db
.update(supporterKey)
.set({
tier: data.data.tier || null,
phrase: data.data.cutePhrase || null,
valid: true
})
.where(eq(supporterKey.keyId, key.keyId));
.update(supporterKey)
.set({
tier: data.data.tier || null,
phrase: data.data.cutePhrase || null,
valid: true
})
.where(eq(supporterKey.keyId, key.keyId));
} catch (e) {
this.supporterData = key;
console.error("Failed to validate supporter key", e);

View file

@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url";
// This is a placeholder value replaced by the build process
export const APP_VERSION = "1.1.0";
export const APP_VERSION = "1.2.0";
export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME);

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { userOrgs, orgs } from "@server/db/schema";
import { userOrgs, orgs } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { resourceAccessToken, resources, userOrgs } from "@server/db/schema";
import { resourceAccessToken, resources, userOrgs } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { roles, userOrgs } from "@server/db/schema";
import { roles, userOrgs } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { userOrgs } from "@server/db/schema";
import { userOrgs } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -5,7 +5,7 @@ import {
userOrgs,
userResources,
roleResources,
} from "@server/db/schema";
} from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { roles, userOrgs } from "@server/db/schema";
import { roles, userOrgs } from "@server/db/schemas";
import { and, eq, inArray } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
@ -44,6 +44,8 @@ export async function verifyRoleAccess(
);
}
const orgIds = new Set(rolesData.map((role) => role.orgId));
// Check user access to each role's organization
for (const role of rolesData) {
const userOrgRole = await db
@ -69,7 +71,16 @@ export async function verifyRoleAccess(
req.userOrgId = role.orgId;
}
const orgId = req.userOrgId;
if (orgIds.size > 1) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"Roles must belong to the same organization"
)
);
}
const orgId = orgIds.values().next().value;
if (!orgId) {
return next(
@ -105,3 +116,4 @@ export async function verifyRoleAccess(
);
}
}

View file

@ -1,7 +1,7 @@
import { NextFunction, Response } from "express";
import ErrorResponse from "@server/types/ErrorResponse";
import { db } from "@server/db";
import { users } from "@server/db/schema";
import { users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { userOrgs } from "@server/db/schema";
import { userOrgs } from "@server/db/schemas";
import { and, eq, inArray, or } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -6,7 +6,7 @@ import {
userSites,
roleSites,
roles,
} from "@server/db/schema";
} from "@server/db/schemas";
import { and, eq, or } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { resources, targets, userOrgs } from "@server/db/schema";
import { resources, targets, userOrgs } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { NextFunction, Response } from "express";
import ErrorResponse from "@server/types/ErrorResponse";
import { db } from "@server/db";
import { users } from "@server/db/schema";
import { users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { userOrgs } from "@server/db/schema";
import { userOrgs } from "@server/db/schemas";
import { and, eq, or } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { db } from "@server/db";
import { userOrgs } from "@server/db/schema";
import { userOrgs } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
@ -55,7 +55,7 @@ export async function verifyUserIsOrgOwner(
)
);
}
return next();
} catch (e) {
return next(

View file

@ -5,7 +5,7 @@ import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { resourceAccessToken } from "@server/db/schema";
import { resourceAccessToken } from "@server/db/schemas";
import { and, eq } from "drizzle-orm";
import db from "@server/db";

View file

@ -9,7 +9,7 @@ import {
ResourceAccessToken,
resourceAccessToken,
resources
} from "@server/db/schema";
} from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";
@ -20,6 +20,8 @@ import { fromError } from "zod-validation-error";
import logger from "@server/logger";
import { createDate, TimeSpan } from "oslo";
import { hashPassword } from "@server/auth/password";
import { encodeHexLowerCase } from "@oslojs/encoding";
import { sha256 } from "@oslojs/crypto/sha2";
export const generateAccessTokenBodySchema = z
.object({
@ -90,11 +92,13 @@ export async function generateAccessToken(
? createDate(new TimeSpan(validForSeconds, "s")).getTime()
: undefined;
const token = generateIdFromEntropySize(25);
const token = generateIdFromEntropySize(16);
const tokenHash = await hashPassword(token);
const tokenHash = encodeHexLowerCase(
sha256(new TextEncoder().encode(token))
);
const id = generateId(15);
const id = generateId(8);
const [result] = await db
.insert(resourceAccessToken)
.values({

View file

@ -7,13 +7,14 @@ import {
roleResources,
resourceAccessToken,
sites
} from "@server/db/schema";
} from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { sql, eq, or, inArray, and, count, isNull, lt, gt } from "drizzle-orm";
import logger from "@server/logger";
import stoi from "@server/lib/stoi";
import { fromZodError } from "zod-validation-error";
const listAccessTokensParamsSchema = z
.object({
@ -133,7 +134,7 @@ export async function listAccessTokens(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedQuery.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedQuery.error)
)
);
}
@ -144,7 +145,7 @@ export async function listAccessTokens(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedParams.error)
)
);
}

View file

@ -4,7 +4,7 @@ import HttpCode from "@server/types/HttpCode";
import { fromError } from "zod-validation-error";
import { z } from "zod";
import { db } from "@server/db";
import { User, users } from "@server/db/schema";
import { User, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { response } from "@server/lib";
import {

View file

@ -4,7 +4,7 @@ import HttpCode from "@server/types/HttpCode";
import { fromError } from "zod-validation-error";
import { z } from "zod";
import { db } from "@server/db";
import { User, users } from "@server/db/schema";
import { User, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { response } from "@server/lib";
import { verifyPassword } from "@server/auth/password";

View file

@ -4,7 +4,7 @@ import {
serializeSessionCookie
} from "@server/auth/sessions/app";
import db from "@server/db";
import { users } from "@server/db/schema";
import { users } from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";

View file

@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from "express";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
import { response } from "@server/lib";
import { User } from "@server/db/schema";
import { User } from "@server/db/schemas";
import { sendEmailVerificationCode } from "../../auth/sendEmailVerificationCode";
import config from "@server/lib/config";
import logger from "@server/logger";

View file

@ -5,7 +5,7 @@ import { fromError } from "zod-validation-error";
import HttpCode from "@server/types/HttpCode";
import { response } from "@server/lib";
import { db } from "@server/db";
import { passwordResetTokens, users } from "@server/db/schema";
import { passwordResetTokens, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { alphabet, generateRandomString, sha256 } from "oslo/crypto";
import { createDate } from "oslo";

View file

@ -6,7 +6,7 @@ import { encodeHex } from "oslo/encoding";
import HttpCode from "@server/types/HttpCode";
import { response } from "@server/lib";
import { db } from "@server/db";
import { User, users } from "@server/db/schema";
import { User, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { createTOTPKeyURI } from "oslo/otp";
import logger from "@server/logger";

View file

@ -6,7 +6,7 @@ import { fromError } from "zod-validation-error";
import HttpCode from "@server/types/HttpCode";
import { response } from "@server/lib";
import { db } from "@server/db";
import { passwordResetTokens, users } from "@server/db/schema";
import { passwordResetTokens, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { hashPassword, verifyPassword } from "@server/auth/password";
import { verifyTotpCode } from "@server/auth/totp";

View file

@ -2,7 +2,7 @@ import { NextFunction, Request, Response } from "express";
import db from "@server/db";
import HttpCode from "@server/types/HttpCode";
import { z } from "zod";
import { users } from "@server/db/schema";
import { users } from "@server/db/schemas";
import { fromError } from "zod-validation-error";
import createHttpError from "http-errors";
import response from "@server/lib/response";

View file

@ -5,7 +5,7 @@ import { fromError } from "zod-validation-error";
import HttpCode from "@server/types/HttpCode";
import { response } from "@server/lib";
import { db } from "@server/db";
import { User, emailVerificationCodes, users } from "@server/db/schema";
import { User, emailVerificationCodes, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { isWithinExpirationDate } from "oslo";
import config from "@server/lib/config";

View file

@ -5,7 +5,7 @@ import { fromError } from "zod-validation-error";
import HttpCode from "@server/types/HttpCode";
import { response } from "@server/lib";
import { db } from "@server/db";
import { twoFactorBackupCodes, User, users } from "@server/db/schema";
import { twoFactorBackupCodes, User, users } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { alphabet, generateRandomString } from "oslo/crypto";
import { hashPassword } from "@server/auth/password";

View file

@ -4,7 +4,7 @@ import createHttpError from "http-errors";
import { z } from "zod";
import { fromError } from "zod-validation-error";
import logger from "@server/logger";
import { resourceAccessToken, resources, sessions } from "@server/db/schema";
import { resourceAccessToken, resources, sessions } from "@server/db/schemas";
import db from "@server/db";
import { eq } from "drizzle-orm";
import {

View file

@ -21,7 +21,7 @@ import {
userOrgs,
userResources,
users
} from "@server/db/schema";
} from "@server/db/schemas";
import config from "@server/lib/config";
import { isIpInCidr } from "@server/lib/ip";
import { response } from "@server/lib/response";
@ -41,12 +41,13 @@ const cache = new NodeCache({
const verifyResourceSessionSchema = z.object({
sessions: z.record(z.string()).optional(),
headers: z.record(z.string()).optional(),
query: z.record(z.string()).optional(),
originalRequestURL: z.string().url(),
scheme: z.string(),
host: z.string(),
path: z.string(),
method: z.string(),
accessToken: z.string().optional(),
tls: z.boolean(),
requestIp: z.string().optional()
});
@ -85,7 +86,8 @@ export async function verifyResourceSession(
originalRequestURL,
requestIp,
path,
accessToken: token
headers,
query
} = parsedBody.data;
const clientIp = requestIp?.split(":")[0];
@ -183,12 +185,33 @@ export async function verifyResourceSession(
resource.resourceId
)}?redirect=${encodeURIComponent(originalRequestURL)}`;
// check for access token
let validAccessToken: ResourceAccessToken | undefined;
if (token) {
const [accessTokenId, accessToken] = token.split(".");
// check for access token in headers
if (
headers &&
headers[
config.getRawConfig().server.resource_access_token_headers.id
] &&
headers[
config.getRawConfig().server.resource_access_token_headers.token
]
) {
const accessTokenId =
headers[
config.getRawConfig().server.resource_access_token_headers
.id
];
const accessToken =
headers[
config.getRawConfig().server.resource_access_token_headers
.token
];
const { valid, error, tokenItem } = await verifyResourceAccessToken(
{ resource, accessTokenId, accessToken }
{
accessToken,
accessTokenId,
resourceId: resource.resourceId
}
);
if (error) {
@ -206,16 +229,44 @@ export async function verifyResourceSession(
}
if (valid && tokenItem) {
validAccessToken = tokenItem;
return allowed(res);
}
}
if (!sessions) {
return await createAccessTokenSession(
res,
resource,
tokenItem
if (
query &&
query[config.getRawConfig().server.resource_access_token_param]
) {
const token =
query[config.getRawConfig().server.resource_access_token_param];
const [accessTokenId, accessToken] = token.split(".");
const { valid, error, tokenItem } = await verifyResourceAccessToken(
{
accessToken,
accessTokenId,
resourceId: resource.resourceId
}
);
if (error) {
logger.debug("Access token invalid: " + error);
}
if (!valid) {
if (config.getRawConfig().app.log_failed_attempts) {
logger.info(
`Resource access token is invalid. Resource ID: ${
resource.resourceId
}. IP: ${clientIp}.`
);
}
}
if (valid && tokenItem) {
return allowed(res);
}
}
if (!sessions) {
@ -321,16 +372,6 @@ export async function verifyResourceSession(
}
}
// At this point we have checked all sessions, but since the access token is
// valid, we should allow access and create a new session.
if (validAccessToken) {
return await createAccessTokenSession(
res,
resource,
validAccessToken
);
}
logger.debug("No more auth to check, resource not allowed");
if (config.getRawConfig().app.log_failed_attempts) {
@ -360,8 +401,7 @@ function extractResourceSessionToken(
ssl ? "_s" : ""
}`;
const all: { cookieName: string; token: string; priority: number }[] =
[];
const all: { cookieName: string; token: string; priority: number }[] = [];
for (const [key, value] of Object.entries(sessions)) {
const parts = key.split(".");

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { domains, orgDomains, users } from "@server/db/schema";
import { domains, orgDomains, users } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
@ -80,15 +80,15 @@ export async function listDomains(
const { orgId } = parsedParams.data;
const domains = await queryDomains(orgId.toString(), limit, offset);
const domainsList = await queryDomains(orgId.toString(), limit, offset);
const [{ count }] = await db
.select({ count: sql<number>`count(*)` })
.from(users);
.from(domains);
return response<ListDomainsResponse>(res, {
data: {
domains,
domains: domainsList,
pagination: {
total: count,
limit,

View file

@ -383,7 +383,10 @@ authenticated.get(
authenticated.get(`/org/:orgId/overview`, verifyOrgAccess, org.getOrgOverview);
authenticated.post(`/supporter-key/validate`, supporterKey.validateSupporterKey);
authenticated.post(
`/supporter-key/validate`,
supporterKey.validateSupporterKey
);
authenticated.post(`/supporter-key/hide`, supporterKey.hideSupporterKey);
unauthenticated.get("/resource/:resourceId/auth", resource.getResourceAuthInfo);
@ -470,7 +473,11 @@ authenticated.delete(
// role.removeRoleAction
// );
authenticated.put("/newt", createNewt);
// authenticated.put(
// "/newt",
// verifyUserHasAction(ActionsEnum.createNewt),
// createNewt
// );
// Auth routes
export const authRouter = Router();
@ -559,3 +566,8 @@ authRouter.post(
"/resource/:resourceId/access-token",
resource.authWithAccessToken
);
authRouter.post(
"/access-token",
resource.authWithAccessToken
);

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from 'express';
import { z } from 'zod';
import { sites, resources, targets, exitNodes } from '@server/db/schema';
import { sites, resources, targets, exitNodes } from '@server/db/schemas';
import { db } from '@server/db';
import { eq } from 'drizzle-orm';
import response from "@server/lib/response";

View file

@ -1,7 +1,7 @@
import axios from 'axios';
import logger from '@server/logger';
import db from '@server/db';
import { exitNodes } from '@server/db/schema';
import { exitNodes } from '@server/db/schemas';
import { eq } from 'drizzle-orm';
export async function addPeer(exitNodeId: number, peer: {
@ -52,4 +52,4 @@ export async function deletePeer(exitNodeId: number, publicKey: string) {
}
throw error;
}
}
}

View file

@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { DrizzleError, eq } from "drizzle-orm";
import { sites, resources, targets, exitNodes } from "@server/db/schema";
import { sites, resources, targets, exitNodes } from "@server/db/schemas";
import db from "@server/db";
import logger from "@server/logger";
import createHttpError from "http-errors";

View file

@ -3,7 +3,7 @@ import db from "@server/db";
import { hash } from "@node-rs/argon2";
import HttpCode from "@server/types/HttpCode";
import { z } from "zod";
import { newts } from "@server/db/schema";
import { newts } from "@server/db/schemas";
import createHttpError from "http-errors";
import response from "@server/lib/response";
import { SqliteError } from "better-sqlite3";

View file

@ -1,6 +1,6 @@
import { generateSessionToken } from "@server/auth/sessions/app";
import db from "@server/db";
import { newts } from "@server/db/schema";
import { newts } from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";

View file

@ -6,7 +6,7 @@ import {
sites,
Target,
targets
} from "@server/db/schema";
} from "@server/db/schemas";
import { eq, and, sql, inArray } from "drizzle-orm";
import { addPeer, deletePeer } from "../gerbil/peers";
import logger from "@server/logger";

View file

@ -1,4 +1,4 @@
import { Target } from "@server/db/schema";
import { Target } from "@server/db/schemas";
import { sendToClient } from "../ws";
export function addTargets(

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { orgs } from "@server/db/schema";
import { orgs } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -10,7 +10,7 @@ import {
roleActions,
roles,
userOrgs
} from "@server/db/schema";
} from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
@ -27,7 +27,7 @@ const createOrgSchema = z
})
.strict();
const MAX_ORGS = 5;
// const MAX_ORGS = 5;
export async function createOrg(
req: Request,
@ -57,15 +57,15 @@ export async function createOrg(
);
}
const userOrgIds = req.userOrgIds;
if (userOrgIds && userOrgIds.length > MAX_ORGS) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
`Maximum number of organizations reached.`
)
);
}
// const userOrgIds = req.userOrgIds;
// if (userOrgIds && userOrgIds.length > MAX_ORGS) {
// return next(
// createHttpError(
// HttpCode.FORBIDDEN,
// `Maximum number of organizations reached.`
// )
// );
// }
const { orgId, name } = parsedBody.data;

View file

@ -7,7 +7,7 @@ import {
orgs,
sites,
userActions
} from "@server/db/schema";
} from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,12 +1,13 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { Org, orgs } from "@server/db/schema";
import { Org, orgs } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromZodError } from "zod-validation-error";
const getOrgSchema = z
.object({
@ -29,7 +30,7 @@ export async function getOrg(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedParams.error)
)
);
}

View file

@ -10,12 +10,13 @@ import {
userResources,
users,
userSites
} from "@server/db/schema";
} from "@server/db/schemas";
import { and, count, eq, inArray } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromZodError } from "zod-validation-error";
const getOrgParamsSchema = z
.object({
@ -45,7 +46,7 @@ export async function getOrgOverview(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedParams.error)
)
);
}

View file

@ -1,12 +1,13 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { Org, orgs } from "@server/db/schema";
import { Org, orgs } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { sql, inArray } from "drizzle-orm";
import logger from "@server/logger";
import { fromZodError } from "zod-validation-error";
const listOrgsSchema = z.object({
limit: z
@ -39,7 +40,7 @@ export async function listOrgs(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedQuery.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedQuery.error)
)
);
}

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { orgs } from "@server/db/schema";
import { orgs } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,6 +1,6 @@
import { generateSessionToken } from "@server/auth/sessions/app";
import db from "@server/db";
import { resources } from "@server/db/schema";
import { Resource, resources } from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";
@ -10,13 +10,16 @@ import { z } from "zod";
import { fromError } from "zod-validation-error";
import { createResourceSession } from "@server/auth/sessions/resource";
import logger from "@server/logger";
import { verifyResourceAccessToken } from "@server/auth/verifyResourceAccessToken";
import {
verifyResourceAccessToken
} from "@server/auth/verifyResourceAccessToken";
import config from "@server/lib/config";
import stoi from "@server/lib/stoi";
const authWithAccessTokenBodySchema = z
.object({
accessToken: z.string(),
accessTokenId: z.string()
accessTokenId: z.string().optional()
})
.strict();
@ -24,13 +27,15 @@ const authWithAccessTokenParamsSchema = z
.object({
resourceId: z
.string()
.transform(Number)
.pipe(z.number().int().positive())
.optional()
.transform(stoi)
.pipe(z.number().int().positive().optional())
})
.strict();
export type AuthWithAccessTokenResponse = {
session?: string;
redirectUrl?: string | null;
};
export async function authWithAccessToken(
@ -64,23 +69,61 @@ export async function authWithAccessToken(
const { accessToken, accessTokenId } = parsedBody.data;
try {
const [resource] = await db
.select()
.from(resources)
.where(eq(resources.resourceId, resourceId))
.limit(1);
let valid;
let tokenItem;
let error;
let resource: Resource | undefined;
if (!resource) {
return next(
createHttpError(HttpCode.NOT_FOUND, "Resource not found")
);
if (accessTokenId) {
if (!resourceId) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"Resource ID is required"
)
);
}
const [foundResource] = await db
.select()
.from(resources)
.where(eq(resources.resourceId, resourceId))
.limit(1);
if (!foundResource) {
return next(
createHttpError(HttpCode.NOT_FOUND, "Resource not found")
);
}
const res = await verifyResourceAccessToken({
accessTokenId,
accessToken
});
valid = res.valid;
tokenItem = res.tokenItem;
error = res.error;
resource = foundResource;
} else {
const res = await verifyResourceAccessToken({
accessToken
});
valid = res.valid;
tokenItem = res.tokenItem;
error = res.error;
resource = res.resource;
}
const { valid, error, tokenItem } = await verifyResourceAccessToken({
resource,
accessTokenId,
accessToken
});
if (!tokenItem || !resource) {
return next(
createHttpError(
HttpCode.UNAUTHORIZED,
"Access token does not exist for resource"
)
);
}
if (!valid) {
if (config.getRawConfig().app.log_failed_attempts) {
@ -96,18 +139,9 @@ export async function authWithAccessToken(
);
}
if (!tokenItem || !resource) {
return next(
createHttpError(
HttpCode.UNAUTHORIZED,
"Access token does not exist for resource"
)
);
}
const token = generateSessionToken();
await createResourceSession({
resourceId,
resourceId: resource.resourceId,
token,
accessTokenId: tokenItem.accessTokenId,
isRequestToken: true,
@ -118,7 +152,8 @@ export async function authWithAccessToken(
return response<AuthWithAccessTokenResponse>(res, {
data: {
session: token
session: token,
redirectUrl: `${resource.ssl ? "https" : "http"}://${resource.fullDomain}`
},
success: true,
error: false,

View file

@ -1,7 +1,7 @@
import { verify } from "@node-rs/argon2";
import { generateSessionToken } from "@server/auth/sessions/app";
import db from "@server/db";
import { orgs, resourcePassword, resources } from "@server/db/schema";
import { orgs, resourcePassword, resources } from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";

View file

@ -1,6 +1,6 @@
import { generateSessionToken } from "@server/auth/sessions/app";
import db from "@server/db";
import { orgs, resourcePincode, resources } from "@server/db/schema";
import { orgs, resourcePincode, resources } from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq } from "drizzle-orm";

View file

@ -5,7 +5,7 @@ import {
resourceOtp,
resources,
resourceWhitelist
} from "@server/db/schema";
} from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq, and } from "drizzle-orm";

View file

@ -10,7 +10,7 @@ import {
roleResources,
roles,
userResources
} from "@server/db/schema";
} from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resourceRules, resources } from "@server/db/schema";
import { resourceRules, resources } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { newts, resources, sites, targets } from "@server/db/schema";
import { newts, resources, sites, targets } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resourceRules, resources } from "@server/db/schema";
import { resourceRules, resources } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
@ -68,4 +68,4 @@ export async function deleteResourceRule(
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
);
}
}
}

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resources } from "@server/db/schema";
import { resources } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import { createResourceSession } from "@server/auth/sessions/resource";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { Resource, resources, sites } from "@server/db/schema";
import { Resource, resources, sites } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -5,7 +5,7 @@ import {
resourcePassword,
resourcePincode,
resources
} from "@server/db/schema";
} from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resourceWhitelist, users } from "@server/db/schema"; // Assuming these are the correct tables
import { resourceWhitelist, users } from "@server/db/schemas"; // Assuming these are the correct tables
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { roleResources, roles } from "@server/db/schema";
import { roleResources, roles } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,5 +1,5 @@
import { db } from "@server/db";
import { resourceRules, resources } from "@server/db/schema";
import { resourceRules, resources } from "@server/db/schemas";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { eq, sql } from "drizzle-orm";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { userResources, users } from "@server/db/schema"; // Assuming these are the correct tables
import { userResources, users } from "@server/db/schemas"; // Assuming these are the correct tables
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -8,13 +8,14 @@ import {
roleResources,
resourcePassword,
resourcePincode
} from "@server/db/schema";
} from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import { sql, eq, or, inArray, and, count } from "drizzle-orm";
import logger from "@server/logger";
import stoi from "@server/lib/stoi";
import { fromZodError } from "zod-validation-error";
const listResourcesParamsSchema = z
.object({
@ -66,7 +67,8 @@ function queryResources(
whitelist: resources.emailWhitelistEnabled,
http: resources.http,
protocol: resources.protocol,
proxyPort: resources.proxyPort
proxyPort: resources.proxyPort,
enabled: resources.enabled
})
.from(resources)
.leftJoin(sites, eq(resources.siteId, sites.siteId))
@ -99,7 +101,8 @@ function queryResources(
whitelist: resources.emailWhitelistEnabled,
http: resources.http,
protocol: resources.protocol,
proxyPort: resources.proxyPort
proxyPort: resources.proxyPort,
enabled: resources.enabled
})
.from(resources)
.leftJoin(sites, eq(resources.siteId, sites.siteId))
@ -136,7 +139,7 @@ export async function listResources(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedQuery.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedQuery.error)
)
);
}
@ -147,7 +150,7 @@ export async function listResources(
return next(
createHttpError(
HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", ")
fromZodError(parsedParams.error)
)
);
}

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resourcePassword } from "@server/db/schema";
import { resourcePassword } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resourcePincode } from "@server/db/schema";
import { resourcePincode } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { roleResources, roles } from "@server/db/schema";
import { roleResources, roles } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { userResources } from "@server/db/schema";
import { userResources } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resources, resourceWhitelist } from "@server/db/schema";
import { resources, resourceWhitelist } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { newts, resources, sites, targets } from "@server/db/schema";
import { newts, resources, sites, targets } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -8,7 +8,7 @@ import {
orgs,
Resource,
resources
} from "@server/db/schema";
} from "@server/db/schemas";
import { eq, and } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
@ -39,7 +39,8 @@ const updateHttpResourceBodySchema = z
emailWhitelistEnabled: z.boolean().optional(),
isBaseDomain: z.boolean().optional(),
applyRules: z.boolean().optional(),
domainId: z.string().optional()
domainId: z.string().optional(),
enabled: z.boolean().optional()
})
.strict()
.refine((data) => Object.keys(data).length > 0, {
@ -73,7 +74,8 @@ export type UpdateResourceResponse = Resource;
const updateRawResourceBodySchema = z
.object({
name: z.string().min(1).max(255).optional(),
proxyPort: z.number().int().min(1).max(65535).optional()
proxyPort: z.number().int().min(1).max(65535).optional(),
enabled: z.boolean().optional()
})
.strict()
.refine((data) => Object.keys(data).length > 0, {

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resourceRules, resources } from "@server/db/schema";
import { resourceRules, resources } from "@server/db/schemas";
import { eq } from "drizzle-orm";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { roleActions, roles } from "@server/db/schema";
import { roleActions, roles } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { resources, roleResources, roleSites } from "@server/db/schema";
import { resources, roleResources, roleSites } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

View file

@ -1,7 +1,7 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db";
import { orgs, Role, roleActions, roles } from "@server/db/schema";
import { orgs, Role, roleActions, roles } from "@server/db/schemas";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";

Some files were not shown because too many files have changed in this diff Show more