Merge remote-tracking branch 'origin/main' into pki-revamp

This commit is contained in:
Carlos Monastyrski
2025-10-10 19:58:06 -03:00
942 changed files with 16524 additions and 12472 deletions
+30 -18
View File
@@ -5,6 +5,7 @@ import {
IdentitiesSchema,
OrganizationsSchema,
OrgMembershipsSchema,
OrgMembershipStatus,
SuperAdminSchema,
UsersSchema
} from "@app/db/schemas";
@@ -172,7 +173,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
email: true,
id: true,
superAdmin: true
}).array()
}).array(),
total: z.number()
})
}
},
@@ -182,13 +184,11 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
});
},
handler: async (req) => {
const users = await server.services.superAdmin.getUsers({
const result = await server.services.superAdmin.getUsers({
...req.query
});
return {
users
};
return result;
}
});
@@ -230,7 +230,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
createdAt: z.date()
})
.array()
}).array()
}).array(),
total: z.number()
})
}
},
@@ -240,13 +241,11 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
});
},
handler: async (req) => {
const organizations = await server.services.superAdmin.getOrganizations({
const result = await server.services.superAdmin.getOrganizations({
...req.query
});
return {
organizations
};
return result;
}
});
@@ -281,7 +280,10 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
);
return {
organizationMembership
organizationMembership: {
...organizationMembership,
status: organizationMembership?.status || OrgMembershipStatus.Accepted
}
};
}
});
@@ -337,7 +339,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
.extend({
isInstanceAdmin: z.boolean()
})
.array()
.array(),
total: z.number()
})
}
},
@@ -347,13 +350,11 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
});
},
handler: async (req) => {
const identities = await server.services.superAdmin.getIdentities({
const result = await server.services.superAdmin.getIdentities({
...req.query
});
return {
identities
};
return result;
}
});
@@ -895,7 +896,13 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
},
handler: async (req) => {
const organizationMembership = await server.services.superAdmin.resendOrgInvite(req.params, req.permission);
return { organizationMembership };
return {
organizationMembership: {
...organizationMembership,
status: organizationMembership?.status || OrgMembershipStatus.Accepted
}
};
}
});
@@ -925,7 +932,12 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
req.params.organizationId,
req.permission
);
return { organizationMembership };
return {
organizationMembership: {
...organizationMembership,
status: organizationMembership?.status || OrgMembershipStatus.Accepted
}
};
}
});
@@ -1,9 +1,13 @@
import { z } from "zod";
import {
AccessScope,
OrgMembershipRole,
OrgMembershipsSchema,
OrgMembershipStatus,
ProjectMembershipsSchema,
ProjectUserMembershipRolesSchema,
TemporaryPermissionMode,
UserEncryptionKeysSchema,
UsersSchema
} from "@app/db/schemas";
@@ -13,7 +17,6 @@ import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -66,14 +69,23 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const memberships = await server.services.projectMembership.getProjectMemberships({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId
const { data: memberships } = await server.services.membershipUser.listMemberships({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.workspaceId
},
data: {}
});
return { memberships };
return {
memberships: memberships.map((el) => ({
...el,
userId: el.actorUserId as string,
projectId: req.params.workspaceId
}))
};
}
});
@@ -124,15 +136,30 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const membership = await server.services.projectMembership.getProjectMembershipById({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId,
id: req.params.membershipId
const { userId } = await server.services.convertor.userMembershipIdToUserId(
req.params.membershipId,
AccessScope.Project,
req.permission.orgId
);
const membership = await server.services.membershipUser.getMembershipByUserId({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.workspaceId
},
selector: {
userId
}
});
return { membership };
return {
membership: {
...membership,
userId,
projectId: req.params.workspaceId
}
};
}
});
@@ -241,14 +268,22 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
...req.auditLogInfo,
event: {
type: EventType.ADD_BATCH_PROJECT_MEMBER,
metadata: data.map(({ userId }) => ({
userId: userId || "",
metadata: data.map(({ actorUserId }) => ({
userId: actorUserId || "",
email: ""
}))
}
});
return { data, success: true };
return {
data: data.map((el) => ({
...el,
orgId: req.permission.orgId,
role: OrgMembershipRole.Member,
status: el.status || OrgMembershipStatus.Accepted
})),
success: true
};
}
});
@@ -282,7 +317,7 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
z.object({
role: z.string(),
isTemporary: z.literal(true),
temporaryMode: z.nativeEnum(ProjectUserMembershipTemporaryMode),
temporaryMode: z.nativeEnum(TemporaryPermissionMode),
temporaryRange: z.string().refine((val) => ms(val) > 0, "Temporary range must be a positive number"),
temporaryAccessStartTime: z.string().datetime()
})
@@ -300,30 +335,28 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const roles = await server.services.projectMembership.updateProjectMembership({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId,
membershipId: req.params.membershipId,
roles: req.body.roles
const { userId } = await server.services.convertor.userMembershipIdToUserId(
req.params.membershipId,
AccessScope.Project,
req.permission.orgId
);
const { membership } = await server.services.membershipUser.updateMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.workspaceId
},
selector: {
userId
},
data: {
roles: req.body.roles
}
});
// await server.services.auditLog.createAuditLog({
// ...req.auditLogInfo,
// projectId: req.params.workspaceId,
// event: {
// type: EventType.UPDATE_USER_WORKSPACE_ROLE,
// metadata: {
// userId: membership.userId,
// newRole: req.body.role,
// oldRole: membership.role,
// email: ""
// }
// }
// });
return { roles };
return { roles: membership.roles.map((el) => ({ ...el, projectMembershipId: req.params.membershipId })) };
}
});
@@ -352,13 +385,22 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const membership = await server.services.projectMembership.deleteProjectMembership({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.workspaceId,
membershipId: req.params.membershipId
const { userId } = await server.services.convertor.userMembershipIdToUserId(
req.params.membershipId,
AccessScope.Project,
req.permission.orgId
);
const { membership } = await server.services.membershipUser.deleteMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.workspaceId
},
selector: {
userId
}
});
await server.services.auditLog.createAuditLog({
@@ -367,12 +409,19 @@ export const registerDeprecatedProjectMembershipRouter = async (server: FastifyZ
event: {
type: EventType.REMOVE_PROJECT_MEMBER,
metadata: {
userId: membership.userId,
userId: membership.actorUserId as string,
email: ""
}
}
});
return { membership };
return {
membership: {
...membership,
userId,
projectId: req.params.workspaceId
}
};
}
});
};
@@ -1,19 +1,21 @@
import { z } from "zod";
import {
AccessScope,
GroupProjectMembershipsSchema,
GroupsSchema,
ProjectMembershipRole,
ProjectUserMembershipRolesSchema,
TemporaryPermissionMode,
UsersSchema
} from "@app/db/schemas";
import { EFilterReturnedUsers } from "@app/ee/services/group/group-types";
import { ApiDocsTags, GROUPS, PROJECTS } from "@app/lib/api-docs";
import { ms } from "@app/lib/ms";
import { isUuidV4 } from "@app/lib/validator";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
export const registerGroupProjectRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -54,7 +56,7 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
z.object({
role: z.string(),
isTemporary: z.literal(true),
temporaryMode: z.nativeEnum(ProjectUserMembershipTemporaryMode),
temporaryMode: z.nativeEnum(TemporaryPermissionMode),
temporaryRange: z.string().refine((val) => ms(val) > 0, "Temporary range must be a positive number"),
temporaryAccessStartTime: z.string().datetime()
})
@@ -73,17 +75,32 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
}
},
handler: async (req) => {
const groupMembership = await server.services.groupProject.addGroupToProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
roles: req.body.roles || [{ role: req.body.role }],
projectId: req.params.projectId,
groupIdOrName: req.params.groupIdOrName
let groupId = req.params.groupIdOrName;
if (!isUuidV4(req.params.groupIdOrName)) {
const groupDetails = await server.services.convertor.getGroupIdFromName(groupId, req.permission.orgId);
groupId = groupDetails.groupId;
}
const { membership: groupMembership } = await server.services.membershipGroup.createMembership({
permission: req.permission,
data: {
groupId,
roles: req.body.roles || [{ role: req.body.role, isTemporary: false }]
},
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
}
});
return { groupMembership };
return {
groupMembership: {
...groupMembership,
projectId: req.params.projectId,
groupId: groupMembership.actorGroupId as string
}
};
}
});
@@ -115,7 +132,7 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
z.object({
role: z.string(),
isTemporary: z.literal(true),
temporaryMode: z.nativeEnum(ProjectUserMembershipTemporaryMode),
temporaryMode: z.nativeEnum(TemporaryPermissionMode),
temporaryRange: z.string().refine((val) => ms(val) > 0, "Temporary range must be a positive number"),
temporaryAccessStartTime: z.string().datetime()
})
@@ -131,17 +148,22 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
}
},
handler: async (req) => {
const roles = await server.services.groupProject.updateGroupInProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId,
groupId: req.params.groupId,
roles: req.body.roles
const { membership: groupMembership } = await server.services.membershipGroup.updateMembership({
permission: req.permission,
selector: {
groupId: req.params.groupId
},
data: {
roles: req.body.roles
},
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
}
});
return { roles };
return { roles: groupMembership.roles.map((el) => ({ ...el, projectMembershipId: groupMembership.id })) };
}
});
@@ -172,16 +194,25 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
}
},
handler: async (req) => {
const groupMembership = await server.services.groupProject.removeGroupFromProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
groupId: req.params.groupId,
projectId: req.params.projectId
const { membership: groupMembership } = await server.services.membershipGroup.deleteMembership({
permission: req.permission,
selector: {
groupId: req.params.groupId
},
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
}
});
return { groupMembership };
return {
groupMembership: {
...groupMembership,
projectId: req.params.projectId,
groupId: groupMembership.actorGroupId as string
}
};
}
});
@@ -233,15 +264,17 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
}
},
handler: async (req) => {
const groupMemberships = await server.services.groupProject.listGroupsInProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId
const { memberships: groupMemberships } = await server.services.membershipGroup.listMemberships({
permission: req.permission,
data: {},
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
}
});
return { groupMemberships };
return { groupMemberships: groupMemberships.map((el) => ({ ...el, groupId: el.actorGroupId as string })) };
}
});
@@ -292,15 +325,25 @@ export const registerGroupProjectRouter = async (server: FastifyZodProvider) =>
}
},
handler: async (req) => {
const groupMembership = await server.services.groupProject.getGroupInProject({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
...req.params
const { membership: groupMembership } = await server.services.membershipGroup.getMembershipByGroupId({
permission: req.permission,
selector: {
groupId: req.params.groupId
},
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
}
});
return { groupMembership };
return {
groupMembership: {
...groupMembership,
projectId: req.params.projectId,
groupId: groupMembership.actorGroupId as string
}
};
}
});
@@ -78,7 +78,7 @@ export const registerIdentityAliCloudAuthRouter = async (server: FastifyZodProvi
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_ALICLOUD_AUTH,
metadata: {
@@ -45,7 +45,7 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_AWS_AUTH,
metadata: {
@@ -40,7 +40,7 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_AZURE_AUTH,
metadata: {
@@ -40,7 +40,7 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_GCP_AUTH,
metadata: {
@@ -119,7 +119,7 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_JWT_AUTH,
metadata: {
@@ -64,7 +64,7 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_KUBERNETES_AUTH,
metadata: {
@@ -168,7 +168,7 @@ export const registerIdentityLdapAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_LDAP_AUTH,
metadata: {
@@ -57,7 +57,7 @@ export const registerIdentityOciAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_OCI_AUTH,
metadata: {
@@ -67,7 +67,7 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_OIDC_AUTH,
metadata: {
@@ -1,10 +1,12 @@
import { z } from "zod";
import {
AccessScope,
IdentitiesSchema,
IdentityProjectMembershipsSchema,
ProjectMembershipRole,
ProjectUserMembershipRolesSchema
ProjectUserMembershipRolesSchema,
TemporaryPermissionMode
} from "@app/db/schemas";
import { ApiDocsTags, ORGANIZATIONS, PROJECT_IDENTITIES } from "@app/lib/api-docs";
import { BadRequestError } from "@app/lib/errors";
@@ -14,7 +16,6 @@ import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectIdentityOrderBy } from "@app/services/identity-project/identity-project-types";
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
import { SanitizedProjectSchema } from "../sanitizedSchemas";
@@ -56,7 +57,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
role: z.string().describe(PROJECT_IDENTITIES.CREATE_IDENTITY_MEMBERSHIP.roles.role),
isTemporary: z.literal(true).describe(PROJECT_IDENTITIES.CREATE_IDENTITY_MEMBERSHIP.roles.role),
temporaryMode: z
.nativeEnum(ProjectUserMembershipTemporaryMode)
.nativeEnum(TemporaryPermissionMode)
.describe(PROJECT_IDENTITIES.CREATE_IDENTITY_MEMBERSHIP.roles.role),
temporaryRange: z
.string()
@@ -82,16 +83,22 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
const { role, roles } = req.body;
if (!role && !roles) throw new BadRequestError({ message: "You must provide either role or roles field" });
const identityMembership = await server.services.identityProject.createProjectIdentity({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
identityId: req.params.identityId,
projectId: req.params.projectId,
roles: roles || [{ role }]
const { membership } = await server.services.membershipIdentity.createMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
data: {
identityId: req.params.identityId,
roles: roles || [{ role, isTemporary: false }]
}
});
return { identityMembership };
return {
identityMembership: { ...membership, identityId: req.params.identityId, projectId: req.params.projectId }
};
}
});
@@ -130,7 +137,7 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
role: z.string().describe(PROJECT_IDENTITIES.UPDATE_IDENTITY_MEMBERSHIP.roles.role),
isTemporary: z.literal(true).describe(PROJECT_IDENTITIES.UPDATE_IDENTITY_MEMBERSHIP.roles.isTemporary),
temporaryMode: z
.nativeEnum(ProjectUserMembershipTemporaryMode)
.nativeEnum(TemporaryPermissionMode)
.describe(PROJECT_IDENTITIES.UPDATE_IDENTITY_MEMBERSHIP.roles.temporaryMode),
temporaryRange: z
.string()
@@ -153,16 +160,24 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}
},
handler: async (req) => {
const roles = await server.services.identityProject.updateProjectIdentity({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
identityId: req.params.identityId,
projectId: req.params.projectId,
roles: req.body.roles
const { membership } = await server.services.membershipIdentity.updateMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
selector: {
identityId: req.params.identityId
},
data: {
roles: req.body.roles
}
});
return { roles };
return {
roles: membership.roles.map((el) => ({ ...el, projectMembershipId: membership.id }))
};
}
});
@@ -193,15 +208,21 @@ export const registerIdentityProjectRouter = async (server: FastifyZodProvider)
}
},
handler: async (req) => {
const identityMembership = await server.services.identityProject.deleteProjectIdentity({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
identityId: req.params.identityId,
projectId: req.params.projectId
const { membership } = await server.services.membershipIdentity.deleteMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
selector: {
identityId: req.params.identityId
}
});
return { identityMembership };
return {
identityMembership: { ...membership, identityId: req.params.identityId, projectId: req.params.projectId }
};
}
});
@@ -72,7 +72,7 @@ export const registerIdentityTlsCertAuthRouter = async (server: FastifyZodProvid
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_TLS_CERT_AUTH,
metadata: {
@@ -332,7 +332,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.CREATE_TOKEN_IDENTITY_TOKEN_AUTH,
metadata: {
@@ -393,7 +393,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.GET_TOKENS_IDENTITY_TOKEN_AUTH,
metadata: {
@@ -447,7 +447,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.UPDATE_TOKEN_IDENTITY_TOKEN_AUTH,
metadata: {
@@ -59,7 +59,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId,
orgId: identityMembershipOrg.scopeOrgId,
event: {
type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH,
metadata: {
@@ -1,6 +1,6 @@
import { z } from "zod";
import { OrgMembershipRole, ProjectMembershipRole, UsersSchema } from "@app/db/schemas";
import { AccessScope, OrgMembershipRole, UsersSchema } from "@app/db/schemas";
import { inviteUserRateLimit, smtpRateLimit } from "@app/server/config/rateLimiter";
import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -23,13 +23,6 @@ export const registerInviteOrgRouter = async (server: FastifyZodProvider) => {
.array()
.refine((val) => val.every((el) => el === el.toLowerCase()), "Email must be lowercase"),
organizationId: z.string().trim(),
projects: z
.object({
id: z.string(),
projectRoleSlug: z.string().array().default([ProjectMembershipRole.Member])
})
.array()
.optional(),
organizationRoleSlug: z.string().default(OrgMembershipRole.Member)
}),
response: {
@@ -50,15 +43,16 @@ export const registerInviteOrgRouter = async (server: FastifyZodProvider) => {
handler: async (req) => {
if (req.auth.actor !== ActorType.USER) return;
const { signupTokens: completeInviteLinks } = await server.services.org.inviteUserToOrganization({
orgId: req.body.organizationId,
actor: req.permission.type,
actorId: req.permission.id,
inviteeEmails: req.body.inviteeEmails,
projects: req.body.projects,
organizationRoleSlug: req.body.organizationRoleSlug,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
const { signUpTokens: completeInviteLinks } = await server.services.membershipUser.createMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Organization,
orgId: req.permission.orgId
},
data: {
usernames: req.body.inviteeEmails,
roles: [{ isTemporary: false, role: req.body.organizationRoleSlug }]
}
});
await server.services.telemetry.sendPostHogEvents({
@@ -86,7 +86,7 @@ export const registerOrgAdminRouter = async (server: FastifyZodProvider) => {
});
}
return { membership };
return { membership: { ...membership, userId: req.permission.id, projectId: req.params.projectId } };
}
});
};
@@ -6,6 +6,7 @@ import {
GroupsSchema,
IncidentContactsSchema,
OrgMembershipsSchema,
OrgMembershipStatus,
OrgRolesSchema,
UsersSchema
} from "@app/db/schemas";
@@ -263,7 +264,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
req.permission.authMethod,
req.permission.orgId
);
return { users };
return { users: users.map((el) => ({ ...el, status: el.status || OrgMembershipStatus.Accepted })) };
}
});
@@ -1,10 +1,11 @@
import { z } from "zod";
import {
OrgMembershipRole,
AccessScope,
ProjectMembershipRole,
ProjectMembershipsSchema,
ProjectUserMembershipRolesSchema,
TemporaryPermissionMode,
UserEncryptionKeysSchema,
UsersSchema
} from "@app/db/schemas";
@@ -14,7 +15,6 @@ import { ms } from "@app/lib/ms";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { ProjectUserMembershipTemporaryMode } from "@app/services/project-membership/project-membership-types";
export const registerProjectMembershipRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -67,14 +67,23 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const memberships = await server.services.projectMembership.getProjectMemberships({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId
const { data: memberships } = await server.services.membershipUser.listMemberships({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
data: {}
});
return { memberships };
return {
memberships: memberships.map((el) => ({
...el,
userId: el.actorUserId as string,
projectId: req.params.projectId
}))
};
}
});
@@ -125,15 +134,30 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const membership = await server.services.projectMembership.getProjectMembershipById({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId,
id: req.params.membershipId
const { userId } = await server.services.convertor.userMembershipIdToUserId(
req.params.membershipId,
AccessScope.Project,
req.permission.orgId
);
const membership = await server.services.membershipUser.getMembershipByUserId({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
selector: {
userId
}
});
return { membership };
return {
membership: {
...membership,
userId,
projectId: req.params.projectId
}
};
}
});
@@ -242,20 +266,17 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const usernamesAndEmails = [...req.body.emails, ...req.body.usernames];
const { projectMemberships: memberships } = await server.services.org.inviteUserToOrganization({
actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id,
actorOrgId: req.permission.orgId,
actor: req.permission.type,
inviteeEmails: usernamesAndEmails,
orgId: req.permission.orgId,
organizationRoleSlug: OrgMembershipRole.NoAccess,
projects: [
{
id: req.params.projectId,
projectRoleSlug: req.body.roleSlugs || [ProjectMembershipRole.Member]
}
]
const { memberships } = await server.services.membershipUser.createMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
data: {
roles: (req.body.roleSlugs || [ProjectMembershipRole.Member]).map((role) => ({ isTemporary: false, role })),
usernames: usernamesAndEmails
}
});
await server.services.auditLog.createAuditLog({
@@ -263,15 +284,21 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
...req.auditLogInfo,
event: {
type: EventType.ADD_BATCH_PROJECT_MEMBER,
metadata: memberships.map(({ userId, id }) => ({
userId: userId || "",
metadata: memberships.map(({ actorUserId, id }) => ({
userId: actorUserId || "",
membershipId: id,
email: ""
}))
}
});
return { memberships };
return {
memberships: memberships.map((el) => ({
...el,
userId: el.actorUserId as string,
projectId: req.params.projectId
}))
};
}
});
@@ -305,7 +332,7 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
z.object({
role: z.string(),
isTemporary: z.literal(true),
temporaryMode: z.nativeEnum(ProjectUserMembershipTemporaryMode),
temporaryMode: z.nativeEnum(TemporaryPermissionMode),
temporaryRange: z.string().refine((val) => ms(val) > 0, "Temporary range must be a positive number"),
temporaryAccessStartTime: z.string().datetime()
})
@@ -323,17 +350,28 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const roles = await server.services.projectMembership.updateProjectMembership({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId,
membershipId: req.params.membershipId,
roles: req.body.roles
const { userId } = await server.services.convertor.userMembershipIdToUserId(
req.params.membershipId,
AccessScope.Project,
req.permission.orgId
);
const { membership } = await server.services.membershipUser.updateMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
selector: {
userId
},
data: {
roles: req.body.roles
}
});
return { roles };
return { roles: membership.roles.map((el) => ({ ...el, projectMembershipId: req.params.membershipId })) };
}
});
@@ -396,13 +434,19 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
event: {
type: EventType.REMOVE_PROJECT_MEMBER,
metadata: {
userId: membership.userId,
userId: membership.actorUserId as string,
email: ""
}
}
});
}
return { memberships };
return {
memberships: memberships.map((el) => ({
...el,
userId: el.actorUserId as string,
projectId: req.params.projectId
}))
};
}
});
@@ -431,13 +475,22 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const membership = await server.services.projectMembership.deleteProjectMembership({
actorId: req.permission.id,
actor: req.permission.type,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
projectId: req.params.projectId,
membershipId: req.params.membershipId
const { userId } = await server.services.convertor.userMembershipIdToUserId(
req.params.membershipId,
AccessScope.Project,
req.permission.orgId
);
const { membership } = await server.services.membershipUser.deleteMembership({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
orgId: req.permission.orgId,
projectId: req.params.projectId
},
selector: {
userId
}
});
await server.services.auditLog.createAuditLog({
@@ -446,12 +499,19 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
event: {
type: EventType.REMOVE_PROJECT_MEMBER,
metadata: {
userId: membership.userId,
userId: membership.actorUserId as string,
email: ""
}
}
});
return { membership };
return {
membership: {
...membership,
userId,
projectId: req.params.projectId
}
};
}
});
@@ -479,7 +539,13 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
actor: req.permission.type,
projectId: req.params.projectId
});
return { membership };
return {
membership: {
...membership,
userId: membership.actorUserId as string,
projectId: req.params.projectId
}
};
}
});
};