mirror of
https://github.com/fosrl/pangolin.git
synced 2025-08-25 11:45:32 +02:00
Badger & traefik working now?
This commit is contained in:
parent
f9184cf489
commit
825bff5d60
7 changed files with 126 additions and 25 deletions
|
@ -4,6 +4,9 @@ import { resourceSessions, ResourceSession } from "@server/db";
|
||||||
import { db } from "@server/db";
|
import { db } from "@server/db";
|
||||||
import { eq, and } from "drizzle-orm";
|
import { eq, and } from "drizzle-orm";
|
||||||
import config from "@server/lib/config";
|
import config from "@server/lib/config";
|
||||||
|
import axios from "axios";
|
||||||
|
import logger from "@server/logger";
|
||||||
|
import { tokenManager } from "@server/lib/tokenManager";
|
||||||
|
|
||||||
export const SESSION_COOKIE_NAME =
|
export const SESSION_COOKIE_NAME =
|
||||||
config.getRawConfig().server.session_cookie_name;
|
config.getRawConfig().server.session_cookie_name;
|
||||||
|
@ -62,6 +65,29 @@ export async function validateResourceSessionToken(
|
||||||
token: string,
|
token: string,
|
||||||
resourceId: number
|
resourceId: number
|
||||||
): Promise<ResourceSessionValidationResult> {
|
): Promise<ResourceSessionValidationResult> {
|
||||||
|
if (config.isHybridMode()) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/resource/${resourceId}/session/validate`, {
|
||||||
|
token: token
|
||||||
|
}, await tokenManager.getAuthHeader());
|
||||||
|
return response.data.data;
|
||||||
|
} catch (error) {
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
|
logger.error("Error validating resource session token in hybrid mode:", {
|
||||||
|
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 validating resource session token in hybrid mode:", error);
|
||||||
|
}
|
||||||
|
return { resourceSession: null };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const sessionId = encodeHexLowerCase(
|
const sessionId = encodeHexLowerCase(
|
||||||
sha256(new TextEncoder().encode(token))
|
sha256(new TextEncoder().encode(token))
|
||||||
);
|
);
|
||||||
|
|
|
@ -17,6 +17,8 @@ import {
|
||||||
import { and, eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import config from "@server/lib/config";
|
import config from "@server/lib/config";
|
||||||
|
import logger from "@server/logger";
|
||||||
|
import { tokenManager } from "@server/lib/tokenManager";
|
||||||
|
|
||||||
export type ResourceWithAuth = {
|
export type ResourceWithAuth = {
|
||||||
resource: Resource | null;
|
resource: Resource | null;
|
||||||
|
@ -37,10 +39,21 @@ export async function getResourceByDomain(
|
||||||
): Promise<ResourceWithAuth | null> {
|
): Promise<ResourceWithAuth | null> {
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/resource/domain/${domain}`);
|
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/resource/domain/${domain}`, await tokenManager.getAuthHeader());
|
||||||
return response.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching resource by domain:", 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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,10 +91,21 @@ export async function getUserSessionWithUser(
|
||||||
): Promise<UserSessionWithUser | null> {
|
): Promise<UserSessionWithUser | null> {
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/session/${userSessionId}`);
|
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/session/${userSessionId}`, await tokenManager.getAuthHeader());
|
||||||
return response.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching user session:", 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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,10 +132,21 @@ export async function getUserSessionWithUser(
|
||||||
export async function getUserOrgRole(userId: string, orgId: string) {
|
export async function getUserOrgRole(userId: string, orgId: string) {
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/user/${userId}/org/${orgId}/role`);
|
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/user/${userId}/org/${orgId}/role`, await tokenManager.getAuthHeader());
|
||||||
return response.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching user org role:", 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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,10 +171,21 @@ export async function getUserOrgRole(userId: string, orgId: string) {
|
||||||
export async function getRoleResourceAccess(resourceId: number, roleId: number) {
|
export async function getRoleResourceAccess(resourceId: number, roleId: number) {
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/role/${roleId}/resource/${resourceId}/access`);
|
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/role/${roleId}/resource/${resourceId}/access`, await tokenManager.getAuthHeader());
|
||||||
return response.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching role resource access:", 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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,10 +210,21 @@ export async function getRoleResourceAccess(resourceId: number, roleId: number)
|
||||||
export async function getUserResourceAccess(userId: string, resourceId: number) {
|
export async function getUserResourceAccess(userId: string, resourceId: number) {
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/user/${userId}/resource/${resourceId}/access`);
|
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/user/${userId}/resource/${resourceId}/access`, await tokenManager.getAuthHeader());
|
||||||
return response.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching user resource access:", 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;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,10 +249,21 @@ export async function getUserResourceAccess(userId: string, resourceId: number)
|
||||||
export async function getResourceRules(resourceId: number): Promise<ResourceRule[]> {
|
export async function getResourceRules(resourceId: number): Promise<ResourceRule[]> {
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/resource/${resourceId}/rules`);
|
const response = await axios.get(`${config.getRawConfig().hybrid?.endpoint}/api/v1/hybrid/resource/${resourceId}/rules`, await tokenManager.getAuthHeader());
|
||||||
return response.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching resource rules:", 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 [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,8 @@ export const configSchema = z
|
||||||
.object({
|
.object({
|
||||||
id: z.string().optional(),
|
id: z.string().optional(),
|
||||||
secret: z.string().optional(),
|
secret: z.string().optional(),
|
||||||
endpoint: z.string().optional()
|
endpoint: z.string().optional(),
|
||||||
|
redirect_endpoint: z.string().optional()
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
domains: z
|
domains: z
|
||||||
|
|
|
@ -218,7 +218,7 @@ export class TraefikConfigManager {
|
||||||
plugin: {
|
plugin: {
|
||||||
[badgerMiddlewareName]: {
|
[badgerMiddlewareName]: {
|
||||||
apiBaseUrl: new URL(
|
apiBaseUrl: new URL(
|
||||||
"/api/v0",
|
"/api/v1",
|
||||||
`http://${
|
`http://${
|
||||||
config.getRawConfig().server.internal_hostname
|
config.getRawConfig().server.internal_hostname
|
||||||
}:${config.getRawConfig().server.internal_port}`
|
}:${config.getRawConfig().server.internal_port}`
|
||||||
|
|
|
@ -140,7 +140,7 @@ export async function verifyResourceSession(
|
||||||
const result = await getResourceByDomain(cleanHost);
|
const result = await getResourceByDomain(cleanHost);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
logger.debug("Resource not found", cleanHost);
|
logger.debug(`Resource not found ${cleanHost}`);
|
||||||
return notAllowed(res);
|
return notAllowed(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ export async function verifyResourceSession(
|
||||||
const { resource, pincode, password } = resourceData;
|
const { resource, pincode, password } = resourceData;
|
||||||
|
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
logger.debug("Resource not found", cleanHost);
|
logger.debug(`Resource not found ${cleanHost}`);
|
||||||
return notAllowed(res);
|
return notAllowed(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,13 @@ export async function verifyResourceSession(
|
||||||
return allowed(res);
|
return allowed(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
const redirectUrl = `${config.getRawConfig().app.dashboard_url}/auth/resource/${encodeURIComponent(
|
let endpoint: string;
|
||||||
|
if (config.isHybridMode()) {
|
||||||
|
endpoint = config.getRawConfig().hybrid?.redirect_endpoint || config.getRawConfig().hybrid?.endpoint || "";
|
||||||
|
} else {
|
||||||
|
endpoint = config.getRawConfig().app.dashboard_url;
|
||||||
|
}
|
||||||
|
const redirectUrl = `${endpoint}/auth/resource/${encodeURIComponent(
|
||||||
resource.resourceId
|
resource.resourceId
|
||||||
)}?redirect=${encodeURIComponent(originalRequestURL)}`;
|
)}?redirect=${encodeURIComponent(originalRequestURL)}`;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ badgerRouter.post("/verify-session", badger.verifyResourceSession);
|
||||||
|
|
||||||
if (config.isHybridMode()) {
|
if (config.isHybridMode()) {
|
||||||
badgerRouter.post("/exchange-session", (req, res, next) =>
|
badgerRouter.post("/exchange-session", (req, res, next) =>
|
||||||
proxyToRemote(req, res, next, "badger/exchange-session")
|
proxyToRemote(req, res, next, "hybrid/badger/exchange-session")
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
badgerRouter.post("/exchange-session", badger.exchangeSession);
|
badgerRouter.post("/exchange-session", badger.exchangeSession);
|
||||||
|
|
|
@ -51,7 +51,7 @@ export async function traefikConfigProvider(
|
||||||
plugin: {
|
plugin: {
|
||||||
[badgerMiddlewareName]: {
|
[badgerMiddlewareName]: {
|
||||||
apiBaseUrl: new URL(
|
apiBaseUrl: new URL(
|
||||||
"/api/v0",
|
"/api/v1",
|
||||||
`http://${
|
`http://${
|
||||||
config.getRawConfig().server.internal_hostname
|
config.getRawConfig().server.internal_hostname
|
||||||
}:${config.getRawConfig().server.internal_port}`
|
}:${config.getRawConfig().server.internal_port}`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue