mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-21 12:26:40 +00:00
fix issues from test deploy
This commit is contained in:
@@ -17,13 +17,21 @@ import logger from "@server/logger";
|
||||
import { verify } from "@node-rs/argon2";
|
||||
import { isWithinExpirationDate } from "oslo";
|
||||
|
||||
const authWithAccessTokenBodySchema = z.object({
|
||||
accessToken: z.string()
|
||||
});
|
||||
const authWithAccessTokenBodySchema = z
|
||||
.object({
|
||||
accessToken: z.string(),
|
||||
accessTokenId: z.string()
|
||||
})
|
||||
.strict();
|
||||
|
||||
const authWithAccessTokenParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
const authWithAccessTokenParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type AuthWithAccessTokenResponse = {
|
||||
session?: string;
|
||||
@@ -57,9 +65,7 @@ export async function authWithAccessToken(
|
||||
}
|
||||
|
||||
const { resourceId } = parsedParams.data;
|
||||
const { accessToken: at } = parsedBody.data;
|
||||
|
||||
const [accessTokenId, accessToken] = at.split(".");
|
||||
const { accessToken, accessTokenId } = parsedBody.data;
|
||||
|
||||
try {
|
||||
const [result] = await db
|
||||
@@ -86,7 +92,7 @@ export async function authWithAccessToken(
|
||||
HttpCode.UNAUTHORIZED,
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Email is not whitelisted"
|
||||
"Access token does not exist for resource"
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -98,15 +104,12 @@ export async function authWithAccessToken(
|
||||
);
|
||||
}
|
||||
|
||||
// const validCode = await verify(tokenItem.tokenHash, accessToken, {
|
||||
// memoryCost: 19456,
|
||||
// timeCost: 2,
|
||||
// outputLen: 32,
|
||||
// parallelism: 1
|
||||
// });
|
||||
logger.debug(`${accessToken} ${tokenItem.tokenHash}`)
|
||||
const validCode = accessToken === tokenItem.tokenHash;
|
||||
|
||||
const validCode = await verify(tokenItem.tokenHash, accessToken, {
|
||||
memoryCost: 19456,
|
||||
timeCost: 2,
|
||||
outputLen: 32,
|
||||
parallelism: 1
|
||||
});
|
||||
if (!validCode) {
|
||||
return next(
|
||||
createHttpError(HttpCode.UNAUTHORIZED, "Invalid access token")
|
||||
|
||||
@@ -14,14 +14,22 @@ import {
|
||||
serializeResourceSessionCookie
|
||||
} from "@server/auth/resource";
|
||||
import config from "@server/config";
|
||||
import logger from "@server/logger";
|
||||
|
||||
export const authWithPasswordBodySchema = z.object({
|
||||
password: z.string()
|
||||
});
|
||||
export const authWithPasswordBodySchema = z
|
||||
.object({
|
||||
password: z.string()
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const authWithPasswordParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
export const authWithPasswordParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type AuthWithPasswordResponse = {
|
||||
session?: string;
|
||||
@@ -120,10 +128,7 @@ export async function authWithPassword(
|
||||
passwordId: definedPassword.passwordId
|
||||
});
|
||||
const cookieName = `${config.server.resource_session_cookie_name}_${resource.resourceId}`;
|
||||
const cookie = serializeResourceSessionCookie(
|
||||
cookieName,
|
||||
token,
|
||||
);
|
||||
const cookie = serializeResourceSessionCookie(cookieName, token);
|
||||
res.appendHeader("Set-Cookie", cookie);
|
||||
|
||||
return response<AuthWithPasswordResponse>(res, {
|
||||
@@ -136,6 +141,7 @@ export async function authWithPassword(
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
|
||||
@@ -24,13 +24,20 @@ import config from "@server/config";
|
||||
import { AuthWithPasswordResponse } from "./authWithPassword";
|
||||
import { isValidOtp, sendResourceOtpEmail } from "@server/auth/resourceOtp";
|
||||
|
||||
export const authWithPincodeBodySchema = z.object({
|
||||
pincode: z.string()
|
||||
});
|
||||
export const authWithPincodeBodySchema = z
|
||||
.object({
|
||||
pincode: z.string()
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const authWithPincodeParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
export const authWithPincodeParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type AuthWithPincodeResponse = {
|
||||
session?: string;
|
||||
@@ -128,10 +135,7 @@ export async function authWithPincode(
|
||||
pincodeId: definedPincode.pincodeId
|
||||
});
|
||||
const cookieName = `${config.server.resource_session_cookie_name}_${resource.resourceId}`;
|
||||
const cookie = serializeResourceSessionCookie(
|
||||
cookieName,
|
||||
token,
|
||||
);
|
||||
const cookie = serializeResourceSessionCookie(cookieName, token);
|
||||
res.appendHeader("Set-Cookie", cookie);
|
||||
|
||||
return response<AuthWithPincodeResponse>(res, {
|
||||
|
||||
@@ -22,14 +22,21 @@ import config from "@server/config";
|
||||
import { isValidOtp, sendResourceOtpEmail } from "@server/auth/resourceOtp";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const authWithWhitelistBodySchema = z.object({
|
||||
email: z.string().email(),
|
||||
otp: z.string().optional()
|
||||
});
|
||||
const authWithWhitelistBodySchema = z
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
otp: z.string().optional()
|
||||
})
|
||||
.strict();
|
||||
|
||||
const authWithWhitelistParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
const authWithWhitelistParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type AuthWithWhitelistResponse = {
|
||||
otpSent?: boolean;
|
||||
@@ -171,10 +178,7 @@ export async function authWithWhitelist(
|
||||
whitelistId: whitelistedEmail.whitelistId
|
||||
});
|
||||
const cookieName = `${config.server.resource_session_cookie_name}_${resource.resourceId}`;
|
||||
const cookie = serializeResourceSessionCookie(
|
||||
cookieName,
|
||||
token,
|
||||
);
|
||||
const cookie = serializeResourceSessionCookie(cookieName, token);
|
||||
res.appendHeader("Set-Cookie", cookie);
|
||||
|
||||
return response<AuthWithWhitelistResponse>(res, {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SqliteError } from "better-sqlite3";
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { db } from "@server/db";
|
||||
@@ -7,7 +8,7 @@ import {
|
||||
resources,
|
||||
roleResources,
|
||||
roles,
|
||||
userResources,
|
||||
userResources
|
||||
} from "@server/db/schema";
|
||||
import response from "@server/utils/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
@@ -16,16 +17,19 @@ import { eq, and } from "drizzle-orm";
|
||||
import stoi from "@server/utils/stoi";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { subdomainSchema } from "@server/schemas/subdomainSchema";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const createResourceParamsSchema = z.object({
|
||||
siteId: z.string().transform(stoi).pipe(z.number().int().positive()),
|
||||
orgId: z.string(),
|
||||
});
|
||||
const createResourceParamsSchema = z
|
||||
.object({
|
||||
siteId: z.string().transform(stoi).pipe(z.number().int().positive()),
|
||||
orgId: z.string()
|
||||
})
|
||||
.strict();
|
||||
|
||||
const createResourceSchema = z
|
||||
.object({
|
||||
name: z.string().min(1).max(255),
|
||||
subdomain: subdomainSchema,
|
||||
subdomain: subdomainSchema
|
||||
})
|
||||
.strict();
|
||||
|
||||
@@ -94,7 +98,7 @@ export async function createResource(
|
||||
orgId,
|
||||
name,
|
||||
subdomain,
|
||||
ssl: true,
|
||||
ssl: true
|
||||
})
|
||||
.returning();
|
||||
|
||||
@@ -112,14 +116,14 @@ export async function createResource(
|
||||
|
||||
await db.insert(roleResources).values({
|
||||
roleId: adminRole[0].roleId,
|
||||
resourceId: newResource[0].resourceId,
|
||||
resourceId: newResource[0].resourceId
|
||||
});
|
||||
|
||||
if (req.userOrgRoleId != adminRole[0].roleId) {
|
||||
// make sure the user can access the resource
|
||||
await db.insert(userResources).values({
|
||||
userId: req.user?.userId!,
|
||||
resourceId: newResource[0].resourceId,
|
||||
resourceId: newResource[0].resourceId
|
||||
});
|
||||
}
|
||||
|
||||
@@ -128,9 +132,22 @@ export async function createResource(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource created successfully",
|
||||
status: HttpCode.CREATED,
|
||||
status: HttpCode.CREATED
|
||||
});
|
||||
} catch (error) {
|
||||
if (
|
||||
error instanceof SqliteError &&
|
||||
error.code === "SQLITE_CONSTRAINT_UNIQUE"
|
||||
) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.CONFLICT,
|
||||
"Resource with that subdomain already exists"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
|
||||
@@ -12,9 +12,14 @@ import { addPeer } from "../gerbil/peers";
|
||||
import { removeTargets } from "../newt/targets";
|
||||
|
||||
// Define Zod schema for request parameters validation
|
||||
const deleteResourceSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const deleteResourceSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export async function deleteResource(
|
||||
req: Request,
|
||||
@@ -67,20 +72,20 @@ export async function deleteResource(
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (site.pubKey) {
|
||||
if (site.type == "wireguard") {
|
||||
// TODO: is this all inefficient?
|
||||
// Fetch resources for this site
|
||||
const resourcesRes = await db.query.resources.findMany({
|
||||
where: eq(resources.siteId, site.siteId),
|
||||
where: eq(resources.siteId, site.siteId)
|
||||
});
|
||||
|
||||
// Fetch targets for all resources of this site
|
||||
const targetIps = await Promise.all(
|
||||
resourcesRes.map(async (resource) => {
|
||||
const targetsRes = await db.query.targets.findMany({
|
||||
where: eq(targets.resourceId, resource.resourceId),
|
||||
where: eq(targets.resourceId, resource.resourceId)
|
||||
});
|
||||
return targetsRes.map((target) => `${target.ip}/32`);
|
||||
})
|
||||
@@ -88,7 +93,7 @@ export async function deleteResource(
|
||||
|
||||
await addPeer(site.exitNodeId!, {
|
||||
publicKey: site.pubKey,
|
||||
allowedIps: targetIps.flat(),
|
||||
allowedIps: targetIps.flat()
|
||||
});
|
||||
} else if (site.type == "newt") {
|
||||
// get the newt on the site by querying the newt table for siteId
|
||||
@@ -107,7 +112,7 @@ export async function deleteResource(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource deleted successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
|
||||
@@ -7,10 +7,16 @@ import response from "@server/utils/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const getResourceSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const getResourceSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type GetResourceResponse = Resource;
|
||||
|
||||
@@ -52,9 +58,10 @@ export async function getResource(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource retrieved successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
|
||||
@@ -4,17 +4,23 @@ import { db } from "@server/db";
|
||||
import {
|
||||
resourcePassword,
|
||||
resourcePincode,
|
||||
resources,
|
||||
resources
|
||||
} from "@server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import response from "@server/utils/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const getResourceAuthInfoSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const getResourceAuthInfoSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export type GetResourceAuthInfoResponse = {
|
||||
resourceId: number;
|
||||
@@ -30,7 +36,7 @@ export type GetResourceAuthInfoResponse = {
|
||||
export async function getResourceAuthInfo(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
try {
|
||||
const parsedParams = getResourceAuthInfoSchema.safeParse(req.params);
|
||||
@@ -38,8 +44,8 @@ export async function getResourceAuthInfo(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
fromError(parsedParams.error).toString(),
|
||||
),
|
||||
fromError(parsedParams.error).toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -50,11 +56,11 @@ export async function getResourceAuthInfo(
|
||||
.from(resources)
|
||||
.leftJoin(
|
||||
resourcePincode,
|
||||
eq(resourcePincode.resourceId, resources.resourceId),
|
||||
eq(resourcePincode.resourceId, resources.resourceId)
|
||||
)
|
||||
.leftJoin(
|
||||
resourcePassword,
|
||||
eq(resourcePassword.resourceId, resources.resourceId),
|
||||
eq(resourcePassword.resourceId, resources.resourceId)
|
||||
)
|
||||
.where(eq(resources.resourceId, resourceId))
|
||||
.limit(1);
|
||||
@@ -67,7 +73,7 @@ export async function getResourceAuthInfo(
|
||||
|
||||
if (!resource) {
|
||||
return next(
|
||||
createHttpError(HttpCode.NOT_FOUND, "Resource not found"),
|
||||
createHttpError(HttpCode.NOT_FOUND, "Resource not found")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,14 +91,12 @@ export async function getResourceAuthInfo(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource auth info retrieved successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"An error occurred",
|
||||
),
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,14 @@ import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
|
||||
const getResourceWhitelistSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
const getResourceWhitelistSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
async function queryWhitelist(resourceId: number) {
|
||||
return await db
|
||||
|
||||
@@ -9,9 +9,14 @@ import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
|
||||
const listResourceRolesSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const listResourceRolesSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
async function query(resourceId: number) {
|
||||
return await db
|
||||
@@ -19,7 +24,7 @@ async function query(resourceId: number) {
|
||||
roleId: roles.roleId,
|
||||
name: roles.name,
|
||||
description: roles.description,
|
||||
isAdmin: roles.isAdmin,
|
||||
isAdmin: roles.isAdmin
|
||||
})
|
||||
.from(roleResources)
|
||||
.innerJoin(roles, eq(roleResources.roleId, roles.roleId))
|
||||
@@ -52,12 +57,12 @@ export async function listResourceRoles(
|
||||
|
||||
return response<ListResourceRolesResponse>(res, {
|
||||
data: {
|
||||
roles: resourceRolesList,
|
||||
roles: resourceRolesList
|
||||
},
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource roles retrieved successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
|
||||
@@ -9,15 +9,20 @@ import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
|
||||
const listResourceUsersSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const listResourceUsersSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
async function queryUsers(resourceId: number) {
|
||||
return await db
|
||||
.select({
|
||||
userId: userResources.userId,
|
||||
email: users.email,
|
||||
email: users.email
|
||||
})
|
||||
.from(userResources)
|
||||
.innerJoin(users, eq(userResources.userId, users.userId))
|
||||
@@ -50,12 +55,12 @@ export async function listResourceUsers(
|
||||
|
||||
return response<ListResourceUsersResponse>(res, {
|
||||
data: {
|
||||
users: resourceUsersList,
|
||||
users: resourceUsersList
|
||||
},
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource users retrieved successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
userResources,
|
||||
roleResources,
|
||||
resourcePassword,
|
||||
resourcePincode,
|
||||
resourcePincode
|
||||
} from "@server/db/schema";
|
||||
import response from "@server/utils/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
@@ -23,10 +23,11 @@ const listResourcesParamsSchema = z
|
||||
.optional()
|
||||
.transform(stoi)
|
||||
.pipe(z.number().int().positive().optional()),
|
||||
orgId: z.string().optional(),
|
||||
orgId: z.string().optional()
|
||||
})
|
||||
.strict()
|
||||
.refine((data) => !!data.siteId !== !!data.orgId, {
|
||||
message: "Either siteId or orgId must be provided, but not both",
|
||||
message: "Either siteId or orgId must be provided, but not both"
|
||||
});
|
||||
|
||||
const listResourcesSchema = z.object({
|
||||
@@ -42,13 +43,13 @@ const listResourcesSchema = z.object({
|
||||
.optional()
|
||||
.default("0")
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().nonnegative()),
|
||||
.pipe(z.number().int().nonnegative())
|
||||
});
|
||||
|
||||
function queryResources(
|
||||
accessibleResourceIds: number[],
|
||||
siteId?: number,
|
||||
orgId?: string,
|
||||
orgId?: string
|
||||
) {
|
||||
if (siteId) {
|
||||
return db
|
||||
@@ -68,17 +69,17 @@ function queryResources(
|
||||
.leftJoin(sites, eq(resources.siteId, sites.siteId))
|
||||
.leftJoin(
|
||||
resourcePassword,
|
||||
eq(resourcePassword.resourceId, resources.resourceId),
|
||||
eq(resourcePassword.resourceId, resources.resourceId)
|
||||
)
|
||||
.leftJoin(
|
||||
resourcePincode,
|
||||
eq(resourcePincode.resourceId, resources.resourceId),
|
||||
eq(resourcePincode.resourceId, resources.resourceId)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
inArray(resources.resourceId, accessibleResourceIds),
|
||||
eq(resources.siteId, siteId),
|
||||
),
|
||||
eq(resources.siteId, siteId)
|
||||
)
|
||||
);
|
||||
} else if (orgId) {
|
||||
return db
|
||||
@@ -98,17 +99,17 @@ function queryResources(
|
||||
.leftJoin(sites, eq(resources.siteId, sites.siteId))
|
||||
.leftJoin(
|
||||
resourcePassword,
|
||||
eq(resourcePassword.resourceId, resources.resourceId),
|
||||
eq(resourcePassword.resourceId, resources.resourceId)
|
||||
)
|
||||
.leftJoin(
|
||||
resourcePincode,
|
||||
eq(resourcePincode.resourceId, resources.resourceId),
|
||||
eq(resourcePincode.resourceId, resources.resourceId)
|
||||
)
|
||||
.where(
|
||||
and(
|
||||
inArray(resources.resourceId, accessibleResourceIds),
|
||||
eq(resources.orgId, orgId),
|
||||
),
|
||||
eq(resources.orgId, orgId)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +122,7 @@ export type ListResourcesResponse = {
|
||||
export async function listResources(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
try {
|
||||
const parsedQuery = listResourcesSchema.safeParse(req.query);
|
||||
@@ -129,8 +130,8 @@ export async function listResources(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
parsedQuery.error.errors.map((e) => e.message).join(", "),
|
||||
),
|
||||
parsedQuery.error.errors.map((e) => e.message).join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
const { limit, offset } = parsedQuery.data;
|
||||
@@ -140,8 +141,8 @@ export async function listResources(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
parsedParams.error.errors.map((e) => e.message).join(", "),
|
||||
),
|
||||
parsedParams.error.errors.map((e) => e.message).join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
const { siteId, orgId } = parsedParams.data;
|
||||
@@ -150,29 +151,29 @@ export async function listResources(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.FORBIDDEN,
|
||||
"User does not have access to this organization",
|
||||
),
|
||||
"User does not have access to this organization"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const accessibleResources = await db
|
||||
.select({
|
||||
resourceId: sql<number>`COALESCE(${userResources.resourceId}, ${roleResources.resourceId})`,
|
||||
resourceId: sql<number>`COALESCE(${userResources.resourceId}, ${roleResources.resourceId})`
|
||||
})
|
||||
.from(userResources)
|
||||
.fullJoin(
|
||||
roleResources,
|
||||
eq(userResources.resourceId, roleResources.resourceId),
|
||||
eq(userResources.resourceId, roleResources.resourceId)
|
||||
)
|
||||
.where(
|
||||
or(
|
||||
eq(userResources.userId, req.user!.userId),
|
||||
eq(roleResources.roleId, req.userOrgRoleId!),
|
||||
),
|
||||
eq(roleResources.roleId, req.userOrgRoleId!)
|
||||
)
|
||||
);
|
||||
|
||||
const accessibleResourceIds = accessibleResources.map(
|
||||
(resource) => resource.resourceId,
|
||||
(resource) => resource.resourceId
|
||||
);
|
||||
|
||||
let countQuery: any = db
|
||||
@@ -192,21 +193,18 @@ export async function listResources(
|
||||
pagination: {
|
||||
total: totalCount,
|
||||
limit,
|
||||
offset,
|
||||
},
|
||||
offset
|
||||
}
|
||||
},
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resources retrieved successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"An error occurred",
|
||||
),
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,14 +8,15 @@ import createHttpError from "http-errors";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { hash } from "@node-rs/argon2";
|
||||
import { response } from "@server/utils";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const setResourceAuthMethodsParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
|
||||
const setResourceAuthMethodsBodySchema = z
|
||||
.object({
|
||||
password: z.string().min(4).max(100).nullable(),
|
||||
password: z.string().min(4).max(100).nullable()
|
||||
})
|
||||
.strict();
|
||||
|
||||
@@ -60,7 +61,7 @@ export async function setResourcePassword(
|
||||
memoryCost: 19456,
|
||||
timeCost: 2,
|
||||
outputLen: 32,
|
||||
parallelism: 1,
|
||||
parallelism: 1
|
||||
});
|
||||
|
||||
await trx
|
||||
@@ -74,9 +75,10 @@ export async function setResourcePassword(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource password set successfully",
|
||||
status: HttpCode.CREATED,
|
||||
status: HttpCode.CREATED
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { fromError } from "zod-validation-error";
|
||||
import { hash } from "@node-rs/argon2";
|
||||
import { response } from "@server/utils";
|
||||
import stoi from "@server/utils/stoi";
|
||||
import logger from "@server/logger";
|
||||
|
||||
const setResourceAuthMethodsParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
@@ -81,6 +82,7 @@ export async function setResourcePincode(
|
||||
status: HttpCode.CREATED,
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
|
||||
@@ -9,13 +9,20 @@ import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { eq, and, ne } from "drizzle-orm";
|
||||
|
||||
const setResourceRolesBodySchema = z.object({
|
||||
roleIds: z.array(z.number().int().positive()),
|
||||
});
|
||||
const setResourceRolesBodySchema = z
|
||||
.object({
|
||||
roleIds: z.array(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
const setResourceRolesParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const setResourceRolesParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export async function setResourceRoles(
|
||||
req: Request,
|
||||
@@ -99,7 +106,7 @@ export async function setResourceRoles(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Roles set for resource successfully",
|
||||
status: HttpCode.CREATED,
|
||||
status: HttpCode.CREATED
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -9,13 +9,20 @@ import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
const setUserResourcesBodySchema = z.object({
|
||||
userIds: z.array(z.string()),
|
||||
});
|
||||
const setUserResourcesBodySchema = z
|
||||
.object({
|
||||
userIds: z.array(z.string())
|
||||
})
|
||||
.strict();
|
||||
|
||||
const setUserResourcesParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const setUserResourcesParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export async function setResourceUsers(
|
||||
req: Request,
|
||||
@@ -66,7 +73,7 @@ export async function setResourceUsers(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Users set for resource successfully",
|
||||
status: HttpCode.CREATED,
|
||||
status: HttpCode.CREATED
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -9,13 +9,20 @@ import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
|
||||
const setResourceWhitelistBodySchema = z.object({
|
||||
emails: z.array(z.string().email()).max(50)
|
||||
});
|
||||
const setResourceWhitelistBodySchema = z
|
||||
.object({
|
||||
emails: z.array(z.string().email()).max(50)
|
||||
})
|
||||
.strict();
|
||||
|
||||
const setResourceWhitelistParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||
});
|
||||
const setResourceWhitelistParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
export async function setResourceWhitelist(
|
||||
req: Request,
|
||||
|
||||
@@ -10,9 +10,14 @@ import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { subdomainSchema } from "@server/schemas/subdomainSchema";
|
||||
|
||||
const updateResourceParamsSchema = z.object({
|
||||
resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
});
|
||||
const updateResourceParamsSchema = z
|
||||
.object({
|
||||
resourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive())
|
||||
})
|
||||
.strict();
|
||||
|
||||
const updateResourceBodySchema = z
|
||||
.object({
|
||||
@@ -21,18 +26,18 @@ const updateResourceBodySchema = z
|
||||
ssl: z.boolean().optional(),
|
||||
sso: z.boolean().optional(),
|
||||
blockAccess: z.boolean().optional(),
|
||||
emailWhitelistEnabled: z.boolean().optional(),
|
||||
emailWhitelistEnabled: z.boolean().optional()
|
||||
// siteId: z.number(),
|
||||
})
|
||||
.strict()
|
||||
.refine((data) => Object.keys(data).length > 0, {
|
||||
message: "At least one field must be provided for update",
|
||||
message: "At least one field must be provided for update"
|
||||
});
|
||||
|
||||
export async function updateResource(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
try {
|
||||
const parsedParams = updateResourceParamsSchema.safeParse(req.params);
|
||||
@@ -40,8 +45,8 @@ export async function updateResource(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
fromError(parsedParams.error).toString(),
|
||||
),
|
||||
fromError(parsedParams.error).toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -50,8 +55,8 @@ export async function updateResource(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
fromError(parsedBody.error).toString(),
|
||||
),
|
||||
fromError(parsedBody.error).toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,8 +73,8 @@ export async function updateResource(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`Resource with ID ${resourceId} not found`,
|
||||
),
|
||||
`Resource with ID ${resourceId} not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -77,8 +82,8 @@ export async function updateResource(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Resource does not have a domain",
|
||||
),
|
||||
"Resource does not have a domain"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -88,7 +93,7 @@ export async function updateResource(
|
||||
|
||||
const updatePayload = {
|
||||
...updateData,
|
||||
...(fullDomain && { fullDomain }),
|
||||
...(fullDomain && { fullDomain })
|
||||
};
|
||||
|
||||
const updatedResource = await db
|
||||
@@ -101,8 +106,8 @@ export async function updateResource(
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
`Resource with ID ${resourceId} not found`,
|
||||
),
|
||||
`Resource with ID ${resourceId} not found`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,15 +116,12 @@ export async function updateResource(
|
||||
success: true,
|
||||
error: false,
|
||||
message: "Resource updated successfully",
|
||||
status: HttpCode.OK,
|
||||
status: HttpCode.OK
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"An error occurred",
|
||||
),
|
||||
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user