Make more progress on service token v3

This commit is contained in:
Tuan Dang
2023-09-22 11:19:14 +01:00
parent 84d094b4d8
commit 53856ff868
6 changed files with 74 additions and 5 deletions

View File

@@ -7,6 +7,7 @@ import {
ITokenVersion,
IUser,
ServiceTokenData,
ServiceTokenDataV3,
TokenVersion,
User,
} from "../models";
@@ -29,6 +30,7 @@ import {
} from "../variables";
import {
ServiceTokenAuthData,
ServiceTokenV3AuthData,
UserAuthData
} from "../interfaces/middleware";
@@ -47,6 +49,9 @@ export const validateAuthMode = ({
headers: { [key: string]: string | string[] | undefined },
acceptedAuthModes: AuthMode[]
}) => {
// TODO: update this to accept service token v3
const apiKey = headers["x-api-key"];
const authHeader = headers["authorization"];
@@ -76,6 +81,9 @@ export const validateAuthMode = ({
case "st":
authMode = AuthMode.SERVICE_TOKEN;
break;
case "proj_token":
authMode = AuthMode.SERVICE_TOKEN_V3;
break;
default:
authMode = AuthMode.JWT;
}
@@ -211,8 +219,55 @@ export const getAuthSTDPayload = async ({
userAgent: req.headers["user-agent"] ?? "",
userAgentType: getUserAgentType(req.headers["user-agent"])
}
}
// return serviceTokenDataToReturn;
/**
* Return service token data V3 payload corresponding to service token [authTokenValue]
* @param {Object} obj
* @param {String} obj.authTokenValue - service token value
* @returns {ServiceTokenData} serviceTokenData - service token data
*/
export const getAuthSTDV3Payload = async ({
req,
authTokenValue,
}: {
req: Request,
authTokenValue: string;
}): Promise<ServiceTokenV3AuthData> => {
const decodedToken = <jwt.UserIDJwtPayload>(
jwt.verify(authTokenValue, "hello") // TODO: change this
);
// perhaps turn this one into a find one and update call?
const serviceTokenData = await ServiceTokenDataV3.findOne({
_id: new Types.ObjectId(decodedToken.serviceTokenDataId),
});
if (!serviceTokenData) {
throw UnauthorizedRequestError({
message: "Failed to authenticate" // standardize auth error messages
});
} else if (serviceTokenData?.expiresAt && new Date(serviceTokenData.expiresAt) < new Date()) {
// case: service token expired
await ServiceTokenDataV3.findByIdAndDelete(serviceTokenData._id);
throw UnauthorizedRequestError({
message: "Failed to authenticate",
});
}
return {
actor: {
type: ActorType.SERVICE, // should this be servicev3 bc the shape of it is different?
metadata: {
serviceId: serviceTokenData._id.toString(),
name: serviceTokenData.name
}
},
authPayload: serviceTokenData,
ipAddress: req.realIP,
userAgent: req.headers["user-agent"] ?? "",
userAgentType: getUserAgentType(req.headers["user-agent"])
}
}
/**

View File

@@ -1,6 +1,7 @@
import { Types } from "mongoose";
import {
IServiceTokenData,
IServiceTokenDataV3,
IUser,
} from "../../models";
import {
@@ -21,6 +22,11 @@ export interface UserAuthData extends BaseAuthData {
authPayload: IUser;
}
export interface ServiceTokenV3AuthData extends BaseAuthData {
actor: ServiceActor;
authPayload: IServiceTokenDataV3;
}
export interface ServiceTokenAuthData extends BaseAuthData {
actor: ServiceActor;
authPayload: IServiceTokenData;
@@ -28,4 +34,5 @@ export interface ServiceTokenAuthData extends BaseAuthData {
export type AuthData =
| UserAuthData
| ServiceTokenV3AuthData
| ServiceTokenAuthData;

View File

@@ -3,6 +3,7 @@ import { NextFunction, Request, Response } from "express";
import {
getAuthAPIKeyPayload,
getAuthSTDPayload,
getAuthSTDV3Payload,
getAuthUserPayload,
validateAuthMode,
} from "../helpers/auth";
@@ -49,6 +50,12 @@ const requireAuth = ({
});
req.serviceTokenData = authData.authPayload;
break;
case AuthMode.SERVICE_TOKEN_V3:
authData = await getAuthSTDV3Payload({
req,
authTokenValue
});
break;
case AuthMode.API_KEY:
authData = await getAuthAPIKeyPayload({
req,
@@ -61,9 +68,7 @@ const requireAuth = ({
req,
authTokenValue
});
// authPayload = authUserPayload.user;
req.user = authData.authPayload;
// req.tokenVersionId = authUserPayload.tokenVersionId; // TODO
break;
}

View File

@@ -17,7 +17,8 @@ export interface IServiceTokenDataV3 extends Document {
workspace: Types.ObjectId;
publicKey: string;
isActive: boolean;
lastUsed: Date;
lastUsed?: Date;
expiresAt?: Date;
scopes: Array<Scope>;
}

View File

@@ -154,7 +154,7 @@ export const DeleteIntegrationAuthV1 = z.object({
export const GetIntegrationAuthTeamCityBuildConfigsV1 = z.object({
params:z.object({
appId:z.string().trim(),
appId:z.string().trim().optional(),
integrationAuthId:z.string().trim()
})
})

View File

@@ -1,6 +1,7 @@
export enum AuthMode {
JWT = "jwt",
SERVICE_TOKEN = "serviceToken",
SERVICE_TOKEN_V3 = "serviceTokenV3",
API_KEY = "apiKey"
}