|
|
|
@ -12,6 +12,7 @@ const { |
|
|
|
getTenantId, |
|
|
|
getTenantUser, |
|
|
|
doesTenantExist, |
|
|
|
doInTenant, |
|
|
|
} = require("@budibase/backend-core/tenancy") |
|
|
|
const { removeUserFromInfoDB } = require("@budibase/backend-core/deprovision") |
|
|
|
const { errors } = require("@budibase/backend-core") |
|
|
|
@ -41,70 +42,73 @@ const parseBooleanParam = (param: any) => { |
|
|
|
|
|
|
|
export const adminUser = async (ctx: any) => { |
|
|
|
const { email, password, tenantId } = ctx.request.body |
|
|
|
await doInTenant(tenantId, async () => { |
|
|
|
// account portal sends a pre-hashed password - honour param to prevent double hashing
|
|
|
|
const hashPassword = parseBooleanParam(ctx.request.query.hashPassword) |
|
|
|
// account portal sends no password for SSO users
|
|
|
|
const requirePassword = parseBooleanParam(ctx.request.query.requirePassword) |
|
|
|
|
|
|
|
if (await doesTenantExist(tenantId)) { |
|
|
|
ctx.throw(403, "Organisation already exists.") |
|
|
|
} |
|
|
|
|
|
|
|
// account portal sends a pre-hashed password - honour param to prevent double hashing
|
|
|
|
const hashPassword = parseBooleanParam(ctx.request.query.hashPassword) |
|
|
|
// account portal sends no password for SSO users
|
|
|
|
const requirePassword = parseBooleanParam(ctx.request.query.requirePassword) |
|
|
|
|
|
|
|
if (await doesTenantExist(tenantId)) { |
|
|
|
ctx.throw(403, "Organisation already exists.") |
|
|
|
} |
|
|
|
|
|
|
|
const response = await doWithGlobalDB(tenantId, async (db: any) => { |
|
|
|
const response = await db.allDocs( |
|
|
|
getGlobalUserParams(null, { |
|
|
|
include_docs: true, |
|
|
|
}) |
|
|
|
) |
|
|
|
// write usage quotas for cloud
|
|
|
|
if (!env.SELF_HOSTED) { |
|
|
|
// could be a scenario where it exists, make sure its clean
|
|
|
|
try { |
|
|
|
const usageQuota = await db.get(StaticDatabases.GLOBAL.docs.usageQuota) |
|
|
|
if (usageQuota) { |
|
|
|
await db.remove(usageQuota._id, usageQuota._rev) |
|
|
|
const response = await doWithGlobalDB(tenantId, async (db: any) => { |
|
|
|
const response = await db.allDocs( |
|
|
|
getGlobalUserParams(null, { |
|
|
|
include_docs: true, |
|
|
|
}) |
|
|
|
) |
|
|
|
// write usage quotas for cloud
|
|
|
|
if (!env.SELF_HOSTED) { |
|
|
|
// could be a scenario where it exists, make sure its clean
|
|
|
|
try { |
|
|
|
const usageQuota = await db.get( |
|
|
|
StaticDatabases.GLOBAL.docs.usageQuota |
|
|
|
) |
|
|
|
if (usageQuota) { |
|
|
|
await db.remove(usageQuota._id, usageQuota._rev) |
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
// don't worry about errors
|
|
|
|
} |
|
|
|
} catch (err) { |
|
|
|
// don't worry about errors
|
|
|
|
await db.put(quotas.generateNewQuotaUsage()) |
|
|
|
} |
|
|
|
await db.put(quotas.generateNewQuotaUsage()) |
|
|
|
return response |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.rows.some((row: any) => row.doc.admin)) { |
|
|
|
ctx.throw( |
|
|
|
403, |
|
|
|
"You cannot initialise once an global user has been created." |
|
|
|
) |
|
|
|
} |
|
|
|
return response |
|
|
|
}) |
|
|
|
|
|
|
|
if (response.rows.some((row: any) => row.doc.admin)) { |
|
|
|
ctx.throw( |
|
|
|
403, |
|
|
|
"You cannot initialise once an global user has been created." |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
const user = { |
|
|
|
email: email, |
|
|
|
password: password, |
|
|
|
createdAt: Date.now(), |
|
|
|
roles: {}, |
|
|
|
builder: { |
|
|
|
global: true, |
|
|
|
}, |
|
|
|
admin: { |
|
|
|
global: true, |
|
|
|
}, |
|
|
|
tenantId, |
|
|
|
} |
|
|
|
try { |
|
|
|
const finalUser = await users.save( |
|
|
|
user, |
|
|
|
const user = { |
|
|
|
email: email, |
|
|
|
password: password, |
|
|
|
createdAt: Date.now(), |
|
|
|
roles: {}, |
|
|
|
builder: { |
|
|
|
global: true, |
|
|
|
}, |
|
|
|
admin: { |
|
|
|
global: true, |
|
|
|
}, |
|
|
|
tenantId, |
|
|
|
hashPassword, |
|
|
|
requirePassword |
|
|
|
) |
|
|
|
await bustCache(CacheKeys.CHECKLIST) |
|
|
|
ctx.body = finalUser |
|
|
|
} catch (err: any) { |
|
|
|
ctx.throw(err.status || 400, err) |
|
|
|
} |
|
|
|
} |
|
|
|
try { |
|
|
|
const finalUser = await users.save( |
|
|
|
user, |
|
|
|
tenantId, |
|
|
|
hashPassword, |
|
|
|
requirePassword |
|
|
|
) |
|
|
|
await bustCache(CacheKeys.CHECKLIST) |
|
|
|
ctx.body = finalUser |
|
|
|
} catch (err: any) { |
|
|
|
ctx.throw(err.status || 400, err) |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
export const destroy = async (ctx: any) => { |
|
|
|
|