310 lines
9.3 KiB
TypeScript
310 lines
9.3 KiB
TypeScript
import { db, RoleResource, UserOrg } from "@server/db";
|
|
import {
|
|
Resource,
|
|
ResourcePassword,
|
|
ResourcePincode,
|
|
ResourceRule,
|
|
resourcePassword,
|
|
resourcePincode,
|
|
resourceRules,
|
|
resources,
|
|
roleResources,
|
|
sessions,
|
|
userOrgs,
|
|
userResources,
|
|
users
|
|
} from "@server/db";
|
|
import { and, eq, inArray } from "drizzle-orm";
|
|
import axios from "axios";
|
|
import config from "@server/lib/config";
|
|
import logger from "@server/logger";
|
|
import { tokenManager } from "@server/lib/tokenManager";
|
|
|
|
export type ResourceWithAuth = {
|
|
resource: Resource | null;
|
|
pincode: ResourcePincode | null;
|
|
password: ResourcePassword | null;
|
|
};
|
|
|
|
export type UserSessionWithUser = {
|
|
session: any;
|
|
user: any;
|
|
};
|
|
|
|
/**
|
|
* Get resource by domain with pincode and password information
|
|
*/
|
|
export async function getResourceByDomain(
|
|
domain: string
|
|
): Promise<ResourceWithAuth | null> {
|
|
if (config.isManagedMode()) {
|
|
try {
|
|
const response = await axios.get(
|
|
`${config.getRawConfig().managed?.endpoint}/api/v1/hybrid/resource/domain/${domain}`,
|
|
await tokenManager.getAuthHeader()
|
|
);
|
|
return response.data.data;
|
|
} catch (error) {
|
|
if (axios.isAxiosError(error)) {
|
|
logger.error("Error fetching config in verify session:", {
|
|
message: error.message,
|
|
code: error.code,
|
|
status: error.response?.status,
|
|
statusText: error.response?.statusText,
|
|
url: error.config?.url,
|
|
method: error.config?.method
|
|
});
|
|
} else {
|
|
logger.error("Error fetching config in verify session:", error);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const [result] = await db
|
|
.select()
|
|
.from(resources)
|
|
.leftJoin(
|
|
resourcePincode,
|
|
eq(resourcePincode.resourceId, resources.resourceId)
|
|
)
|
|
.leftJoin(
|
|
resourcePassword,
|
|
eq(resourcePassword.resourceId, resources.resourceId)
|
|
)
|
|
.where(eq(resources.fullDomain, domain))
|
|
.limit(1);
|
|
|
|
if (!result) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
resource: result.resources,
|
|
pincode: result.resourcePincode,
|
|
password: result.resourcePassword
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get user session with user information
|
|
*/
|
|
export async function getUserSessionWithUser(
|
|
userSessionId: string
|
|
): Promise<UserSessionWithUser | null> {
|
|
if (config.isManagedMode()) {
|
|
try {
|
|
const response = await axios.get(
|
|
`${config.getRawConfig().managed?.endpoint}/api/v1/hybrid/session/${userSessionId}`,
|
|
await tokenManager.getAuthHeader()
|
|
);
|
|
return response.data.data;
|
|
} catch (error) {
|
|
if (axios.isAxiosError(error)) {
|
|
logger.error("Error fetching config in verify session:", {
|
|
message: error.message,
|
|
code: error.code,
|
|
status: error.response?.status,
|
|
statusText: error.response?.statusText,
|
|
url: error.config?.url,
|
|
method: error.config?.method
|
|
});
|
|
} else {
|
|
logger.error("Error fetching config in verify session:", error);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const [res] = await db
|
|
.select()
|
|
.from(sessions)
|
|
.leftJoin(users, eq(users.userId, sessions.userId))
|
|
.where(eq(sessions.sessionId, userSessionId));
|
|
|
|
if (!res) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
session: res.session,
|
|
user: res.user
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get user organization roles
|
|
*/
|
|
export async function getUserOrgRoles(
|
|
userId: string,
|
|
orgId: string
|
|
): Promise<number[]> {
|
|
if (config.isManagedMode()) {
|
|
try {
|
|
const response = await axios.get(
|
|
`${config.getRawConfig().managed?.endpoint}/api/v1/hybrid/user/${userId}/org/${orgId}/role`,
|
|
await tokenManager.getAuthHeader()
|
|
);
|
|
return response.data.data;
|
|
} catch (error) {
|
|
if (axios.isAxiosError(error)) {
|
|
logger.error("Error fetching config in verify session:", {
|
|
message: error.message,
|
|
code: error.code,
|
|
status: error.response?.status,
|
|
statusText: error.response?.statusText,
|
|
url: error.config?.url,
|
|
method: error.config?.method
|
|
});
|
|
} else {
|
|
logger.error("Error fetching config in verify session:", error);
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
const userOrgRes = await db
|
|
.select()
|
|
.from(userOrgs)
|
|
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, orgId)));
|
|
return userOrgRes.map((r) => r.roleId);
|
|
}
|
|
|
|
/**
|
|
* Check if role has access to resource
|
|
*/
|
|
export async function getRoleResourceAccess(
|
|
resourceId: number,
|
|
roleIds: number[]
|
|
): Promise<RoleResource | null> {
|
|
if (config.isManagedMode()) {
|
|
const requests = roleIds.map(async (roleId) => {
|
|
const response = await axios.get(
|
|
`${config.getRawConfig().managed?.endpoint}/api/v1/hybrid/role/${roleId}/resource/${resourceId}/access`,
|
|
await tokenManager.getAuthHeader()
|
|
);
|
|
return response.data.data;
|
|
});
|
|
const results = await Promise.allSettled(requests);
|
|
|
|
for (const result of results) {
|
|
if (result.status === "fulfilled") {
|
|
if (result.value) return result.value;
|
|
} else {
|
|
const error = result.reason;
|
|
if (axios.isAxiosError(error)) {
|
|
logger.error("Error fetching config in verify session:", {
|
|
message: error.message,
|
|
code: error.code,
|
|
status: error.response?.status,
|
|
statusText: error.response?.statusText,
|
|
url: error.config?.url,
|
|
method: error.config?.method
|
|
});
|
|
} else {
|
|
logger.error(
|
|
"Error fetching config in verify session:",
|
|
error
|
|
);
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const roleResourceAccess = await db
|
|
.select()
|
|
.from(roleResources)
|
|
.where(
|
|
and(
|
|
eq(roleResources.resourceId, resourceId),
|
|
inArray(roleResources.roleId, roleIds)
|
|
)
|
|
)
|
|
.limit(1);
|
|
|
|
return roleResourceAccess.length > 0 ? roleResourceAccess[0] : null;
|
|
}
|
|
|
|
/**
|
|
* Check if user has direct access to resource
|
|
*/
|
|
export async function getUserResourceAccess(
|
|
userId: string,
|
|
resourceId: number
|
|
) {
|
|
if (config.isManagedMode()) {
|
|
try {
|
|
const response = await axios.get(
|
|
`${config.getRawConfig().managed?.endpoint}/api/v1/hybrid/user/${userId}/resource/${resourceId}/access`,
|
|
await tokenManager.getAuthHeader()
|
|
);
|
|
return response.data.data;
|
|
} catch (error) {
|
|
if (axios.isAxiosError(error)) {
|
|
logger.error("Error fetching config in verify session:", {
|
|
message: error.message,
|
|
code: error.code,
|
|
status: error.response?.status,
|
|
statusText: error.response?.statusText,
|
|
url: error.config?.url,
|
|
method: error.config?.method
|
|
});
|
|
} else {
|
|
logger.error("Error fetching config in verify session:", error);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const userResourceAccess = await db
|
|
.select()
|
|
.from(userResources)
|
|
.where(
|
|
and(
|
|
eq(userResources.userId, userId),
|
|
eq(userResources.resourceId, resourceId)
|
|
)
|
|
)
|
|
.limit(1);
|
|
|
|
return userResourceAccess.length > 0 ? userResourceAccess[0] : null;
|
|
}
|
|
|
|
/**
|
|
* Get resource rules for a given resource
|
|
*/
|
|
export async function getResourceRules(
|
|
resourceId: number
|
|
): Promise<ResourceRule[]> {
|
|
if (config.isManagedMode()) {
|
|
try {
|
|
const response = await axios.get(
|
|
`${config.getRawConfig().managed?.endpoint}/api/v1/hybrid/resource/${resourceId}/rules`,
|
|
await tokenManager.getAuthHeader()
|
|
);
|
|
return response.data.data;
|
|
} catch (error) {
|
|
if (axios.isAxiosError(error)) {
|
|
logger.error("Error fetching config in verify session:", {
|
|
message: error.message,
|
|
code: error.code,
|
|
status: error.response?.status,
|
|
statusText: error.response?.statusText,
|
|
url: error.config?.url,
|
|
method: error.config?.method
|
|
});
|
|
} else {
|
|
logger.error("Error fetching config in verify session:", error);
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
|
|
const rules = await db
|
|
.select()
|
|
.from(resourceRules)
|
|
.where(eq(resourceRules.resourceId, resourceId));
|
|
|
|
return rules;
|
|
}
|