mirror of https://github.com/nocodb/nocodb
Pranav C
2 years ago
11 changed files with 395 additions and 74 deletions
@ -0,0 +1,41 @@
|
||||
export function validatePassword(p) { |
||||
let error = ''; |
||||
let progress = 0; |
||||
let hint = null; |
||||
let valid = true; |
||||
if (!p) { |
||||
error = |
||||
'At least 8 letters with one Uppercase, one number and one special letter'; |
||||
valid = false; |
||||
} else { |
||||
if (!(p.length >= 8)) { |
||||
error += 'Atleast 8 letters. '; |
||||
valid = false; |
||||
} else { |
||||
progress = Math.min(100, progress + 25); |
||||
} |
||||
|
||||
if (!p.match(/.*[A-Z].*/)) { |
||||
error += 'One Uppercase Letter. '; |
||||
valid = false; |
||||
} else { |
||||
progress = Math.min(100, progress + 25); |
||||
} |
||||
|
||||
if (!p.match(/.*[0-9].*/)) { |
||||
error += 'One Number. '; |
||||
valid = false; |
||||
} else { |
||||
progress = Math.min(100, progress + 25); |
||||
} |
||||
|
||||
if (!p.match(/[$&+,:;=?@#|'<>.^*()%!_-]/)) { |
||||
error += 'One special letter. '; |
||||
hint = "Allowed special character list : $&+,:;=?@#|'<>.^*()%!_-"; |
||||
valid = false; |
||||
} else { |
||||
progress = Math.min(100, progress + 25); |
||||
} |
||||
} |
||||
return { error, valid, progress, hint }; |
||||
} |
@ -0,0 +1,209 @@
|
||||
import User from '../../../models/User'; |
||||
import { v4 as uuidv4 } from 'uuid'; |
||||
import { promisify } from 'util'; |
||||
import { Tele } from 'nc-help'; |
||||
|
||||
import bcrypt from 'bcryptjs'; |
||||
import Noco from '../../../Noco'; |
||||
import { MetaTable } from '../../../utils/globals'; |
||||
import ProjectUser from '../../../models/ProjectUser'; |
||||
import { validatePassword } from 'nocodb-sdk'; |
||||
import boxen from 'boxen'; |
||||
|
||||
const { isEmail } = require('validator'); |
||||
const rolesLevel = { owner: 0, creator: 1, editor: 2, commenter: 3, viewer: 4 }; |
||||
|
||||
export default async function initAdminFromEnv(_ncMeta = Noco.ncMeta) { |
||||
if (process.env.NC_ADMIN_EMAIL && process.env.NC_ADMIN_PASSWORD) { |
||||
if (!isEmail(process.env.NC_ADMIN_EMAIL?.trim())) { |
||||
console.log( |
||||
'\n', |
||||
boxen( |
||||
`Provided admin email '${process.env.NC_ADMIN_EMAIL}' is not valid`, |
||||
{ |
||||
title: 'Invalid admin email', |
||||
padding: 1, |
||||
borderStyle: 'double', |
||||
titleAlignment: 'center', |
||||
borderColor: 'red' |
||||
} |
||||
), |
||||
'\n' |
||||
); |
||||
process.exit(1); |
||||
} |
||||
|
||||
const { valid, error, hint } = validatePassword( |
||||
process.env.NC_ADMIN_PASSWORD |
||||
); |
||||
if (!valid) { |
||||
console.log( |
||||
'\n', |
||||
boxen(`${error}${hint ? `\n\n${hint}` : ''}`, { |
||||
title: 'Invalid admin password', |
||||
padding: 1, |
||||
borderStyle: 'double', |
||||
titleAlignment: 'center', |
||||
borderColor: 'red' |
||||
}), |
||||
'\n' |
||||
); |
||||
process.exit(1); |
||||
} |
||||
|
||||
let ncMeta; |
||||
try { |
||||
ncMeta = await _ncMeta.startTransaction(); |
||||
const email = process.env.NC_ADMIN_EMAIL.toLowerCase().trim(); |
||||
|
||||
const salt = await promisify(bcrypt.genSalt)(10); |
||||
const password = await promisify(bcrypt.hash)( |
||||
process.env.NC_ADMIN_PASSWORD, |
||||
salt |
||||
); |
||||
const email_verification_token = uuidv4(); |
||||
|
||||
// if super admin not present
|
||||
if (await User.isFirst(ncMeta)) { |
||||
const roles = 'user,super'; |
||||
|
||||
// roles = 'owner,creator,editor'
|
||||
Tele.emit('evt', { |
||||
evt_type: 'project:invite', |
||||
count: 1 |
||||
}); |
||||
|
||||
await User.insert( |
||||
{ |
||||
firstname: '', |
||||
lastname: '', |
||||
email, |
||||
salt, |
||||
password, |
||||
email_verification_token, |
||||
roles |
||||
}, |
||||
ncMeta |
||||
); |
||||
} else { |
||||
const salt = await promisify(bcrypt.genSalt)(10); |
||||
const password = await promisify(bcrypt.hash)( |
||||
process.env.NC_ADMIN_PASSWORD, |
||||
salt |
||||
); |
||||
const email_verification_token = uuidv4(); |
||||
const superUser = await ncMeta.metaGet2(null, null, MetaTable.USERS, { |
||||
roles: 'user,super' |
||||
}); |
||||
|
||||
if (email !== superUser.email) { |
||||
// update admin email and password and migrate projects
|
||||
// if user already present and associated with some project
|
||||
|
||||
// check user account already present with the new admin email
|
||||
const existingUserWithNewEmail = await User.getByEmail(email, ncMeta); |
||||
|
||||
if (existingUserWithNewEmail) { |
||||
// get all project access belongs to the existing account
|
||||
// and migrate to the admin account
|
||||
const existingUserProjects = await ncMeta.metaList2( |
||||
null, |
||||
null, |
||||
MetaTable.PROJECT_USERS, |
||||
{ |
||||
condition: { fk_user_id: existingUserWithNewEmail.id } |
||||
} |
||||
); |
||||
|
||||
for (const existingUserProject of existingUserProjects) { |
||||
const userProject = await ProjectUser.get( |
||||
existingUserProject.project_id, |
||||
superUser.id, |
||||
ncMeta |
||||
); |
||||
|
||||
// if admin user already have access to the project
|
||||
// then update role based on the highest access level
|
||||
if (userProject) { |
||||
if ( |
||||
rolesLevel[userProject.roles] > |
||||
rolesLevel[existingUserProject.roles] |
||||
) { |
||||
await ProjectUser.update( |
||||
userProject.project_id, |
||||
superUser.id, |
||||
existingUserProject.roles, |
||||
ncMeta |
||||
); |
||||
} |
||||
} else { |
||||
// if super doesn't have access then add the access
|
||||
await ProjectUser.insert( |
||||
{ |
||||
...existingUserProject, |
||||
fk_user_id: superUser.id |
||||
}, |
||||
ncMeta |
||||
); |
||||
} |
||||
// delete the old project access entry from DB
|
||||
await ProjectUser.delete( |
||||
existingUserProject.project_id, |
||||
existingUserProject.fk_user_id, |
||||
ncMeta |
||||
); |
||||
} |
||||
|
||||
// delete existing user
|
||||
ncMeta.metaDelete( |
||||
null, |
||||
null, |
||||
MetaTable.USERS, |
||||
existingUserWithNewEmail.id |
||||
); |
||||
|
||||
// Update email and password of super admin account
|
||||
await User.update( |
||||
superUser.id, |
||||
{ |
||||
salt, |
||||
email, |
||||
password, |
||||
email_verification_token |
||||
}, |
||||
ncMeta |
||||
); |
||||
} else { |
||||
// if email's are not different update the password and hash
|
||||
await User.update( |
||||
superUser.id, |
||||
{ |
||||
salt, |
||||
email, |
||||
password, |
||||
email_verification_token |
||||
}, |
||||
ncMeta |
||||
); |
||||
} |
||||
} else { |
||||
// if email's are not different update the password and hash
|
||||
await User.update( |
||||
superUser.id, |
||||
{ |
||||
salt, |
||||
password, |
||||
email_verification_token |
||||
}, |
||||
ncMeta |
||||
); |
||||
} |
||||
} |
||||
await ncMeta.commit(); |
||||
} catch (e) { |
||||
console.log('Error occurred while updating/creating admin user'); |
||||
console.log(e); |
||||
await ncMeta.rollback(e); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue