uberf-8425: improve account methods params checks (#9278)

Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
This commit is contained in:
Alexey Zinoviev
2025-06-17 23:45:58 +07:00
committed by GitHub
parent feafc9a092
commit 2d009aaeea
5 changed files with 247 additions and 30 deletions
+1 -1
View File
@@ -369,7 +369,7 @@ class AccountClientImpl implements AccountClient {
async resendInvite (email: string, role: AccountRole): Promise<void> {
const request = {
method: 'resendInvite' as const,
params: [email, role]
params: { email, role }
}
await this.rpc(request)
@@ -424,7 +424,7 @@ describe('invite operations', () => {
;(mockDb.invite.findOne as jest.Mock).mockResolvedValue(existingInvite)
global.fetch = jest.fn().mockResolvedValue({ ok: true })
await resendInvite(mockCtx, mockDb, mockBranding, mockToken, mockEmail, AccountRole.User)
await resendInvite(mockCtx, mockDb, mockBranding, mockToken, { email: mockEmail, role: AccountRole.User })
expect(mockDb.invite.updateOne).toHaveBeenCalledWith(
{ id: existingInvite.id },
@@ -446,7 +446,7 @@ describe('invite operations', () => {
;(mockDb.invite.insertOne as jest.Mock).mockResolvedValue(newInviteId)
global.fetch = jest.fn().mockResolvedValue({ ok: true })
await resendInvite(mockCtx, mockDb, mockBranding, mockToken, mockEmail, AccountRole.User)
await resendInvite(mockCtx, mockDb, mockBranding, mockToken, { email: mockEmail, role: AccountRole.User })
expect(mockDb.invite.insertOne).toHaveBeenCalled()
expect(global.fetch).toHaveBeenCalled()
+155 -18
View File
@@ -98,7 +98,8 @@ import {
wrap,
updateAllowReadOnlyGuests,
READONLY_GUEST_ACCOUNT,
getWorkspaceByDataId
getWorkspaceByDataId,
assignableRoles
} from './utils'
// Note: it is IMPORTANT to always destructure params passed here to avoid sending extra params
@@ -145,6 +146,11 @@ export async function login (
}
): Promise<LoginInfo> {
const { email, password } = params
if (email == null || password == null || email === '' || password === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const normalizedEmail = cleanEmail(email)
try {
@@ -199,6 +205,10 @@ export async function loginOtp (
): Promise<OtpInfo> {
const { email } = params
if (email == null || email === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
// Note: can support OTP based on any other social logins later
const normalizedEmail = cleanEmail(email)
const emailSocialId = await getEmailSocialId(db, normalizedEmail)
@@ -231,12 +241,17 @@ export async function signUp (
email: string
password: string
firstName: string
lastName: string
lastName?: string
},
meta?: Meta
): Promise<LoginInfo> {
const { email, password, firstName, lastName } = params
const { account, socialId } = await signUpByEmail(ctx, db, branding, email, password, firstName, lastName)
if (email == null || password == null || firstName == null || email === '' || password === '' || firstName === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, socialId } = await signUpByEmail(ctx, db, branding, email, password, firstName, lastName ?? '')
const person = await db.person.findOne({ uuid: account })
if (person == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {}))
@@ -270,10 +285,15 @@ export async function signUpOtp (
params: {
email: string
firstName: string
lastName: string
lastName?: string
}
): Promise<OtpInfo> {
const { email, firstName, lastName } = params
if (email == null || firstName == null || email === '' || firstName === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
// Note: can support OTP based on any other social logins later
const normalizedEmail = cleanEmail(email)
let emailSocialId = await getEmailSocialId(db, normalizedEmail)
@@ -287,12 +307,12 @@ export async function signUpOtp (
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountAlreadyExists, {}))
}
await db.person.updateOne({ uuid: emailSocialId.personUuid }, { firstName, lastName })
await db.person.updateOne({ uuid: emailSocialId.personUuid }, { firstName, lastName: lastName ?? '' })
personUuid = emailSocialId.personUuid
} else {
// There's no person linked to this email, so we need to create a new one
personUuid = await db.person.insertOne({ firstName, lastName })
personUuid = await db.person.insertOne({ firstName, lastName: lastName ?? '' })
const newSocialId = { type: SocialIdType.EMAIL, value: normalizedEmail, personUuid }
const emailSocialIdId = await db.socialId.insertOne(newSocialId)
emailSocialId = { ...newSocialId, _id: emailSocialIdId, key: buildSocialIdString(newSocialId) }
@@ -314,6 +334,10 @@ export async function validateOtp (
): Promise<LoginInfo> {
const { email, code, password } = params
if (email == null || code == null || email === '' || code === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
// Note: can support OTP based on any other social logins later
const normalizedEmail = cleanEmail(email)
try {
@@ -383,6 +407,11 @@ export async function createWorkspace (
}
): Promise<WorkspaceLoginInfo> {
const { workspaceName, region } = params
if (workspaceName == null || workspaceName.length === 0) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account } = decodeTokenVerbose(ctx, token)
checkRateLimit(account, workspaceName)
@@ -448,6 +477,11 @@ export async function createInvite (
}
): Promise<string> {
const { exp, emailMask, email, limit, role, autoJoin } = params
if (role == null || !assignableRoles.includes(role)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, workspace: workspaceUuid, extra } = decodeTokenVerbose(ctx, token)
const currentAccount = await db.account.findOne({ uuid: account })
@@ -501,6 +535,11 @@ export async function sendInvite (
}
): Promise<void> {
const { email, role, expHours } = params
if (email == null || email === '' || role == null || !assignableRoles.includes(role)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, workspace: workspaceUuid, extra } = decodeTokenVerbose(ctx, token)
const currentAccount = await db.account.findOne({ uuid: account })
@@ -540,6 +579,11 @@ export async function createInviteLink (
}
): Promise<string> {
const { email, role, autoJoin, firstName, lastName, navigateUrl, expHours } = params
if (email == null || email === '' || role == null || !assignableRoles.includes(role)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, workspace: workspaceUuid, extra } = decodeTokenVerbose(ctx, token)
const currentAccount = await db.account.findOne({ uuid: account })
@@ -626,10 +670,19 @@ export async function resendInvite (
db: AccountDB,
branding: Branding | null,
token: string,
email: string,
role: AccountRole
params: {
email: string
role: AccountRole
}
): Promise<void> {
const { email, role } = params
if (email == null || email === '' || role == null || !assignableRoles.includes(role)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, workspace: workspaceUuid, extra } = decodeTokenVerbose(ctx, token)
const currentAccount = await db.account.findOne({ uuid: account })
if (currentAccount == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, { account }))
@@ -687,6 +740,11 @@ export async function join (
meta?: Meta
): Promise<WorkspaceLoginInfo | LoginInfo> {
const { email, password, inviteId } = params
if (email == null || email === '' || password == null || password === '' || inviteId == null || inviteId === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const normalizedEmail = cleanEmail(email)
const invite = await getWorkspaceInvite(db, inviteId)
if (invite == null) {
@@ -726,6 +784,10 @@ export async function checkJoin (
): Promise<WorkspaceLoginInfo> {
const { inviteId } = params
if (inviteId == null || inviteId === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const invite = await getWorkspaceInvite(db, inviteId)
if (invite == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
@@ -766,6 +828,11 @@ export async function checkAutoJoin (
params: { inviteId: string, firstName?: string, lastName?: string }
): Promise<WorkspaceLoginInfo | WorkspaceInviteInfo> {
const { inviteId, firstName, lastName } = params
if (inviteId == null || inviteId === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const invite = await getWorkspaceInvite(db, inviteId)
if (invite == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
@@ -878,12 +945,26 @@ export async function signUpJoin (
email: string
password: string
first: string
last: string
last?: string
inviteId: string
},
meta?: Meta
): Promise<WorkspaceLoginInfo> {
const { email, password, first, last, inviteId } = params
if (
email == null ||
email === '' ||
password == null ||
password === '' ||
first == null ||
first === '' ||
inviteId == null ||
inviteId === ''
) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const normalizedEmail = cleanEmail(email)
ctx.info('Signing up and joining a workspace using invite', { email, normalizedEmail, first, last, inviteId })
@@ -899,7 +980,7 @@ export async function signUpJoin (
throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUuid }))
}
const { account } = await signUpByEmail(ctx, db, branding, email, password, first, last, true)
const { account } = await signUpByEmail(ctx, db, branding, email, password, first, last ?? '', true)
void setTimezoneIfNotDefined(ctx, db, account, null, meta)
return await doJoinByInvite(ctx, db, branding, generateToken(account, workspaceUuid), account, workspace, invite)
@@ -951,6 +1032,11 @@ export async function changePassword (
}
): Promise<void> {
const { oldPassword, newPassword } = params
if (oldPassword == null || oldPassword === '' || newPassword == null || newPassword === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account: accountUuid } = decodeTokenVerbose(ctx, token)
ctx.info('Changing password', { accountUuid })
@@ -978,6 +1064,11 @@ export async function requestPasswordReset (
params: { email: string }
): Promise<void> {
const { email } = params
if (email == null || email === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const normalizedEmail = cleanEmail(email)
ctx.info('Requesting password reset', { email, normalizedEmail })
@@ -1046,6 +1137,10 @@ export async function restorePassword (
): Promise<LoginInfo> {
const { password } = params
if (password == null || password === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, extra } = decodeTokenVerbose(ctx, token)
ctx.info('Restoring password', { account, extra })
@@ -1081,6 +1176,11 @@ export async function leaveWorkspace (
params: { account: AccountUuid }
): Promise<LoginInfo | null> {
const { account: targetAccount } = params
if (targetAccount == null || targetAccount === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, workspace } = decodeTokenVerbose(ctx, token)
ctx.info('Removing account from workspace', { account, workspace })
@@ -1128,17 +1228,20 @@ export async function changeUsername (
token: string,
params: {
first: string
last: string
last?: string
}
): Promise<void> {
const { first, last } = params
if (first == null || first === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account } = decodeTokenVerbose(ctx, token)
ctx.info('Changing name of person', { account, first, last })
await db.person.updateOne({ uuid: account }, { firstName: first, lastName: last ?? '' })
await db.person.updateOne({ uuid: account }, { firstName: first, lastName: last })
ctx.info('Name changed', { account, first, last })
ctx.info('Person name changed', { account, first, last })
}
export async function updateWorkspaceName (
@@ -1149,6 +1252,11 @@ export async function updateWorkspaceName (
params: { name: string }
): Promise<void> {
const { name } = params
if (name == null || name === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account, workspace } = decodeTokenVerbose(ctx, token)
const role = await db.getWorkspaceRole(account, workspace)
@@ -1224,13 +1332,19 @@ export async function getWorkspacesInfo (
token: string,
params: { ids: WorkspaceUuid[] }
): Promise<WorkspaceInfoWithStatus[]> {
const { account } = decodeTokenVerbose(ctx, token)
const { ids } = params
if (ids == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account } = decodeTokenVerbose(ctx, token)
if (account !== systemAccountUuid) {
ctx.error('getWorkspaceInfos with wrong user', { account, token })
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
}
const workspaces: WorkspaceInfoWithStatus[] = []
for (const id of ids) {
const ws = await getWorkspaceInfoWithStatusById(db, id)
@@ -1547,6 +1661,11 @@ export async function findPersonBySocialKey (
params: { socialString: string, requireAccount?: boolean }
): Promise<PersonUuid | undefined> {
const { socialString } = params
if (socialString == null || socialString === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
decodeTokenVerbose(ctx, token)
const socialId = await db.socialId.findOne({ key: socialString })
@@ -1572,6 +1691,11 @@ export async function findPersonBySocialId (
params: { socialId: PersonId, requireAccount?: boolean }
): Promise<PersonUuid | undefined> {
const { socialId, requireAccount } = params
if (socialId == null || socialId === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
decodeTokenVerbose(ctx, token)
const socialIdObj = await db.socialId.findOne({ _id: socialId })
@@ -1650,8 +1774,12 @@ export async function getAccountInfo (
token: string,
params: { accountId: AccountUuid }
): Promise<AccountInfo> {
decodeTokenVerbose(ctx, token)
const { accountId } = params
if (accountId == null || accountId === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
decodeTokenVerbose(ctx, token)
const account = await getAccount(db, accountId)
if (account === undefined || account === null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, {}))
@@ -1729,8 +1857,13 @@ async function createMailbox (
domain: string
}
): Promise<{ mailbox: string, socialId: PersonId }> {
const { account } = decodeTokenVerbose(ctx, token)
const { name, domain } = params
if (name == null || name === '' || domain == null || domain === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account } = decodeTokenVerbose(ctx, token)
const normalizedName = cleanEmail(name)
const normalizedDomain = cleanEmail(domain)
const mailbox = normalizedName + '@' + normalizedDomain
@@ -1778,6 +1911,10 @@ async function deleteMailbox (
token: string,
params: { mailbox: string }
): Promise<void> {
if (params.mailbox == null || params.mailbox === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { account } = decodeTokenVerbose(ctx, token)
const mailbox = cleanEmail(params.mailbox)
+85 -8
View File
@@ -67,7 +67,8 @@ import {
doReleaseSocialId,
doMergeAccounts,
doMergePersons,
READONLY_GUEST_ACCOUNT
READONLY_GUEST_ACCOUNT,
assignableRoles
} from './utils'
// Note: it is IMPORTANT to always destructure params passed here to avoid sending extra params
@@ -210,6 +211,11 @@ export async function updateWorkspaceRoleBySocialKey (
}
): Promise<void> {
const { socialKey, targetRole } = params
if (socialKey == null || socialKey === '' || targetRole == null || !assignableRoles.includes(targetRole)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const { extra } = decodeTokenVerbose(ctx, token)
verifyAllowedServices(['workspace', 'tool'], extra)
@@ -282,13 +288,18 @@ export async function updateWorkspaceInfo (
}
): Promise<void> {
const { workspaceUuid, event, version, message } = params
let progress = params.progress
const { extra } = decodeTokenVerbose(ctx, token)
if (!['workspace', 'tool'].includes(extra?.service)) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
}
if (workspaceUuid == null || workspaceUuid === '' || event == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
let progress = params.progress
const wsExists = await db.workspace.exists({ uuid: workspaceUuid })
if (!wsExists) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.WorkspaceNotFound, { workspaceUuid }))
@@ -476,6 +487,17 @@ export async function assignWorkspace (
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
}
if (
email == null ||
email === '' ||
workspaceUuid == null ||
workspaceUuid === '' ||
role == null ||
!assignableRoles.includes(role)
) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const normalizedEmail = cleanEmail(email)
const emailSocialId = await getEmailSocialId(db, normalizedEmail)
@@ -515,6 +537,10 @@ export async function getPersonInfo (
const { extra } = decodeTokenVerbose(ctx, token)
verifyAllowedServices(['workspace', 'tool'], extra)
if (account == null || account === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const person = await db.person.findOne({ uuid: account })
if (person == null) {
@@ -543,7 +569,7 @@ export async function releaseSocialId (
const { personUuid, type, value } = params
if (personUuid == null || !Object.values(SocialIdType).includes(type) || value == null) {
if (personUuid == null || !Object.values(SocialIdType).includes(type) || value == null || value === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
@@ -562,6 +588,10 @@ export async function addSocialIdToPerson (
verifyAllowedServices(['github', 'telegram-bot', 'gmail', 'tool', 'workspace', 'hulygram'], extra)
if (person == null || person === '' || !Object.values(SocialIdType).includes(type) || value == null || value === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
return await addSocialId(db, person, type, value, confirmed, displayValue)
}
@@ -577,6 +607,10 @@ export async function updateSocialId (
verifyAllowedServices(['telegram-bot', 'gmail'], extra)
if (personId == null || personId === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const socialId = await db.socialId.findOne({ _id: personId })
if (socialId != null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.SocialIdNotFound, { _id: personId }))
@@ -593,6 +627,7 @@ export async function createIntegration (
params: Integration
): Promise<void> {
const { extra, account } = decodeTokenVerbose(ctx, token)
// it checks params and throws BadRequest if params are invalid
const existing = await findExistingIntegration(account, db, params, extra)
if (existing != null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationAlreadyExists, {}))
@@ -616,6 +651,7 @@ export async function updateIntegration (
params: Integration
): Promise<void> {
const { extra, account } = decodeTokenVerbose(ctx, token)
// it checks params and throws BadRequest if params are invalid
const existing = await findExistingIntegration(account, db, params, extra)
if (existing == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {}))
@@ -633,6 +669,7 @@ export async function deleteIntegration (
params: IntegrationKey
): Promise<void> {
const { extra, account } = decodeTokenVerbose(ctx, token)
// it checks params and throws BadRequest if params are invalid
const existing = await findExistingIntegration(account, db, params, extra)
if (existing == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.IntegrationNotFound, {}))
@@ -695,7 +732,7 @@ export async function getIntegration (
const isAllowedService = verifyAllowedServices(integrationServices, extra, false)
const { socialId, kind, workspaceUuid } = params
if (kind == null || socialId == null || workspaceUuid === undefined) {
if (kind == null || kind === '' || socialId == null || socialId === '' || workspaceUuid === undefined) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
@@ -719,7 +756,14 @@ export async function addIntegrationSecret (
): Promise<void> {
const { extra, account } = decodeTokenVerbose(ctx, token)
const { socialId, kind, workspaceUuid, key, secret } = params
if (kind == null || socialId == null || workspaceUuid === undefined || key == null) {
if (
kind == null ||
kind === '' ||
socialId == null ||
socialId === '' ||
workspaceUuid === undefined ||
key == null
) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
@@ -746,7 +790,14 @@ export async function updateIntegrationSecret (
): Promise<void> {
const { extra, account } = decodeTokenVerbose(ctx, token)
const { socialId, kind, workspaceUuid, key, secret } = params
if (kind == null || socialId == null || workspaceUuid === undefined || key == null) {
if (
kind == null ||
kind === '' ||
socialId == null ||
socialId === '' ||
workspaceUuid === undefined ||
key == null
) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
@@ -773,7 +824,14 @@ export async function deleteIntegrationSecret (
): Promise<void> {
const { extra, account } = decodeTokenVerbose(ctx, token)
const { socialId, kind, workspaceUuid, key } = params
if (kind == null || socialId == null || workspaceUuid === undefined || key == null) {
if (
kind == null ||
kind === '' ||
socialId == null ||
socialId === '' ||
workspaceUuid === undefined ||
key == null
) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
@@ -802,7 +860,14 @@ export async function getIntegrationSecret (
verifyAllowedServices(integrationServices, extra)
const { socialId, kind, workspaceUuid, key } = params
if (kind == null || socialId == null || workspaceUuid === undefined || key == null) {
if (
kind == null ||
kind === '' ||
socialId == null ||
socialId === '' ||
workspaceUuid === undefined ||
key == null
) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
const existing = await db.integrationSecret.findOne({ socialId, kind, workspaceUuid, key })
@@ -836,6 +901,10 @@ export async function findFullSocialIdBySocialKey (
const { socialKey } = params
if (socialKey == null || socialKey === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
return await db.socialId.findOne({ key: socialKey })
}
@@ -853,6 +922,10 @@ export async function mergeSpecifiedPersons (
verifyAllowedServices(['tool', 'workspace'], extra)
const { primaryPerson, secondaryPerson } = params
if (primaryPerson == null || primaryPerson === '' || secondaryPerson == null || secondaryPerson === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
await doMergePersons(db, primaryPerson, secondaryPerson)
}
@@ -870,6 +943,10 @@ export async function mergeSpecifiedAccounts (
verifyAllowedServices(['tool', 'workspace'], extra)
const { primaryAccount, secondaryAccount } = params
if (primaryAccount == null || primaryAccount === '' || secondaryAccount == null || secondaryAccount === '') {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}
await doMergeAccounts(db, primaryAccount, secondaryAccount)
}
+4 -1
View File
@@ -119,6 +119,8 @@ export async function getAccountDB (
}
}
export const assignableRoles = [AccountRole.Guest, AccountRole.User, AccountRole.Maintainer, AccountRole.Owner]
export function getRolePower (role: AccountRole): number {
return roleOrder[role]
}
@@ -1612,7 +1614,8 @@ export async function findExistingIntegration (
extra: any
): Promise<Integration | null> {
const { socialId, kind, workspaceUuid } = params
if (kind == null || socialId == null || workspaceUuid === undefined) {
// Note: workspaceUuid === null is a decent use case for account-wise integration not related to a particular workspace
if (kind == null || kind === '' || socialId == null || socialId === '' || workspaceUuid === undefined) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.BadRequest, {}))
}