Add actor data to request

This commit is contained in:
Owen
2025-10-22 14:27:21 -07:00
parent f748c5dbe4
commit f2c31d3ca6
6 changed files with 79 additions and 44 deletions

View File

@@ -678,7 +678,6 @@ export const requestAuditLog = pgTable(
id: serial("id").primaryKey(), id: serial("id").primaryKey(),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId") orgId: text("orgId")
.notNull()
.references(() => orgs.orgId, { onDelete: "cascade" }), .references(() => orgs.orgId, { onDelete: "cascade" }),
action: boolean("action").notNull(), action: boolean("action").notNull(),
reason: integer("reason").notNull(), reason: integer("reason").notNull(),

View File

@@ -723,7 +723,6 @@ export const requestAuditLog = sqliteTable(
id: integer("id").primaryKey({ autoIncrement: true }), id: integer("id").primaryKey({ autoIncrement: true }),
timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds timestamp: integer("timestamp").notNull(), // this is EPOCH time in seconds
orgId: text("orgId") orgId: text("orgId")
.notNull()
.references(() => orgs.orgId, { onDelete: "cascade" }), .references(() => orgs.orgId, { onDelete: "cascade" }),
action: integer("action", { mode: "boolean" }).notNull(), action: integer("action", { mode: "boolean" }).notNull(),
reason: integer("reason").notNull(), reason: integer("reason").notNull(),

View File

@@ -17,9 +17,9 @@ export type QueryActionAuditLogResponse = {
export type QueryRequestAuditLogResponse = { export type QueryRequestAuditLogResponse = {
log: { log: {
timestamp: number; timestamp: number;
orgId: string;
action: boolean; action: boolean;
reason: number; reason: number;
orgId: string | null;
actorType: string | null; actorType: string | null;
actor: string | null; actor: string | null;
actorId: string | null; actorId: string | null;

View File

@@ -27,9 +27,10 @@ export async function logRequestAudit(
action: boolean; action: boolean;
reason: number; reason: number;
resourceId?: number; resourceId?: number;
orgId?: string;
location?: string; location?: string;
user?: { username: string; userId: string; orgId: string }; user?: { username: string; userId: string; };
apiKey?: { name: string; apiKeyId: string; orgId: string }; apiKey?: { name: string | null; apiKeyId: string; };
metadata?: any; metadata?: any;
// userAgent?: string; // userAgent?: string;
}, },
@@ -47,32 +48,23 @@ export async function logRequestAudit(
} }
) { ) {
try { try {
let orgId: string | undefined;
let actorType: string | undefined; let actorType: string | undefined;
let actor: string | undefined; let actor: string | undefined;
let actorId: string | undefined; let actorId: string | undefined;
const user = data.user; const user = data.user;
if (user) { if (user) {
orgId = user.orgId;
actorType = "user"; actorType = "user";
actor = user.username; actor = user.username;
actorId = user.userId; actorId = user.userId;
} }
const apiKey = data.apiKey; const apiKey = data.apiKey;
if (apiKey) { if (apiKey) {
orgId = apiKey.orgId;
actorType = "apiKey"; actorType = "apiKey";
actor = apiKey.name; actor = apiKey.name || apiKey.apiKeyId;
actorId = apiKey.apiKeyId; actorId = apiKey.apiKeyId;
} }
if (!orgId) {
logger.warn("logRequestAudit: No organization context found");
orgId = "org_7g93l5xu7p61q14";
// return;
}
// if (!actorType || !actor || !actorId) { // if (!actorType || !actor || !actorId) {
// logger.warn("logRequestAudit: Incomplete actor information"); // logger.warn("logRequestAudit: Incomplete actor information");
// return; // return;
@@ -107,7 +99,7 @@ export async function logRequestAudit(
await db.insert(requestAuditLog).values({ await db.insert(requestAuditLog).values({
timestamp, timestamp,
orgId, orgId: data.orgId,
actorType, actorType,
actor, actor,
actorId, actorId,

View File

@@ -1,6 +1,4 @@
import { import { validateResourceSessionToken } from "@server/auth/sessions/resource";
validateResourceSessionToken
} from "@server/auth/sessions/resource";
import { verifyResourceAccessToken } from "@server/auth/verifyResourceAccessToken"; import { verifyResourceAccessToken } from "@server/auth/verifyResourceAccessToken";
import { import {
getResourceByDomain, getResourceByDomain,
@@ -151,14 +149,17 @@ export async function verifyResourceSession(
if (!result) { if (!result) {
logger.debug(`Resource not found ${cleanHost}`); logger.debug(`Resource not found ${cleanHost}`);
logRequestAudit( // TODO: we cant log this for now because we dont know the org
{ // eventually it would be cool to show this for the server admin
action: false,
reason: 201, //resource not found // logRequestAudit(
location: ipCC // {
}, // action: false,
parsedBody.data // reason: 201, //resource not found
); // location: ipCC
// },
// parsedBody.data
// );
return notAllowed(res); return notAllowed(res);
} }
@@ -172,14 +173,17 @@ export async function verifyResourceSession(
if (!resource) { if (!resource) {
logger.debug(`Resource not found ${cleanHost}`); logger.debug(`Resource not found ${cleanHost}`);
logRequestAudit( // TODO: we cant log this for now because we dont know the org
{ // eventually it would be cool to show this for the server admin
action: false,
reason: 201, //resource not found // logRequestAudit(
location: ipCC // {
}, // action: false,
parsedBody.data // reason: 201, //resource not found
); // location: ipCC
// },
// parsedBody.data
// );
return notAllowed(res); return notAllowed(res);
} }
@@ -193,6 +197,8 @@ export async function verifyResourceSession(
{ {
action: false, action: false,
reason: 202, //resource blocked reason: 202, //resource blocked
resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -218,6 +224,7 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 100, // allowed by rule reason: 100, // allowed by rule
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -233,6 +240,7 @@ export async function verifyResourceSession(
action: false, action: false,
reason: 203, // dropped by rules reason: 203, // dropped by rules
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -264,6 +272,7 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 101, // allowed no auth reason: 101, // allowed no auth
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -325,7 +334,12 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 102, // valid access token reason: 102, // valid access token
resourceId: resource.resourceId, resourceId: resource.resourceId,
location: ipCC orgId: resource.orgId,
location: ipCC,
apiKey: {
name: tokenItem.title,
apiKeyId: tokenItem.accessTokenId,
}
}, },
parsedBody.data parsedBody.data
); );
@@ -371,7 +385,12 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 102, // valid access token reason: 102, // valid access token
resourceId: resource.resourceId, resourceId: resource.resourceId,
location: ipCC orgId: resource.orgId,
location: ipCC,
apiKey: {
name: tokenItem.title,
apiKeyId: tokenItem.accessTokenId,
}
}, },
parsedBody.data parsedBody.data
); );
@@ -393,7 +412,8 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 103, // valid header auth reason: 103, // valid header auth
resourceId: resource.resourceId, resourceId: resource.resourceId,
location: ipCC orgId: resource.orgId,
location: ipCC,
}, },
parsedBody.data parsedBody.data
); );
@@ -413,6 +433,7 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 103, // valid header auth reason: 103, // valid header auth
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -433,6 +454,7 @@ export async function verifyResourceSession(
action: false, action: false,
reason: 299, // no more auth methods reason: 299, // no more auth methods
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -453,6 +475,7 @@ export async function verifyResourceSession(
action: false, action: false,
reason: 299, // no more auth methods reason: 299, // no more auth methods
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -476,6 +499,7 @@ export async function verifyResourceSession(
action: false, action: false,
reason: 204, // no sessions reason: 204, // no sessions
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -520,6 +544,7 @@ export async function verifyResourceSession(
action: false, action: false,
reason: 205, // temporary request token reason: 205, // temporary request token
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -539,6 +564,7 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 104, // valid pincode reason: 104, // valid pincode
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -557,6 +583,7 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 105, // valid password reason: 105, // valid password
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -578,6 +605,7 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 106, // valid email reason: 106, // valid email
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data
@@ -596,7 +624,12 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 102, // valid access token reason: 102, // valid access token
resourceId: resource.resourceId, resourceId: resource.resourceId,
location: ipCC orgId: resource.orgId,
location: ipCC,
apiKey: {
name: resourceSession.accessTokenTitle,
apiKeyId: resourceSession.accessTokenId,
}
}, },
parsedBody.data parsedBody.data
); );
@@ -634,7 +667,12 @@ export async function verifyResourceSession(
action: true, action: true,
reason: 107, // valid sso reason: 107, // valid sso
resourceId: resource.resourceId, resourceId: resource.resourceId,
location: ipCC orgId: resource.orgId,
location: ipCC,
user: {
username: allowedUserData.username,
userId: resourceSession.userId
}
}, },
parsedBody.data parsedBody.data
); );
@@ -662,6 +700,7 @@ export async function verifyResourceSession(
action: false, action: false,
reason: 299, // no more auth methods reason: 299, // no more auth methods
resourceId: resource.resourceId, resourceId: resource.resourceId,
orgId: resource.orgId,
location: ipCC location: ipCC
}, },
parsedBody.data parsedBody.data

View File

@@ -353,12 +353,18 @@ export default function GeneralPage() {
cell: ({ row }) => { cell: ({ row }) => {
return ( return (
<span className="flex items-center gap-1"> <span className="flex items-center gap-1">
{row.original.actorType == "user" ? ( {row.original.actor ? (
<User className="h-4 w-4" /> <>
{row.original.actorType == "user" ? (
<User className="h-4 w-4" />
) : (
<Key className="h-4 w-4" />
)}
{row.original.actor}
</>
) : ( ) : (
<Key className="h-4 w-4" /> <>-</>
)} )}
{row.original.actor}
</span> </span>
); );
} }