mirror of
https://github.com/logto-io/logto.git
synced 2025-01-06 20:40:08 -05:00
refactor(core): use audit log middleware on-demand
This commit is contained in:
parent
854e1e5751
commit
1476b8ea3a
7 changed files with 31 additions and 20 deletions
|
@ -9,7 +9,6 @@ import koaLogger from 'koa-logger';
|
||||||
import mount from 'koa-mount';
|
import mount from 'koa-mount';
|
||||||
|
|
||||||
import envSet, { MountedApps } from '#src/env-set/index.js';
|
import envSet, { MountedApps } from '#src/env-set/index.js';
|
||||||
import koaAuditLog from '#src/middleware/koa-audit-log.js';
|
|
||||||
import koaCheckDemoApp from '#src/middleware/koa-check-demo-app.js';
|
import koaCheckDemoApp from '#src/middleware/koa-check-demo-app.js';
|
||||||
import koaConnectorErrorHandler from '#src/middleware/koa-connector-error-handler.js';
|
import koaConnectorErrorHandler from '#src/middleware/koa-connector-error-handler.js';
|
||||||
import koaErrorHandler from '#src/middleware/koa-error-handler.js';
|
import koaErrorHandler from '#src/middleware/koa-error-handler.js';
|
||||||
|
@ -37,7 +36,6 @@ export default async function initApp(app: Koa): Promise<void> {
|
||||||
app.use(koaOIDCErrorHandler());
|
app.use(koaOIDCErrorHandler());
|
||||||
app.use(koaSlonikErrorHandler());
|
app.use(koaSlonikErrorHandler());
|
||||||
app.use(koaConnectorErrorHandler());
|
app.use(koaConnectorErrorHandler());
|
||||||
app.use(koaAuditLog());
|
|
||||||
app.use(koaI18next());
|
app.use(koaI18next());
|
||||||
|
|
||||||
const provider = await initOidc(app);
|
const provider = await initOidc(app);
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default function koaAuditLogSession<StateT, ContextT extends WithLogConte
|
||||||
} = await provider.interactionDetails(ctx.req, ctx.res);
|
} = await provider.interactionDetails(ctx.req, ctx.res);
|
||||||
ctx.log({ sessionId: jti, applicationId: String(client_id) });
|
ctx.log({ sessionId: jti, applicationId: String(client_id) });
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.error(`"${ctx.url}" failed to get oidc provider interaction`, error);
|
console.error(`Failed to get oidc provider interaction`, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default function koaLogSessionLegacy<
|
||||||
} = await provider.interactionDetails(ctx.req, ctx.res);
|
} = await provider.interactionDetails(ctx.req, ctx.res);
|
||||||
ctx.addLogContext({ sessionId: jti, applicationId: String(client_id) });
|
ctx.addLogContext({ sessionId: jti, applicationId: String(client_id) });
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.error(`"${ctx.url}" failed to get oidc provider interaction`, error);
|
console.error(`Failed to get oidc provider interaction`, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { Provider, errors } from 'oidc-provider';
|
||||||
import snakecaseKeys from 'snakecase-keys';
|
import snakecaseKeys from 'snakecase-keys';
|
||||||
|
|
||||||
import envSet from '#src/env-set/index.js';
|
import envSet from '#src/env-set/index.js';
|
||||||
|
import koaAuditLog from '#src/middleware/koa-audit-log.js';
|
||||||
import postgresAdapter from '#src/oidc/adapter.js';
|
import postgresAdapter from '#src/oidc/adapter.js';
|
||||||
import { isOriginAllowed, validateCustomClientMetadata } from '#src/oidc/utils.js';
|
import { isOriginAllowed, validateCustomClientMetadata } from '#src/oidc/utils.js';
|
||||||
import { findApplicationById } from '#src/queries/application.js';
|
import { findApplicationById } from '#src/queries/application.js';
|
||||||
|
@ -188,6 +189,9 @@ export default async function initOidc(app: Koa): Promise<Provider> {
|
||||||
|
|
||||||
addOidcEventListeners(oidc);
|
addOidcEventListeners(oidc);
|
||||||
|
|
||||||
|
// Session audit logs
|
||||||
|
oidc.use(koaAuditLog());
|
||||||
|
|
||||||
app.use(mount('/oidc', oidc.app));
|
app.use(mount('/oidc', oidc.app));
|
||||||
|
|
||||||
return oidc;
|
return oidc;
|
||||||
|
|
|
@ -4,6 +4,9 @@ import mount from 'koa-mount';
|
||||||
import Router from 'koa-router';
|
import Router from 'koa-router';
|
||||||
import type { Provider } from 'oidc-provider';
|
import type { Provider } from 'oidc-provider';
|
||||||
|
|
||||||
|
import koaAuditLogLegacy from '#src/middleware/koa-audit-log-legacy.js';
|
||||||
|
import koaAuditLog from '#src/middleware/koa-audit-log.js';
|
||||||
|
|
||||||
import koaAuditLogSession from '../middleware/koa-audit-log-session.js';
|
import koaAuditLogSession from '../middleware/koa-audit-log-session.js';
|
||||||
import koaAuth from '../middleware/koa-auth.js';
|
import koaAuth from '../middleware/koa-auth.js';
|
||||||
import koaLogSessionLegacy from '../middleware/koa-log-session-legacy.js';
|
import koaLogSessionLegacy from '../middleware/koa-log-session-legacy.js';
|
||||||
|
@ -29,11 +32,11 @@ import wellKnownRoutes from './well-known.js';
|
||||||
|
|
||||||
const createRouters = (provider: Provider) => {
|
const createRouters = (provider: Provider) => {
|
||||||
const sessionRouter: AnonymousRouterLegacy = new Router();
|
const sessionRouter: AnonymousRouterLegacy = new Router();
|
||||||
sessionRouter.use(koaLogSessionLegacy(provider));
|
sessionRouter.use(koaAuditLogLegacy(), koaLogSessionLegacy(provider));
|
||||||
sessionRoutes(sessionRouter, provider);
|
sessionRoutes(sessionRouter, provider);
|
||||||
|
|
||||||
const interactionRouter: AnonymousRouter = new Router();
|
const interactionRouter: AnonymousRouter = new Router();
|
||||||
interactionRouter.use(koaAuditLogSession(provider));
|
interactionRouter.use(koaAuditLog(), koaAuditLogSession(provider));
|
||||||
interactionRoutes(interactionRouter, provider);
|
interactionRoutes(interactionRouter, provider);
|
||||||
|
|
||||||
const managementRouter: AuthedRouter = new Router();
|
const managementRouter: AuthedRouter = new Router();
|
||||||
|
|
|
@ -24,7 +24,7 @@ export const verifySocialIdentity = async (
|
||||||
{ connectorId, connectorData }: SocialConnectorPayload,
|
{ connectorId, connectorData }: SocialConnectorPayload,
|
||||||
log: LogContext['log']
|
log: LogContext['log']
|
||||||
): Promise<SocialUserInfo> => {
|
): Promise<SocialUserInfo> => {
|
||||||
log.setKey('SignIn.SocialId.Social.Submit');
|
log.setKey('SignIn.SocialId.Social.Create');
|
||||||
log({ connectorId, connectorData });
|
log({ connectorId, connectorData });
|
||||||
|
|
||||||
const userInfo = await getUserInfoByAuthCode(connectorId, connectorData);
|
const userInfo = await getUserInfoByAuthCode(connectorId, connectorData);
|
||||||
|
|
|
@ -20,10 +20,12 @@ export enum Method {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum Action {
|
export enum Action {
|
||||||
/** Submit updated info to an entity, or submit to the system. (E.g. submit an interaction, submit a verification code to get verified) */
|
|
||||||
Submit = 'Submit',
|
|
||||||
/** Create a new entity. (E.g. create an interaction, create a verification code) */
|
/** Create a new entity. (E.g. create an interaction, create a verification code) */
|
||||||
Create = 'Create',
|
Create = 'Create',
|
||||||
|
/** Update an existing entity. (E.g. change interaction type) */
|
||||||
|
Update = 'Update',
|
||||||
|
/** Submit updated info to an entity, or submit to the system. (E.g. submit an interaction, submit a verification code to get verified) */
|
||||||
|
Submit = 'Submit',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,7 +46,7 @@ export enum Action {
|
||||||
export type ForgotPasswordLogKey = `${Flow.ForgotPassword}.${Exclude<
|
export type ForgotPasswordLogKey = `${Flow.ForgotPassword}.${Exclude<
|
||||||
Identifier,
|
Identifier,
|
||||||
'SocialId'
|
'SocialId'
|
||||||
>}.${Method.VerificationCode}.${Action}`;
|
>}.${Method.VerificationCode}.${Action.Create | Action.Submit}`;
|
||||||
|
|
||||||
type SignInRegisterFlow = Exclude<Flow, 'ForgotPassword'>;
|
type SignInRegisterFlow = Exclude<Flow, 'ForgotPassword'>;
|
||||||
|
|
||||||
|
@ -57,15 +59,18 @@ type SignInRegisterFlow = Exclude<Flow, 'ForgotPassword'>;
|
||||||
*
|
*
|
||||||
* Restrictions:
|
* Restrictions:
|
||||||
*
|
*
|
||||||
* - For social identifier and method, the value can only be `SignIn.SocialId.Social.Submit`.
|
* - For social identifier and method, the value can only be `SignIn.SocialId.Social.Create`.
|
||||||
* - For password method, the action can only be `Submit`.
|
* - For password method, the action can only be `Create`.
|
||||||
|
* - For verification code method, the action can be `Create` or `Submit`.
|
||||||
*
|
*
|
||||||
* @see {@link SignInRegisterFlow}, {@link Identifier}, {@link Method}, {@link Action} for all available enums.
|
* @see {@link SignInRegisterFlow}, {@link Identifier}, {@link Method}, {@link Action} for all available enums.
|
||||||
*/
|
*/
|
||||||
export type SignInRegisterLogKey =
|
export type SignInRegisterLogKey =
|
||||||
| `${Flow.SignIn}.${Identifier.SocialId}.${Method.Social}.${Action.Submit}`
|
| `${Flow.SignIn}.${Identifier.SocialId}.${Method.Social}.${Action.Create}`
|
||||||
| `${SignInRegisterFlow}.${Exclude<Identifier, 'SocialId'>}.${Method.Password}.${Action.Submit}`
|
| `${SignInRegisterFlow}.${Exclude<Identifier, 'SocialId'>}.${Method.Password}.${Action.Create}`
|
||||||
| `${SignInRegisterFlow}.${Exclude<Identifier, 'SocialId'>}.${Method.VerificationCode}.${Action}`;
|
| `${SignInRegisterFlow}.${Exclude<Identifier, 'SocialId'>}.${Method.VerificationCode}.${
|
||||||
|
| Action.Create
|
||||||
|
| Action.Submit}`;
|
||||||
|
|
||||||
export type FlowLogKey = `${Flow}.${Action}`;
|
export type FlowLogKey = `${Flow}.${Action}`;
|
||||||
|
|
||||||
|
@ -81,14 +86,15 @@ export type FlowLogKey = `${Flow}.${Action}`;
|
||||||
*
|
*
|
||||||
* The key MUST describe an {@link Action}:
|
* The key MUST describe an {@link Action}:
|
||||||
*
|
*
|
||||||
* - {@link Action.Submit} (submit updated info to an entity, or submit to the system);
|
* - {@link Action.Create} (Create a new entity);
|
||||||
* - {@link Action.Create} (create a new entity).
|
* - {@link Action.Update} (Update an existing entity.);
|
||||||
|
* - {@link Action.Submit} (Submit updated info to an entity, or submit to the system).
|
||||||
*
|
*
|
||||||
* In an interaction, ONLY the interaction itself and verification codes can be created, i.e.:
|
* In an interaction, ONLY the interaction itself and verification codes can be submitted, i.e.:
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* `${Flow}.Create`
|
* `${Flow}.Submit`
|
||||||
* `${Flow}.${Identifier}.VerificationCode.Create`
|
* `${Flow}.${Identifier}.VerificationCode.Submit`
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* There may be more restrictions, please see the specific type to learn more.
|
* There may be more restrictions, please see the specific type to learn more.
|
||||||
|
|
Loading…
Reference in a new issue