mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 01:52:22 +00:00
Update ST V3 to machine identity
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
MachineMembershipOrg,
|
||||
Membership,
|
||||
MembershipOrg,
|
||||
ServiceMembershipOrg,
|
||||
MembershipOrg,
|
||||
Workspace
|
||||
} from "../../models";
|
||||
import { Role } from "../../ee/models";
|
||||
@@ -389,16 +389,16 @@ export const deleteOrganizationById = async (req: Request, res: Response) => {
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const getOrganizationServiceMemberships = async (req: Request, res: Response) => {
|
||||
export const getOrganizationMachineMemberships = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgServiceMembersV2, req);
|
||||
|
||||
const serviceMemberships = await ServiceMembershipOrg.find({
|
||||
const machineMemberships = await MachineMembershipOrg.find({
|
||||
organization: new Types.ObjectId(organizationId)
|
||||
}).populate("service customRole");
|
||||
|
||||
}).populate("machineIdentity customRole");
|
||||
|
||||
return res.status(200).send({
|
||||
serviceMemberships
|
||||
machineMemberships
|
||||
});
|
||||
}
|
||||
@@ -2,10 +2,10 @@ import { Request, Response } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
Key,
|
||||
Membership,
|
||||
ServiceMembership,
|
||||
MachineIdentity,
|
||||
MachineMembership,
|
||||
Membership,
|
||||
ServiceTokenData,
|
||||
ServiceTokenDataV3,
|
||||
Workspace
|
||||
} from "../../models";
|
||||
import { Role } from "../../ee/models";
|
||||
@@ -503,16 +503,15 @@ export const toggleAutoCapitalization = async (req: Request, res: Response) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Add service account with id [serviceId] to workspace
|
||||
* Add machine identity with id [machineId] to workspace
|
||||
* with id [workspaceId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const addWorkspaceServiceMembership = async (req: Request, res: Response) => {
|
||||
export const addMachineToWorkspace = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { workspaceId },
|
||||
params: { workspaceId, machineId },
|
||||
body: {
|
||||
serviceId,
|
||||
role
|
||||
}
|
||||
} = await validateRequest(reqValidator.AddWorkspaceServiceMemberV2, req);
|
||||
@@ -527,22 +526,22 @@ export const addWorkspaceServiceMembership = async (req: Request, res: Response)
|
||||
ProjectPermissionSub.ServiceTokens
|
||||
);
|
||||
|
||||
let serviceMembership = await ServiceMembership.findOne({
|
||||
service: new Types.ObjectId(serviceId),
|
||||
let machineMembership = await MachineMembership.findOne({
|
||||
machineIdentity: new Types.ObjectId(machineId),
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
if (serviceMembership) throw BadRequestError({
|
||||
if (machineMembership) throw BadRequestError({
|
||||
message: "Service account already exists in workspace"
|
||||
});
|
||||
|
||||
const serviceTokenData = await ServiceTokenDataV3.findById(serviceId);
|
||||
if (!serviceTokenData) throw ResourceNotFoundError();
|
||||
const machineIdentity = await MachineIdentity.findById(machineId);
|
||||
if (!machineIdentity) throw ResourceNotFoundError();
|
||||
|
||||
const workspace = await Workspace.findById(workspaceId);
|
||||
if (!workspace) throw ResourceNotFoundError();
|
||||
|
||||
if (!serviceTokenData.organization.equals(workspace.organization)) throw BadRequestError({
|
||||
if (!machineIdentity.organization.equals(workspace.organization)) throw BadRequestError({
|
||||
message: "Failed to add service account to workspace in another organization"
|
||||
});
|
||||
|
||||
@@ -560,27 +559,27 @@ export const addWorkspaceServiceMembership = async (req: Request, res: Response)
|
||||
}
|
||||
}
|
||||
|
||||
serviceMembership = await new ServiceMembership({
|
||||
service: serviceTokenData._id,
|
||||
machineMembership = await new MachineMembership({
|
||||
machineIdentity: machineIdentity._id,
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
role,
|
||||
customRole
|
||||
}).save();
|
||||
|
||||
return res.status(200).send({
|
||||
serviceMembership
|
||||
machineMembership
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add service account with id [serviceId] to workspace
|
||||
* Add service account with id [machineId] to workspace
|
||||
* with id [workspaceId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const deleteWorkspaceServiceMembership = async (req: Request, res: Response) => {
|
||||
export const deleteMachineFromWorkspace = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { workspaceId, serviceId }
|
||||
params: { workspaceId, machineId }
|
||||
} = await validateRequest(reqValidator.DeleteWorkspaceServiceMemberV2, req);
|
||||
|
||||
const { permission } = await getAuthDataProjectPermissions({
|
||||
@@ -593,29 +592,29 @@ export const addWorkspaceServiceMembership = async (req: Request, res: Response)
|
||||
ProjectPermissionSub.ServiceTokens
|
||||
);
|
||||
|
||||
const serviceMembership = await ServiceMembership.findOneAndDelete({
|
||||
service: new Types.ObjectId(serviceId),
|
||||
const machineMembership = await MachineMembership.findOneAndDelete({
|
||||
machineIdentity: new Types.ObjectId(machineId),
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
if (!serviceMembership) throw ResourceNotFoundError();
|
||||
if (!machineMembership) throw ResourceNotFoundError();
|
||||
|
||||
return res.status(200).send({
|
||||
serviceMembership
|
||||
machineMembership
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of service memberships for workspace with id [workspaceId]
|
||||
* Return list of machine identity memberships for workspace with id [workspaceId]
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const getWorkspaceServiceMemberships = async (req: Request, res: Response) => {
|
||||
export const getWorkspaceMachineMemberships = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { workspaceId }
|
||||
} = await validateRequest(reqValidator.GetWorkspaceServiceMembersV2, req);
|
||||
|
||||
|
||||
const { permission } = await getAuthDataProjectPermissions({
|
||||
authData: req.authData,
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
@@ -626,11 +625,11 @@ export const addWorkspaceServiceMembership = async (req: Request, res: Response)
|
||||
ProjectPermissionSub.ServiceTokens
|
||||
);
|
||||
|
||||
const serviceMemberships = await ServiceMembership.find({
|
||||
const machineMemberships = await MachineMembership.find({
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
}).populate("service customRole");
|
||||
}).populate("machineIdentity customRole");
|
||||
|
||||
return res.status(200).send({
|
||||
serviceMemberships
|
||||
machineMemberships
|
||||
});
|
||||
}
|
||||
@@ -2,10 +2,10 @@ import { Request, Response } from "express";
|
||||
import { PipelineStage, Types } from "mongoose";
|
||||
import {
|
||||
Folder,
|
||||
MachineIdentity,
|
||||
Membership,
|
||||
Secret,
|
||||
ServiceTokenData,
|
||||
ServiceTokenDataV3,
|
||||
TFolderSchema,
|
||||
User,
|
||||
Workspace
|
||||
@@ -758,14 +758,14 @@ export const getWorkspaceAuditLogActorFilterOpts = async (req: Request, res: Res
|
||||
}));
|
||||
|
||||
const serviceV3Actors: ServiceActorV3[] = (
|
||||
await ServiceTokenDataV3.find({
|
||||
await MachineIdentity.find({
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
})
|
||||
).map((serviceTokenData) => ({
|
||||
).map((machineIdentity) => ({
|
||||
type: ActorType.SERVICE_V3,
|
||||
metadata: {
|
||||
serviceId: serviceTokenData._id.toString(),
|
||||
name: serviceTokenData.name
|
||||
serviceId: machineIdentity._id.toString(),
|
||||
name: machineIdentity.name
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as serviceTokenDataController from "./serviceTokenDataController";
|
||||
import * as machineIdentityController from "./machineIdentityController";
|
||||
import * as apiKeyDataController from "./apiKeyDataController";
|
||||
|
||||
export {
|
||||
serviceTokenDataController,
|
||||
machineIdentityController,
|
||||
apiKeyDataController
|
||||
}
|
||||
+71
-77
@@ -2,20 +2,19 @@ import jwt from "jsonwebtoken";
|
||||
import { Request, Response } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
ServiceTokenDataV3,
|
||||
ServiceTokenDataV3Key, // TODO: remove
|
||||
IMachineIdentityTrustedIp,
|
||||
MachineIdentity,
|
||||
MachineMembership,
|
||||
MachineMembershipOrg,
|
||||
Organization,
|
||||
ServiceMembershipOrg,
|
||||
ServiceMembership
|
||||
} from "../../../models";
|
||||
import { IServiceTokenV3TrustedIp } from "../../../models/serviceTokenDataV3";
|
||||
import {
|
||||
ActorType,
|
||||
EventType,
|
||||
Role
|
||||
} from "../../models";
|
||||
import { validateRequest } from "../../../helpers/validation";
|
||||
import * as reqValidator from "../../../validation/serviceTokenDataV3";
|
||||
import * as reqValidator from "../../../validation/machineIdentity";
|
||||
import { createToken } from "../../../helpers/auth";
|
||||
|
||||
|
||||
@@ -26,7 +25,7 @@ import { getAuthSecret } from "../../../config";
|
||||
import { ADMIN, AuthTokenType, CUSTOM, MEMBER } from "../../../variables";
|
||||
|
||||
/**
|
||||
* Return access and refresh token as per refresh operation
|
||||
* Return machine identity access and refresh token as per refresh operation
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
@@ -43,14 +42,14 @@ import { ADMIN, AuthTokenType, CUSTOM, MEMBER } from "../../../variables";
|
||||
|
||||
if (decodedToken.authTokenType !== AuthTokenType.SERVICE_REFRESH_TOKEN) throw UnauthorizedRequestError();
|
||||
|
||||
let serviceTokenData = await ServiceTokenDataV3.findOne({
|
||||
let machineIdentity = await MachineIdentity.findOne({
|
||||
_id: new Types.ObjectId(decodedToken.serviceTokenDataId),
|
||||
isActive: true
|
||||
});
|
||||
|
||||
if (!serviceTokenData) throw UnauthorizedRequestError();
|
||||
if (!machineIdentity) throw UnauthorizedRequestError();
|
||||
|
||||
if (decodedToken.tokenVersion !== serviceTokenData.tokenVersion) {
|
||||
if (decodedToken.tokenVersion !== machineIdentity.tokenVersion) {
|
||||
// raise alarm
|
||||
throw UnauthorizedRequestError();
|
||||
}
|
||||
@@ -67,9 +66,9 @@ import { ADMIN, AuthTokenType, CUSTOM, MEMBER } from "../../../variables";
|
||||
token_type: "Bearer"
|
||||
};
|
||||
|
||||
if (serviceTokenData.isRefreshTokenRotationEnabled) {
|
||||
serviceTokenData = await ServiceTokenDataV3.findByIdAndUpdate(
|
||||
serviceTokenData._id,
|
||||
if (machineIdentity.isRefreshTokenRotationEnabled) {
|
||||
machineIdentity = await MachineIdentity.findByIdAndUpdate(
|
||||
machineIdentity._id,
|
||||
{
|
||||
$inc: {
|
||||
tokenVersion: 1
|
||||
@@ -80,13 +79,13 @@ import { ADMIN, AuthTokenType, CUSTOM, MEMBER } from "../../../variables";
|
||||
}
|
||||
);
|
||||
|
||||
if (!serviceTokenData) throw BadRequestError();
|
||||
if (!machineIdentity) throw BadRequestError();
|
||||
|
||||
response.refresh_token = createToken({
|
||||
payload: {
|
||||
serviceTokenDataId: serviceTokenData._id.toString(),
|
||||
serviceTokenDataId: machineIdentity._id.toString(),
|
||||
authTokenType: AuthTokenType.SERVICE_REFRESH_TOKEN,
|
||||
tokenVersion: serviceTokenData.tokenVersion
|
||||
tokenVersion: machineIdentity.tokenVersion
|
||||
},
|
||||
secret: await getAuthSecret()
|
||||
});
|
||||
@@ -94,18 +93,18 @@ import { ADMIN, AuthTokenType, CUSTOM, MEMBER } from "../../../variables";
|
||||
|
||||
response.access_token = createToken({
|
||||
payload: {
|
||||
serviceTokenDataId: serviceTokenData._id.toString(),
|
||||
serviceTokenDataId: machineIdentity._id.toString(),
|
||||
authTokenType: AuthTokenType.SERVICE_ACCESS_TOKEN,
|
||||
tokenVersion: serviceTokenData.tokenVersion
|
||||
tokenVersion: machineIdentity.tokenVersion
|
||||
},
|
||||
expiresIn: serviceTokenData.accessTokenTTL,
|
||||
expiresIn: machineIdentity.accessTokenTTL,
|
||||
secret: await getAuthSecret()
|
||||
});
|
||||
|
||||
response.expires_in = serviceTokenData.accessTokenTTL;
|
||||
response.expires_in = machineIdentity.accessTokenTTL;
|
||||
|
||||
await ServiceTokenDataV3.findByIdAndUpdate(
|
||||
serviceTokenData._id,
|
||||
await MachineIdentity.findByIdAndUpdate(
|
||||
machineIdentity._id,
|
||||
{
|
||||
refreshTokenLastUsed: new Date(),
|
||||
$inc: { refreshTokenUsageCount: 1 }
|
||||
@@ -119,12 +118,12 @@ import { ADMIN, AuthTokenType, CUSTOM, MEMBER } from "../../../variables";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create service token data V3
|
||||
* Create machine identity
|
||||
* @param req
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
export const createMachineIdentity = async (req: Request, res: Response) => {
|
||||
const {
|
||||
body: {
|
||||
name,
|
||||
@@ -135,7 +134,7 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
accessTokenTTL,
|
||||
isRefreshTokenRotationEnabled
|
||||
}
|
||||
} = await validateRequest(reqValidator.CreateServiceTokenV3, req);
|
||||
} = await validateRequest(reqValidator.CreateMachineIdentityV3, req);
|
||||
|
||||
// const { permission } = await getAuthDataProjectPermissions({
|
||||
// authData: req.authData,
|
||||
@@ -195,7 +194,7 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
const isActive = true;
|
||||
const serviceTokenData = await new ServiceTokenDataV3({
|
||||
const machineIdentity = await new MachineIdentity({
|
||||
name,
|
||||
user,
|
||||
organization: new Types.ObjectId(organizationId),
|
||||
@@ -209,18 +208,18 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
isRefreshTokenRotationEnabled
|
||||
}).save();
|
||||
|
||||
await new ServiceMembershipOrg({
|
||||
service: serviceTokenData._id,
|
||||
organization: serviceTokenData.organization,
|
||||
await new MachineMembershipOrg({
|
||||
machineIdentity: machineIdentity._id,
|
||||
organization: machineIdentity.organization,
|
||||
role: isCustomRole ? CUSTOM : role,
|
||||
customRole
|
||||
}).save();
|
||||
|
||||
const refreshToken = createToken({
|
||||
payload: {
|
||||
serviceTokenDataId: serviceTokenData._id.toString(),
|
||||
serviceTokenDataId: machineIdentity._id.toString(),
|
||||
authTokenType: AuthTokenType.SERVICE_REFRESH_TOKEN,
|
||||
tokenVersion: serviceTokenData.tokenVersion
|
||||
tokenVersion: machineIdentity.tokenVersion
|
||||
},
|
||||
secret: await getAuthSecret()
|
||||
});
|
||||
@@ -228,12 +227,12 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.CREATE_SERVICE_TOKEN_V3,
|
||||
type: EventType.CREATE_MACHINE_IDENTITY,
|
||||
metadata: {
|
||||
name,
|
||||
isActive,
|
||||
role,
|
||||
trustedIps: reformattedTrustedIps as Array<IServiceTokenV3TrustedIp>,
|
||||
trustedIps: reformattedTrustedIps as Array<IMachineIdentityTrustedIp>,
|
||||
expiresAt
|
||||
}
|
||||
},
|
||||
@@ -243,7 +242,7 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
serviceTokenData,
|
||||
machineIdentity,
|
||||
refreshToken
|
||||
});
|
||||
}
|
||||
@@ -254,22 +253,22 @@ export const createServiceTokenData = async (req: Request, res: Response) => {
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const updateServiceTokenData = async (req: Request, res: Response) => {
|
||||
export const updateMachineIdentity = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { serviceTokenDataId },
|
||||
params: { machineId },
|
||||
body: {
|
||||
name,
|
||||
isActive,
|
||||
role, // bring this somewhere else?
|
||||
role,
|
||||
trustedIps,
|
||||
expiresIn,
|
||||
accessTokenTTL,
|
||||
isRefreshTokenRotationEnabled
|
||||
}
|
||||
} = await validateRequest(reqValidator.UpdateServiceTokenV3, req);
|
||||
} = await validateRequest(reqValidator.UpdateMachineIdentityV3, req);
|
||||
|
||||
let serviceTokenData = await ServiceTokenDataV3.findById(serviceTokenDataId);
|
||||
if (!serviceTokenData) throw ResourceNotFoundError({
|
||||
let machineIdentity = await MachineIdentity.findById(machineId);
|
||||
if (!machineIdentity) throw ResourceNotFoundError({
|
||||
message: "Service token not found"
|
||||
});
|
||||
|
||||
@@ -293,14 +292,14 @@ export const updateServiceTokenData = async (req: Request, res: Response) => {
|
||||
customRole = await Role.findOne({
|
||||
slug: role,
|
||||
isOrgRole: true,
|
||||
organization: serviceTokenData.organization
|
||||
organization: machineIdentity.organization
|
||||
});
|
||||
|
||||
if (!customRole) throw BadRequestError({ message: "Role not found" });
|
||||
}
|
||||
}
|
||||
|
||||
const plan = await EELicenseService.getPlan(serviceTokenData.organization);
|
||||
const plan = await EELicenseService.getPlan(machineIdentity.organization);
|
||||
|
||||
// validate trusted ips
|
||||
let reformattedTrustedIps;
|
||||
@@ -326,12 +325,11 @@ export const updateServiceTokenData = async (req: Request, res: Response) => {
|
||||
expiresAt.setSeconds(expiresAt.getSeconds() + expiresIn);
|
||||
}
|
||||
|
||||
serviceTokenData = await ServiceTokenDataV3.findByIdAndUpdate(
|
||||
serviceTokenDataId,
|
||||
machineIdentity = await MachineIdentity.findByIdAndUpdate(
|
||||
machineId,
|
||||
{
|
||||
name,
|
||||
isActive,
|
||||
|
||||
trustedIps: reformattedTrustedIps,
|
||||
expiresAt,
|
||||
accessTokenTTL,
|
||||
@@ -342,13 +340,13 @@ export const updateServiceTokenData = async (req: Request, res: Response) => {
|
||||
}
|
||||
);
|
||||
|
||||
if (!serviceTokenData) throw BadRequestError({
|
||||
if (!machineIdentity) throw BadRequestError({
|
||||
message: "Failed to update service token"
|
||||
});
|
||||
|
||||
await ServiceMembershipOrg.findOneAndUpdate(
|
||||
await MachineMembershipOrg.findOneAndUpdate(
|
||||
{
|
||||
service: serviceTokenData._id
|
||||
machineIdentity: machineIdentity._id
|
||||
},
|
||||
{
|
||||
role: customRole ? CUSTOM : role,
|
||||
@@ -369,22 +367,22 @@ export const updateServiceTokenData = async (req: Request, res: Response) => {
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.UPDATE_SERVICE_TOKEN_V3,
|
||||
type: EventType.UPDATE_MACHINE_IDENTITY,
|
||||
metadata: {
|
||||
name: serviceTokenData.name,
|
||||
name: machineIdentity.name,
|
||||
isActive,
|
||||
role,
|
||||
trustedIps: reformattedTrustedIps as Array<IServiceTokenV3TrustedIp>,
|
||||
trustedIps: reformattedTrustedIps as Array<IMachineIdentityTrustedIp>,
|
||||
expiresAt
|
||||
}
|
||||
},
|
||||
{
|
||||
organizationId: serviceTokenData.organization
|
||||
organizationId: machineIdentity.organization
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
serviceTokenData
|
||||
machineIdentity
|
||||
});
|
||||
}
|
||||
|
||||
@@ -394,13 +392,13 @@ export const updateServiceTokenData = async (req: Request, res: Response) => {
|
||||
* @param res
|
||||
* @returns
|
||||
*/
|
||||
export const deleteServiceTokenData = async (req: Request, res: Response) => {
|
||||
export const deleteMachineIdentity = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { serviceTokenDataId }
|
||||
} = await validateRequest(reqValidator.DeleteServiceTokenV3, req);
|
||||
params: { machineId }
|
||||
} = await validateRequest(reqValidator.DeleteMachineIdentityV3, req);
|
||||
|
||||
let serviceTokenData = await ServiceTokenDataV3.findById(serviceTokenDataId);
|
||||
if (!serviceTokenData) throw ResourceNotFoundError({
|
||||
let machineIdentity = await MachineIdentity.findById(machineId);
|
||||
if (!machineIdentity) throw ResourceNotFoundError({
|
||||
message: "Service token not found"
|
||||
});
|
||||
|
||||
@@ -414,46 +412,42 @@ export const deleteServiceTokenData = async (req: Request, res: Response) => {
|
||||
// ProjectPermissionSub.ServiceTokens
|
||||
// );
|
||||
|
||||
serviceTokenData = await ServiceTokenDataV3.findByIdAndDelete(serviceTokenDataId);
|
||||
machineIdentity = await MachineIdentity.findByIdAndDelete(machineId);
|
||||
|
||||
if (!serviceTokenData) throw BadRequestError({
|
||||
if (!machineIdentity) throw BadRequestError({
|
||||
message: "Failed to delete service token"
|
||||
});
|
||||
|
||||
const serviceMembershipOrg = await ServiceMembershipOrg.findOneAndDelete({
|
||||
service: serviceTokenData._id,
|
||||
const machineMembershipOrg = await MachineMembershipOrg.findOneAndDelete({
|
||||
machineIdentity: machineIdentity._id,
|
||||
});
|
||||
|
||||
if (!serviceMembershipOrg) throw BadRequestError({
|
||||
if (!machineMembershipOrg) throw BadRequestError({
|
||||
message: "Failed to delete service token"
|
||||
});
|
||||
|
||||
await ServiceTokenDataV3Key.findOneAndDelete({
|
||||
serviceTokenData: serviceTokenData._id
|
||||
});
|
||||
|
||||
await ServiceMembership.deleteMany({
|
||||
service: serviceTokenData._id,
|
||||
await MachineMembership.deleteMany({
|
||||
machineIdentity: machineIdentity._id,
|
||||
});
|
||||
|
||||
await EEAuditLogService.createAuditLog(
|
||||
req.authData,
|
||||
{
|
||||
type: EventType.DELETE_SERVICE_TOKEN_V3,
|
||||
type: EventType.DELETE_MACHINE_IDENTITY,
|
||||
metadata: {
|
||||
name: serviceTokenData.name,
|
||||
isActive: serviceTokenData.isActive,
|
||||
role: serviceMembershipOrg.role,
|
||||
trustedIps: serviceTokenData.trustedIps as Array<IServiceTokenV3TrustedIp>,
|
||||
expiresAt: serviceTokenData.expiresAt
|
||||
name: machineIdentity.name,
|
||||
isActive: machineIdentity.isActive,
|
||||
role: machineMembershipOrg.role,
|
||||
trustedIps: machineIdentity.trustedIps as Array<IMachineIdentityTrustedIp>,
|
||||
expiresAt: machineIdentity.expiresAt
|
||||
}
|
||||
},
|
||||
{
|
||||
organizationId: serviceTokenData.organization
|
||||
organizationId: machineIdentity.organization
|
||||
}
|
||||
);
|
||||
|
||||
return res.status(200).send({
|
||||
serviceTokenData
|
||||
machineIdentity
|
||||
});
|
||||
}
|
||||
@@ -32,9 +32,9 @@ export enum EventType {
|
||||
DELETE_TRUSTED_IP = "delete-trusted-ip",
|
||||
CREATE_SERVICE_TOKEN = "create-service-token", // v2
|
||||
DELETE_SERVICE_TOKEN = "delete-service-token", // v2
|
||||
CREATE_SERVICE_TOKEN_V3 = "create-service-token-v3", // v3
|
||||
UPDATE_SERVICE_TOKEN_V3 = "update-service-token-v3", // v3
|
||||
DELETE_SERVICE_TOKEN_V3 = "delete-service-token-v3", // v3
|
||||
CREATE_MACHINE_IDENTITY = "create-machine-identity",
|
||||
UPDATE_MACHINE_IDENTITY = "update-machine-identity",
|
||||
DELETE_MACHINE_IDENTITY = "delete-machine-identity",
|
||||
CREATE_ENVIRONMENT = "create-environment",
|
||||
UPDATE_ENVIRONMENT = "update-environment",
|
||||
DELETE_ENVIRONMENT = "delete-environment",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ActorType, EventType } from "./enums";
|
||||
import { IServiceTokenV3TrustedIp } from "../../../models/serviceTokenDataV3";
|
||||
import { IMachineIdentityTrustedIp } from "../../../models/machineIdentity";
|
||||
|
||||
interface UserActorMetadata {
|
||||
userId: string;
|
||||
@@ -220,36 +220,36 @@ interface DeleteServiceTokenEvent {
|
||||
};
|
||||
}
|
||||
|
||||
interface CreateServiceTokenV3Event {
|
||||
type: EventType.CREATE_SERVICE_TOKEN_V3;
|
||||
interface CreateMachineIdentityEvent {
|
||||
type: EventType.CREATE_MACHINE_IDENTITY;
|
||||
metadata: {
|
||||
name: string;
|
||||
isActive: boolean;
|
||||
role: string;
|
||||
trustedIps: Array<IServiceTokenV3TrustedIp>;
|
||||
trustedIps: Array<IMachineIdentityTrustedIp>;
|
||||
expiresAt?: Date;
|
||||
};
|
||||
}
|
||||
|
||||
interface UpdateServiceTokenV3Event {
|
||||
type: EventType.UPDATE_SERVICE_TOKEN_V3;
|
||||
interface UpdateMachineIdentityEvent {
|
||||
type: EventType.UPDATE_MACHINE_IDENTITY;
|
||||
metadata: {
|
||||
name?: string;
|
||||
isActive?: boolean;
|
||||
role?: string;
|
||||
trustedIps?: Array<IServiceTokenV3TrustedIp>;
|
||||
trustedIps?: Array<IMachineIdentityTrustedIp>;
|
||||
expiresAt?: Date;
|
||||
};
|
||||
}
|
||||
|
||||
interface DeleteServiceTokenV3Event {
|
||||
type: EventType.DELETE_SERVICE_TOKEN_V3;
|
||||
interface DeleteMachineIdentityEvent {
|
||||
type: EventType.DELETE_MACHINE_IDENTITY;
|
||||
metadata: {
|
||||
name: string;
|
||||
isActive: boolean;
|
||||
role: string;
|
||||
expiresAt?: Date;
|
||||
trustedIps: Array<IServiceTokenV3TrustedIp>;
|
||||
trustedIps: Array<IMachineIdentityTrustedIp>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -495,9 +495,9 @@ export type Event =
|
||||
| DeleteTrustedIPEvent
|
||||
| CreateServiceTokenEvent
|
||||
| DeleteServiceTokenEvent
|
||||
| CreateServiceTokenV3Event
|
||||
| UpdateServiceTokenV3Event
|
||||
| DeleteServiceTokenV3Event
|
||||
| CreateMachineIdentityEvent
|
||||
| UpdateMachineIdentityEvent
|
||||
| DeleteMachineIdentityEvent
|
||||
| CreateEnvironmentEvent
|
||||
| UpdateEnvironmentEvent
|
||||
| DeleteEnvironmentEvent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import serviceTokenData from "./serviceTokenData";
|
||||
import machineIdentity from "./machineIdentity";
|
||||
import apiKeyData from "./apiKeyData";
|
||||
|
||||
export {
|
||||
serviceTokenData,
|
||||
machineIdentity,
|
||||
apiKeyData
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import { requireAuth } from "../../../middleware";
|
||||
import { AuthMode } from "../../../variables";
|
||||
import { machineIdentityController } from "../../controllers/v3";
|
||||
|
||||
router.post(
|
||||
"/me/token",
|
||||
machineIdentityController.refreshToken
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
machineIdentityController.createMachineIdentity
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/:machineId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
machineIdentityController.updateMachineIdentity
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:machineId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
machineIdentityController.deleteMachineIdentity
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -1,36 +0,0 @@
|
||||
import express from "express";
|
||||
const router = express.Router();
|
||||
import { requireAuth } from "../../../middleware";
|
||||
import { AuthMode } from "../../../variables";
|
||||
import { serviceTokenDataController } from "../../controllers/v3";
|
||||
|
||||
router.post(
|
||||
"/me/token",
|
||||
serviceTokenDataController.refreshToken
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
serviceTokenDataController.createServiceTokenData
|
||||
);
|
||||
|
||||
router.patch(
|
||||
"/:serviceTokenDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
serviceTokenDataController.updateServiceTokenData
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:serviceTokenDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
serviceTokenDataController.deleteServiceTokenData
|
||||
);
|
||||
|
||||
export default router;
|
||||
@@ -13,9 +13,9 @@ import picomatch from "picomatch";
|
||||
import { AuthData } from "../../interfaces/middleware";
|
||||
import { ActorType, IRole } from "../models";
|
||||
import {
|
||||
IServiceTokenDataV3,
|
||||
Membership,
|
||||
ServiceMembership,
|
||||
IMachineIdentity,
|
||||
MachineMembership,
|
||||
Membership,
|
||||
ServiceTokenData
|
||||
} from "../../models";
|
||||
import { ADMIN, CUSTOM, MEMBER, VIEWER } from "../../variables";
|
||||
@@ -290,13 +290,13 @@ export const getAuthDataProjectPermissions = async ({
|
||||
break;
|
||||
}
|
||||
case ActorType.SERVICE_V3: {
|
||||
const serviceMembership = await ServiceMembership.findOne({
|
||||
service: authData.authPayload._id,
|
||||
const serviceMembership = await MachineMembership.findOne({
|
||||
machineIdentity: authData.authPayload._id,
|
||||
workspace: workspaceId
|
||||
})
|
||||
.populate<{
|
||||
customRole: IRole & { permissions: RawRuleOf<MongoAbility<ProjectPermissionSet>>[] };
|
||||
service: IServiceTokenDataV3
|
||||
machineIdentity: IMachineIdentity
|
||||
}>("customRole service")
|
||||
.exec();
|
||||
|
||||
@@ -306,7 +306,7 @@ export const getAuthDataProjectPermissions = async ({
|
||||
|
||||
checkIPAgainstBlocklist({
|
||||
ipAddress: authData.ipAddress,
|
||||
trustedIps: serviceMembership.service.trustedIps
|
||||
trustedIps: serviceMembership.machineIdentity.trustedIps
|
||||
});
|
||||
|
||||
role = serviceMembership.role;
|
||||
|
||||
@@ -8,6 +8,9 @@ import {
|
||||
Integration,
|
||||
IntegrationAuth,
|
||||
Key,
|
||||
MachineIdentity,
|
||||
MachineMembership,
|
||||
MachineMembershipOrg,
|
||||
Membership,
|
||||
MembershipOrg,
|
||||
Organization,
|
||||
@@ -16,8 +19,6 @@ import {
|
||||
SecretImport,
|
||||
ServiceToken,
|
||||
ServiceTokenData,
|
||||
ServiceTokenDataV3,
|
||||
ServiceTokenDataV3Key,
|
||||
Tag,
|
||||
Webhook,
|
||||
Workspace
|
||||
@@ -124,6 +125,14 @@ export const deleteOrganization = async ({
|
||||
organization: organization._id
|
||||
});
|
||||
|
||||
await MachineIdentity.deleteMany({
|
||||
organization: organization._id
|
||||
});
|
||||
|
||||
await MachineMembershipOrg.deleteMany({
|
||||
organization: organization._id
|
||||
});
|
||||
|
||||
await BotOrg.deleteMany({
|
||||
organization: organization._id
|
||||
});
|
||||
@@ -268,13 +277,7 @@ export const deleteOrganization = async ({
|
||||
}
|
||||
});
|
||||
|
||||
await ServiceTokenDataV3.deleteMany({
|
||||
workspace: {
|
||||
$in: workspaceIds
|
||||
}
|
||||
});
|
||||
|
||||
await ServiceTokenDataV3Key.deleteMany({
|
||||
await MachineMembership.deleteMany({
|
||||
workspace: {
|
||||
$in: workspaceIds
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ import {
|
||||
Integration,
|
||||
IntegrationAuth,
|
||||
Key,
|
||||
MachineMembership,
|
||||
Membership,
|
||||
Secret,
|
||||
SecretBlindIndexData,
|
||||
SecretImport,
|
||||
ServiceToken,
|
||||
ServiceTokenData,
|
||||
ServiceTokenDataV3,
|
||||
ServiceTokenDataV3Key,
|
||||
Tag,
|
||||
Webhook,
|
||||
Workspace
|
||||
@@ -178,12 +177,8 @@ export const deleteWorkspace = async ({
|
||||
await ServiceTokenData.deleteMany({
|
||||
workspace: workspace._id
|
||||
});
|
||||
|
||||
await ServiceTokenDataV3.deleteMany({
|
||||
workspace: workspace._id
|
||||
});
|
||||
|
||||
await ServiceTokenDataV3Key.deleteMany({
|
||||
|
||||
await MachineMembership.deleteMany({
|
||||
workspace: workspace._id
|
||||
});
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
secretScanning as v1SecretScanningRouter
|
||||
} from "./ee/routes/v1";
|
||||
import { apiKeyData as v3apiKeyDataRouter } from "./ee/routes/v3";
|
||||
import { serviceTokenData as v3ServiceTokenDataRouter } from "./ee/routes/v3";
|
||||
import { machineIdentity as v3MachineIdentityRouter } from "./ee/routes/v3";
|
||||
import {
|
||||
admin as v1AdminRouter,
|
||||
auth as v1AuthRouter,
|
||||
@@ -205,8 +205,8 @@ const main = async () => {
|
||||
app.use("/api/v1/organizations", eeOrganizationsRouter);
|
||||
app.use("/api/v1/sso", eeSSORouter);
|
||||
app.use("/api/v1/cloud-products", eeCloudProductsRouter);
|
||||
app.use("/api/v3/api-key", v3apiKeyDataRouter); // new
|
||||
app.use("/api/v3/service-token", v3ServiceTokenDataRouter); // new
|
||||
app.use("/api/v3/api-key", v3apiKeyDataRouter);
|
||||
app.use("/api/v3/machines", v3MachineIdentityRouter);
|
||||
app.use("/api/v1/secret-rotation-providers", v1SecretRotationProviderRouter);
|
||||
app.use("/api/v1/secret-rotations", v1SecretRotation);
|
||||
|
||||
@@ -220,7 +220,7 @@ const main = async () => {
|
||||
app.use("/api/v1/organization", v1OrganizationRouter);
|
||||
app.use("/api/v1/workspace", v1WorkspaceRouter);
|
||||
app.use("/api/v1/membership-org", v1MembershipOrgRouter);
|
||||
app.use("/api/v1/membership", v1MembershipRouter); //
|
||||
app.use("/api/v1/membership", v1MembershipRouter);
|
||||
app.use("/api/v1/key", v1KeyRouter);
|
||||
app.use("/api/v1/invite-org", v1InviteOrgRouter);
|
||||
app.use("/api/v1/secret", v1SecretRouter); // deprecate
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Types } from "mongoose";
|
||||
import { IServiceTokenData, IServiceTokenDataV3, IUser } from "../../models";
|
||||
import { IMachineIdentity, IServiceTokenData, IUser } from "../../models";
|
||||
import { ServiceActor, ServiceActorV3, UserActor, UserAgentType } from "../../ee/models";
|
||||
|
||||
interface BaseAuthData {
|
||||
@@ -14,9 +14,9 @@ export interface UserAuthData extends BaseAuthData {
|
||||
authPayload: IUser;
|
||||
}
|
||||
|
||||
export interface ServiceTokenV3AuthData extends BaseAuthData {
|
||||
export interface MachineIdentityAuthData extends BaseAuthData {
|
||||
actor: ServiceActorV3;
|
||||
authPayload: IServiceTokenDataV3;
|
||||
authPayload: IMachineIdentity;
|
||||
}
|
||||
|
||||
export interface ServiceTokenAuthData extends BaseAuthData {
|
||||
@@ -24,4 +24,4 @@ export interface ServiceTokenAuthData extends BaseAuthData {
|
||||
authPayload: IServiceTokenData;
|
||||
}
|
||||
|
||||
export type AuthData = UserAuthData | ServiceTokenV3AuthData | ServiceTokenAuthData;
|
||||
export type AuthData = UserAuthData | MachineIdentityAuthData | ServiceTokenAuthData;
|
||||
|
||||
@@ -20,10 +20,9 @@ export * from "./user";
|
||||
export * from "./userAction";
|
||||
export * from "./workspace";
|
||||
export * from "./serviceTokenData"; // TODO: deprecate
|
||||
export * from "./serviceTokenDataV3";
|
||||
export * from "./serviceMembershipOrg";
|
||||
export * from "./serviceMembership";
|
||||
export * from "./serviceTokenDataV3Key"; /// TODO: remove
|
||||
export * from "./machineIdentity";
|
||||
export * from "./machineMembershipOrg";
|
||||
export * from "./machineMembership";
|
||||
export * from "./apiKeyData"; // TODO: deprecate
|
||||
export * from "./apiKeyDataV2";
|
||||
export * from "./loginSRPDetail";
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Document, Schema, Types, model } from "mongoose";
|
||||
import { IPType } from "../ee/models";
|
||||
|
||||
export interface IServiceTokenV3TrustedIp {
|
||||
export interface IMachineIdentityTrustedIp {
|
||||
ipAddress: string;
|
||||
type: IPType;
|
||||
prefix: number;
|
||||
}
|
||||
|
||||
export interface IServiceTokenDataV3 extends Document {
|
||||
export interface IMachineIdentity extends Document {
|
||||
_id: Types.ObjectId;
|
||||
name: string;
|
||||
organization: Types.ObjectId;
|
||||
@@ -21,10 +21,10 @@ export interface IServiceTokenDataV3 extends Document {
|
||||
isRefreshTokenRotationEnabled: boolean;
|
||||
expiresAt?: Date;
|
||||
accessTokenTTL: number;
|
||||
trustedIps: Array<IServiceTokenV3TrustedIp>;
|
||||
trustedIps: Array<IMachineIdentityTrustedIp>;
|
||||
}
|
||||
|
||||
const serviceTokenDataV3Schema = new Schema(
|
||||
const machineIdentitySchema = new Schema(
|
||||
{
|
||||
name: {
|
||||
type: String,
|
||||
@@ -117,4 +117,4 @@ const serviceTokenDataV3Schema = new Schema(
|
||||
}
|
||||
);
|
||||
|
||||
export const ServiceTokenDataV3 = model<IServiceTokenDataV3>("ServiceTokenDataV3", serviceTokenDataV3Schema);
|
||||
export const MachineIdentity = model<IMachineIdentity>("MachineIdentity", machineIdentitySchema);
|
||||
@@ -1,19 +1,19 @@
|
||||
import { Schema, Types, model } from "mongoose";
|
||||
import { ADMIN, CUSTOM, MEMBER, VIEWER } from "../variables";
|
||||
|
||||
export interface IServiceMembership {
|
||||
export interface IMachineMembership {
|
||||
_id: Types.ObjectId;
|
||||
service: Types.ObjectId;
|
||||
machineIdentity: Types.ObjectId;
|
||||
workspace: Types.ObjectId;
|
||||
role: "admin" | "member" | "viewer" | "custom";
|
||||
customRole: Types.ObjectId;
|
||||
}
|
||||
|
||||
const serviceMembershipSchema = new Schema<IServiceMembership>(
|
||||
const machineMembershipSchema = new Schema<IMachineMembership>(
|
||||
{
|
||||
service: { // TODO: consider renaming
|
||||
machineIdentity: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "ServiceTokenDataV3"
|
||||
ref: "MachineIdentity"
|
||||
},
|
||||
workspace: {
|
||||
type: Schema.Types.ObjectId,
|
||||
@@ -35,4 +35,4 @@ const serviceMembershipSchema = new Schema<IServiceMembership>(
|
||||
}
|
||||
);
|
||||
|
||||
export const ServiceMembership = model<IServiceMembership>("ServiceMembership", serviceMembershipSchema);
|
||||
export const MachineMembership = model<IMachineMembership>("MachineMembership", machineMembershipSchema);
|
||||
+6
-6
@@ -1,19 +1,19 @@
|
||||
import { Schema, Types, model } from "mongoose";
|
||||
import { ADMIN, CUSTOM, MEMBER } from "../variables";
|
||||
|
||||
export interface IServiceMembershipOrg {
|
||||
export interface IMachineMembershipOrg {
|
||||
_id: Types.ObjectId;
|
||||
service: Types.ObjectId;
|
||||
machineIdentity: Types.ObjectId;
|
||||
organization: Types.ObjectId;
|
||||
role: "admin" | "member" | "viewer" | "custom";
|
||||
customRole: Types.ObjectId;
|
||||
}
|
||||
|
||||
const serviceMembershipOrgSchema = new Schema<IServiceMembershipOrg>(
|
||||
const machineMembershipOrgSchema = new Schema<IMachineMembershipOrg>(
|
||||
{
|
||||
service: { // TODO: consider renaming
|
||||
machineIdentity: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "ServiceTokenDataV3"
|
||||
ref: "MachineIdentity"
|
||||
},
|
||||
organization: {
|
||||
type: Schema.Types.ObjectId,
|
||||
@@ -34,4 +34,4 @@ const serviceMembershipOrgSchema = new Schema<IServiceMembershipOrg>(
|
||||
}
|
||||
);
|
||||
|
||||
export const ServiceMembershipOrg = model<IServiceMembershipOrg>("ServiceMembershipOrg", serviceMembershipOrgSchema);
|
||||
export const MachineMembershipOrg = model<IMachineMembershipOrg>("MachineMembershipOrg", machineMembershipOrgSchema);
|
||||
@@ -1,43 +0,0 @@
|
||||
import { Document, Schema, Types, model } from "mongoose";
|
||||
|
||||
export interface IServiceTokenDataV3Key extends Document {
|
||||
_id: Types.ObjectId;
|
||||
encryptedKey: string;
|
||||
nonce: string;
|
||||
sender: Types.ObjectId;
|
||||
serviceTokenData: Types.ObjectId;
|
||||
workspace: Types.ObjectId;
|
||||
}
|
||||
|
||||
const serviceTokenDataV3KeySchema = new Schema(
|
||||
{
|
||||
encryptedKey: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
nonce: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
sender: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "User",
|
||||
required: true
|
||||
},
|
||||
serviceTokenData: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "ServiceTokenDataV3",
|
||||
required: true,
|
||||
},
|
||||
workspace: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: "Workspace",
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
{
|
||||
timestamps: true
|
||||
}
|
||||
);
|
||||
|
||||
export const ServiceTokenDataV3Key = model<IServiceTokenDataV3Key>("ServiceTokenDataV3Key", serviceTokenDataV3KeySchema);
|
||||
@@ -55,11 +55,11 @@ router.delete(
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:organizationId/service-memberships",
|
||||
"/:organizationId/machine-memberships",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
organizationsController.getOrganizationServiceMemberships
|
||||
organizationsController.getOrganizationMachineMemberships
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
import { AuthMode } from "../../variables";
|
||||
import { serviceTokenDataController } from "../../controllers/v2";
|
||||
|
||||
router.get( // TODO: deprecate (moving to ST V3)
|
||||
router.get( // TODO: deprecate (moving to machine identity)
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.SERVICE_TOKEN]
|
||||
@@ -14,7 +14,7 @@ router.get( // TODO: deprecate (moving to ST V3)
|
||||
serviceTokenDataController.getServiceTokenData
|
||||
);
|
||||
|
||||
router.post( // TODO: deprecate (moving to ST V3)
|
||||
router.post( // TODO: deprecate (moving to machine identity)
|
||||
"/",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
@@ -22,7 +22,7 @@ router.post( // TODO: deprecate (moving to ST V3)
|
||||
serviceTokenDataController.createServiceTokenData
|
||||
);
|
||||
|
||||
router.delete( // TODO: deprecate (moving to ST V3)
|
||||
router.delete( // TODO: deprecate (moving to machine identity)
|
||||
"/:serviceTokenDataId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
|
||||
@@ -93,29 +93,28 @@ router.patch(
|
||||
workspaceController.toggleAutoCapitalization
|
||||
);
|
||||
|
||||
// TODO: consider endpoint restructuring
|
||||
router.post(
|
||||
"/:workspaceId/service-memberships",
|
||||
"/:workspaceId/machine-memberships/:machineId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||
}),
|
||||
workspaceController.addWorkspaceServiceMembership
|
||||
workspaceController.addMachineToWorkspace
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/:workspaceId/service-memberships/:serviceId",
|
||||
"/:workspaceId/machine-memberships/:machineId",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.API_KEY]
|
||||
}),
|
||||
workspaceController.deleteWorkspaceServiceMembership
|
||||
workspaceController.deleteMachineFromWorkspace
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:workspaceId/service-memberships",
|
||||
"/:workspaceId/machine-memberships",
|
||||
requireAuth({
|
||||
acceptedAuthModes: [AuthMode.JWT]
|
||||
}),
|
||||
workspaceController.getWorkspaceServiceMemberships
|
||||
workspaceController.getWorkspaceMachineMemberships
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -2,4 +2,4 @@ export * from "./apiKey";
|
||||
export * from "./apiKeyV2";
|
||||
export * from "./jwt";
|
||||
export * from "./serviceTokenV2";
|
||||
export * from "./serviceTokenV3";
|
||||
export * from "./machineIdentity";
|
||||
+13
-13
@@ -1,36 +1,36 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import { Types } from "mongoose";
|
||||
import { ServiceTokenDataV3 } from "../../../models";
|
||||
import { MachineIdentity } from "../../../models";
|
||||
import { getAuthSecret } from "../../../config";
|
||||
import { AuthTokenType } from "../../../variables";
|
||||
import { UnauthorizedRequestError } from "../../errors";
|
||||
|
||||
interface ValidateServiceTokenV3Params {
|
||||
interface ValidateMachineIdentityParams {
|
||||
authTokenValue: string;
|
||||
}
|
||||
|
||||
export const validateServiceTokenV3 = async ({
|
||||
export const validateMachineIdentity = async ({
|
||||
authTokenValue
|
||||
}: ValidateServiceTokenV3Params) => {
|
||||
}: ValidateMachineIdentityParams) => {
|
||||
const decodedToken = <jwt.ServiceRefreshTokenJwtPayload>(
|
||||
jwt.verify(authTokenValue, await getAuthSecret())
|
||||
);
|
||||
|
||||
if (decodedToken.authTokenType !== AuthTokenType.SERVICE_ACCESS_TOKEN) throw UnauthorizedRequestError();
|
||||
|
||||
const serviceTokenData = await ServiceTokenDataV3.findOne({
|
||||
const machineIdentity = await MachineIdentity.findOne({
|
||||
_id: new Types.ObjectId(decodedToken.serviceTokenDataId),
|
||||
isActive: true
|
||||
});
|
||||
|
||||
if (!serviceTokenData) {
|
||||
if (!machineIdentity) {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed to authenticate"
|
||||
});
|
||||
} else if (serviceTokenData?.expiresAt && new Date(serviceTokenData.expiresAt) < new Date()) {
|
||||
} else if (machineIdentity?.expiresAt && new Date(machineIdentity.expiresAt) < new Date()) {
|
||||
// case: service token expired
|
||||
await ServiceTokenDataV3.findByIdAndUpdate(
|
||||
serviceTokenData._id,
|
||||
await MachineIdentity.findByIdAndUpdate(
|
||||
machineIdentity._id,
|
||||
{
|
||||
isActive: false
|
||||
},
|
||||
@@ -42,15 +42,15 @@ export const validateServiceTokenV3 = async ({
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed to authenticate",
|
||||
});
|
||||
} else if (decodedToken.tokenVersion !== serviceTokenData.tokenVersion) {
|
||||
} else if (decodedToken.tokenVersion !== machineIdentity.tokenVersion) {
|
||||
// TODO: raise alarm
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed to authenticate",
|
||||
});
|
||||
}
|
||||
|
||||
await ServiceTokenDataV3.findByIdAndUpdate(
|
||||
serviceTokenData._id,
|
||||
await MachineIdentity.findByIdAndUpdate(
|
||||
machineIdentity._id,
|
||||
{
|
||||
accessTokenLastUsed: new Date(),
|
||||
$inc: { accessTokenUsageCount: 1 }
|
||||
@@ -60,5 +60,5 @@ export const validateServiceTokenV3 = async ({
|
||||
}
|
||||
);
|
||||
|
||||
return serviceTokenData;
|
||||
return machineIdentity;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { AuthData } from "../../../interfaces/middleware";
|
||||
import {
|
||||
MachineIdentity,
|
||||
ServiceTokenData,
|
||||
ServiceTokenDataV3,
|
||||
User
|
||||
} from "../../../models";
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
return { serviceTokenDataId: authData.authPayload._id };
|
||||
}
|
||||
|
||||
if (authData.authPayload instanceof ServiceTokenDataV3) {
|
||||
if (authData.authPayload instanceof MachineIdentity) {
|
||||
return { serviceTokenDataId: authData.authPayload._id };
|
||||
}
|
||||
};
|
||||
@@ -38,7 +38,7 @@ export const getAuthDataPayloadUserObj = (authData: AuthData) => {
|
||||
return { user: authData.authPayload.user };
|
||||
}
|
||||
|
||||
if (authData.authPayload instanceof ServiceTokenDataV3) {
|
||||
if (authData.authPayload instanceof MachineIdentity) {
|
||||
return { user: authData.authPayload.user };
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
validateAPIKey,
|
||||
validateAPIKeyV2,
|
||||
validateJWT,
|
||||
validateServiceTokenV2,
|
||||
validateServiceTokenV3
|
||||
validateMachineIdentity,
|
||||
validateServiceTokenV2
|
||||
} from "../authModeValidators";
|
||||
import { getUserAgentType } from "../../posthog";
|
||||
|
||||
@@ -36,7 +36,7 @@ interface GetAuthDataParams {
|
||||
* - SERVICE_TOKEN
|
||||
* - API_KEY
|
||||
* - JWT
|
||||
* - SERVICE_ACCESS_TOKEN (from ST V3)
|
||||
* - SERVICE_ACCESS_TOKEN (from machine identity)
|
||||
* - API_KEY_V2
|
||||
* @param {Object} params
|
||||
* @param {Object.<string, (string|string[]|undefined)>} params.headers - The HTTP request headers, usually from Express's `req.headers`.
|
||||
@@ -116,7 +116,7 @@ export const getAuthData = async ({
|
||||
}
|
||||
}
|
||||
case AuthMode.SERVICE_ACCESS_TOKEN: {
|
||||
const serviceTokenData = await validateServiceTokenV3({
|
||||
const serviceTokenData = await validateMachineIdentity({
|
||||
authTokenValue
|
||||
});
|
||||
|
||||
|
||||
@@ -8,5 +8,5 @@ export * from "./membershipOrg";
|
||||
export * from "./organization";
|
||||
export * from "./secrets";
|
||||
export * from "./serviceTokenData";
|
||||
export * from "./serviceTokenDataV3";
|
||||
export * from "./machineIdentity";
|
||||
export * from "./apiKeyDataV3";
|
||||
|
||||
+5
-5
@@ -7,7 +7,7 @@ export const RefreshTokenV3 = z.object({
|
||||
})
|
||||
});
|
||||
|
||||
export const CreateServiceTokenV3 = z.object({
|
||||
export const CreateMachineIdentityV3 = z.object({
|
||||
body: z.object({
|
||||
name: z.string().trim(),
|
||||
organizationId: z.string().trim(),
|
||||
@@ -25,9 +25,9 @@ export const CreateServiceTokenV3 = z.object({
|
||||
})
|
||||
});
|
||||
|
||||
export const UpdateServiceTokenV3 = z.object({
|
||||
export const UpdateMachineIdentityV3 = z.object({
|
||||
params: z.object({
|
||||
serviceTokenDataId: z.string()
|
||||
machineId: z.string()
|
||||
}),
|
||||
body: z.object({
|
||||
name: z.string().trim().optional(),
|
||||
@@ -46,8 +46,8 @@ export const UpdateServiceTokenV3 = z.object({
|
||||
}),
|
||||
});
|
||||
|
||||
export const DeleteServiceTokenV3 = z.object({
|
||||
export const DeleteMachineIdentityV3 = z.object({
|
||||
params: z.object({
|
||||
serviceTokenDataId: z.string()
|
||||
machineId: z.string()
|
||||
}),
|
||||
});
|
||||
@@ -216,8 +216,4 @@ export const DeleteOrgv2 = z.object({
|
||||
|
||||
export const GetOrgServiceMembersV2 = z.object({
|
||||
params: z.object({ organizationId: z.string().trim() })
|
||||
});
|
||||
|
||||
export const GetOrgServiceTokenDataV3V2 = z.object({
|
||||
params: z.object({ organizationId: z.string().trim() })
|
||||
});
|
||||
@@ -282,10 +282,10 @@ export const ToggleAutoCapitalizationV2 = z.object({
|
||||
|
||||
export const AddWorkspaceServiceMemberV2 = z.object({
|
||||
params: z.object({
|
||||
workspaceId: z.string().trim()
|
||||
workspaceId: z.string().trim(),
|
||||
machineId: z.string().trim()
|
||||
}),
|
||||
body: z.object({
|
||||
serviceId: z.string().trim(), // TODO: consider renaming
|
||||
role: z.string().trim().min(1).default(MEMBER),
|
||||
})
|
||||
});
|
||||
@@ -293,7 +293,7 @@ export const AddWorkspaceServiceMemberV2 = z.object({
|
||||
export const DeleteWorkspaceServiceMemberV2 = z.object({
|
||||
params: z.object({
|
||||
workspaceId: z.string().trim(),
|
||||
serviceId: z.string().trim()
|
||||
machineId: z.string().trim()
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user