Feat: Scoped JWT to organization, add authMethod to request

This commit is contained in:
Daniel Hougaard
2024-03-17 18:48:10 +01:00
parent 6e96f2338c
commit 47287be5bf
3 changed files with 49 additions and 10 deletions
+2 -1
View File
@@ -19,7 +19,7 @@ import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service";
import { TAuthLoginFactory } from "@app/services/auth/auth-login-service"; import { TAuthLoginFactory } from "@app/services/auth/auth-login-service";
import { TAuthPasswordFactory } from "@app/services/auth/auth-password-service"; import { TAuthPasswordFactory } from "@app/services/auth/auth-password-service";
import { TAuthSignupFactory } from "@app/services/auth/auth-signup-service"; import { TAuthSignupFactory } from "@app/services/auth/auth-signup-service";
import { ActorType } from "@app/services/auth/auth-type"; import { ActorAuthMethod } from "@app/services/auth/auth-type";
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
import { TIdentityServiceFactory } from "@app/services/identity/identity-service"; import { TIdentityServiceFactory } from "@app/services/identity/identity-service";
import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service"; import { TIdentityAccessTokenServiceFactory } from "@app/services/identity-access-token/identity-access-token-service";
@@ -59,6 +59,7 @@ declare module "fastify" {
// identity injection. depending on which kinda of token the information is filled in auth // identity injection. depending on which kinda of token the information is filled in auth
auth: TAuthMode; auth: TAuthMode;
permission: { permission: {
authMethod: ActorAuthMethod;
type: ActorType; type: ActorType;
id: string; id: string;
orgId?: string; orgId?: string;
@@ -6,7 +6,7 @@ import { TServiceTokens, TUsers } from "@app/db/schemas";
import { TScimTokenJwtPayload } from "@app/ee/services/scim/scim-types"; import { TScimTokenJwtPayload } from "@app/ee/services/scim/scim-types";
import { getConfig } from "@app/lib/config/env"; import { getConfig } from "@app/lib/config/env";
import { UnauthorizedError } from "@app/lib/errors"; import { UnauthorizedError } from "@app/lib/errors";
import { ActorType, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type"; import { ActorType, AuthMethod, AuthMode, AuthModeJwtTokenPayload, AuthTokenType } from "@app/services/auth/auth-type";
import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "@app/services/identity-access-token/identity-access-token-types";
export type TAuthMode = export type TAuthMode =
@@ -17,6 +17,7 @@ export type TAuthMode =
tokenVersionId: string; // the session id of token used tokenVersionId: string; // the session id of token used
user: TUsers; user: TUsers;
orgId?: string; orgId?: string;
authMethod: AuthMethod;
} }
// | { // | {
// authMode: AuthMode.API_KEY; // authMode: AuthMode.API_KEY;
@@ -31,6 +32,7 @@ export type TAuthMode =
actor: ActorType.SERVICE; actor: ActorType.SERVICE;
serviceTokenId: string; serviceTokenId: string;
orgId: string; orgId: string;
authMethod: null;
} }
| { | {
authMode: AuthMode.IDENTITY_ACCESS_TOKEN; authMode: AuthMode.IDENTITY_ACCESS_TOKEN;
@@ -38,12 +40,14 @@ export type TAuthMode =
identityId: string; identityId: string;
identityName: string; identityName: string;
orgId: string; orgId: string;
authMethod: null;
} }
| { | {
authMode: AuthMode.SCIM_TOKEN; authMode: AuthMode.SCIM_TOKEN;
actor: ActorType.SCIM_CLIENT; actor: ActorType.SCIM_CLIENT;
scimTokenId: string; scimTokenId: string;
orgId: string; orgId: string;
authMethod: null;
}; };
const extractAuth = async (req: FastifyRequest, jwtSecret: string) => { const extractAuth = async (req: FastifyRequest, jwtSecret: string) => {
@@ -108,7 +112,15 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
switch (authMode) { switch (authMode) {
case AuthMode.JWT: { case AuthMode.JWT: {
const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token); const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token);
req.auth = { authMode: AuthMode.JWT, user, userId: user.id, tokenVersionId, actor, orgId }; req.auth = {
authMode: AuthMode.JWT,
user,
userId: user.id,
tokenVersionId,
actor,
orgId,
authMethod: token.authMethod
};
break; break;
} }
// Will always contain an orgId. // Will always contain an orgId.
@@ -119,7 +131,8 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
actor, actor,
orgId: identity.orgId, orgId: identity.orgId,
identityId: identity.identityId, identityId: identity.identityId,
identityName: identity.name identityName: identity.name,
authMethod: null
}; };
break; break;
} }
@@ -130,7 +143,8 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
authMode: AuthMode.SERVICE_TOKEN as const, authMode: AuthMode.SERVICE_TOKEN as const,
serviceToken, serviceToken,
serviceTokenId: serviceToken.id, serviceTokenId: serviceToken.id,
actor actor,
authMethod: null
}; };
break; break;
} }
@@ -141,7 +155,7 @@ export const injectIdentity = fp(async (server: FastifyZodProvider) => {
// } // }
case AuthMode.SCIM_TOKEN: { case AuthMode.SCIM_TOKEN: {
const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token); const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token);
req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId }; req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null };
break; break;
} }
default: default:
@@ -8,14 +8,38 @@ export const injectPermission = fp(async (server) => {
server.addHook("onRequest", async (req) => { server.addHook("onRequest", async (req) => {
if (!req.auth) return; if (!req.auth) return;
// if (!req.auth.authMethod) {
// throw new Error("THIS SHOULD NOT HAPPEN");
// }
if (req.auth.actor === ActorType.USER) { if (req.auth.actor === ActorType.USER) {
req.permission = { type: ActorType.USER, id: req.auth.userId, orgId: req.auth.orgId }; req.permission = {
type: ActorType.USER,
id: req.auth.userId,
orgId: req.auth.orgId,
authMethod: req.auth.authMethod
};
} else if (req.auth.actor === ActorType.IDENTITY) { } else if (req.auth.actor === ActorType.IDENTITY) {
req.permission = { type: ActorType.IDENTITY, id: req.auth.identityId, orgId: req.auth.orgId }; req.permission = {
type: ActorType.IDENTITY,
id: req.auth.identityId,
orgId: req.auth.orgId,
authMethod: null
};
} else if (req.auth.actor === ActorType.SERVICE) { } else if (req.auth.actor === ActorType.SERVICE) {
req.permission = { type: ActorType.SERVICE, id: req.auth.serviceTokenId, orgId: req.auth.orgId }; req.permission = {
type: ActorType.SERVICE,
id: req.auth.serviceTokenId,
orgId: req.auth.orgId,
authMethod: null
};
} else if (req.auth.actor === ActorType.SCIM_CLIENT) { } else if (req.auth.actor === ActorType.SCIM_CLIENT) {
req.permission = { type: ActorType.SCIM_CLIENT, id: req.auth.scimTokenId, orgId: req.auth.orgId }; req.permission = {
type: ActorType.SCIM_CLIENT,
id: req.auth.scimTokenId,
orgId: req.auth.orgId,
authMethod: null
};
} }
}); });
}); });