Added new metadata parameter for signup

This commit is contained in:
Daniel Hougaard
2024-08-22 08:13:29 +04:00
parent 59b16f647e
commit 121b642d50
4 changed files with 69 additions and 8 deletions

View File

@@ -179,7 +179,8 @@ export const registerSignupRouter = async (server: FastifyZodProvider) => {
encryptedPrivateKeyIV: z.string().trim(),
encryptedPrivateKeyTag: z.string().trim(),
salt: z.string().trim(),
verifier: z.string().trim()
verifier: z.string().trim(),
metadata: z.string().optional()
}),
response: {
200: z.object({

View File

@@ -49,3 +49,14 @@ export type TIssueAuthTokenDTO = {
ip: string;
userAgent: string;
};
export enum TokenMetadataType {
InviteToProjects = "projects-invite"
}
// TODO: Split the payloads into separate types for better type inference (not needed until we add more types of metadata)
export type TTokenMetadata = {
type: TokenMetadataType.InviteToProjects;
projectIds: string[];
userId: string;
};

View File

@@ -1,7 +1,7 @@
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { OrgMembershipStatus, TableName } from "@app/db/schemas";
import { OrgMembershipStatus, ProjectMembershipRole, TableName } from "@app/db/schemas";
import { convertPendingGroupAdditionsToGroupMemberships } from "@app/ee/services/group/group-fns";
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
@@ -9,7 +9,7 @@ import { isAuthMethodSaml } from "@app/ee/services/permission/permission-fns";
import { getConfig } from "@app/lib/config/env";
import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
import { getUserPrivateKey } from "@app/lib/crypto/srp";
import { BadRequestError } from "@app/lib/errors";
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { isDisposableEmail } from "@app/lib/validator";
import { TGroupProjectDALFactory } from "@app/services/group-project/group-project-dal";
import { TProjectDALFactory } from "@app/services/project/project-dal";
@@ -17,9 +17,12 @@ import { TProjectBotDALFactory } from "@app/services/project-bot/project-bot-dal
import { TProjectKeyDALFactory } from "@app/services/project-key/project-key-dal";
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
import { TokenType } from "../auth-token/auth-token-types";
import { TokenType, TTokenMetadata } from "../auth-token/auth-token-types";
import { TOrgDALFactory } from "../org/org-dal";
import { TOrgServiceFactory } from "../org/org-service";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { addMembersToProject } from "../project-membership/project-membership-fns";
import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal";
import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service";
import { TUserDALFactory } from "../user/user-dal";
import { TAuthDALFactory } from "./auth-dal";
@@ -32,10 +35,14 @@ type TAuthSignupDep = {
userDAL: TUserDALFactory;
userGroupMembershipDAL: Pick<
TUserGroupMembershipDALFactory,
"find" | "transaction" | "insertMany" | "deletePendingUserGroupMembershipsByUserIds"
| "find"
| "transaction"
| "insertMany"
| "deletePendingUserGroupMembershipsByUserIds"
| "findUserGroupMembershipsInProject"
>;
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "findLatestProjectKey" | "insertMany">;
projectDAL: Pick<TProjectDALFactory, "findProjectGhostUser">;
projectDAL: Pick<TProjectDALFactory, "findProjectGhostUser" | "findProjectById">;
projectBotDAL: Pick<TProjectBotDALFactory, "findOne">;
groupProjectDAL: Pick<TGroupProjectDALFactory, "find">;
orgService: Pick<TOrgServiceFactory, "createOrganization">;
@@ -43,6 +50,8 @@ type TAuthSignupDep = {
tokenService: TAuthTokenServiceFactory;
smtpService: TSmtpService;
licenseService: Pick<TLicenseServiceFactory, "updateSubscriptionOrgMemberCount">;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "find" | "transaction" | "insertMany">;
projectUserMembershipRoleDAL: Pick<TProjectUserMembershipRoleDALFactory, "insertMany">;
};
export type TAuthSignupFactory = ReturnType<typeof authSignupServiceFactory>;
@@ -58,6 +67,8 @@ export const authSignupServiceFactory = ({
smtpService,
orgService,
orgDAL,
projectMembershipDAL,
projectUserMembershipRoleDAL,
licenseService
}: TAuthSignupDep) => {
// first step of signup. create user and send email
@@ -301,7 +312,8 @@ export const authSignupServiceFactory = ({
encryptedPrivateKey,
encryptedPrivateKeyIV,
encryptedPrivateKeyTag,
authorization
authorization,
metadata
}: TCompleteAccountInviteDTO) => {
const user = await userDAL.findUserByUsername(email);
if (!user || (user && user.isAccepted)) {
@@ -358,6 +370,38 @@ export const authSignupServiceFactory = ({
tx
);
if (metadata) {
const metadataObj = jwt.verify(metadata, appCfg.AUTH_SECRET) as TTokenMetadata;
if (user.id !== metadataObj.userId) {
throw new UnauthorizedError({
message: "Malformed or invalid metadata token"
});
}
for await (const projectId of metadataObj.projectIds) {
await addMembersToProject({
orgDAL,
projectDAL,
projectMembershipDAL,
projectKeyDAL,
userGroupMembershipDAL,
projectBotDAL,
projectUserMembershipRoleDAL,
smtpService
}).addMembersToNonE2EEProject(
{
emails: [user.email!],
usernames: [],
projectId,
projectMembershipRole: ProjectMembershipRole.Member,
sendEmails: false
},
tx
);
}
}
const updatedMembersips = await orgDAL.updateMembership(
{ inviteEmail: email, status: OrgMembershipStatus.Invited },
{ userId: us.id, status: OrgMembershipStatus.Accepted },

View File

@@ -64,6 +64,10 @@ export default function SignupInvite() {
const email = (parsedUrl.to as string)?.replace(" ", "+").trim();
const { config } = useServerConfig();
const queryParams = new URLSearchParams(window.location.search);
const metadata = queryParams.get("metadata") || undefined;
const { mutateAsync: selectOrganization } = useSelectOrganization();
useEffect(() => {
@@ -160,7 +164,8 @@ export default function SignupInvite() {
encryptedPrivateKeyIV,
encryptedPrivateKeyTag,
salt: result.salt,
verifier: result.verifier
verifier: result.verifier,
metadata
});
// unset temporary signup JWT token and set JWT token