kritsana135-hooray-server
Version:
for server
234 lines (214 loc) • 7.16 kB
JavaScript
import validator from "validator"
import { USER_TYPE } from "../constants/configUser"
import {
APP_NOT_FOUND,
CORE_SERVICE_NOT_FOUND,
SERVICE_NOT_FOUND,
} from "../constants/errors/application"
import {
EMAIL_ADDRESS_NOT_FOUND,
INVALID_EMAIL_ADDRESS,
INVALID_REGISTER_TYPE,
TYPE_LOGIN_NOT_FOUND,
USERNAME_ALREADY_EXIST,
USER_NAME_NOT_FOUND,
} from "../constants/errors/resourceOwner"
import {
EMAIL_ALREADY_EXIST,
PASSWORD_NOT_FOUND,
} from "../constants/errors/utils"
import { FEATURE_KEYS_PROPERTY as FEATURE_KEY } from "../constants/featureKeys"
import { EN } from "../constants/language"
import { REGISTER } from "../constants/loginType"
import { CREATE_RESOURCE_SUCCESS } from "../constants/logsSystem/message"
import { DEFAULT_PERMISSION } from "../constants/resourceOwnerPermissions"
import AppModel from "../models/AppModel"
import ResourceOwnerModel from "../models/ResourceOwnerModel"
import ServiceModel from "../models/ServiceModel"
import ThemeModel from "../models/ThemeModel"
import { checkFeatureKey } from "./auth"
import ErrorMessage from "./error"
import { sendToVerifyEmail } from "./sendEmail"
import { validatePassword } from "./validate"
const addAttribute = async (user, application, locale = EN, connection) => {
const coreServiceKey = process.env.SERVICE_KEY || ""
if (!application) throw ErrorMessage(locale, APP_NOT_FOUND)
user.userType = USER_TYPE.USER
user.application = application
user.userPermission = {
service: null,
permissions: [],
}
DEFAULT_PERMISSION.forEach((element) => {
user.userPermission.permissions.push({
permissionName: element.permissionName,
code: element.defaultCode,
})
})
// console.log("\n==app==\n", application);
if (!application.services || application.services.length == 0) {
const service = await ServiceModel(connection).findOne({
serviceKey: coreServiceKey,
})
if (!service) throw ErrorMessage(locale, SERVICE_NOT_FOUND)
user.userPermission.service = service
return user
}
const findCoreService = application?.services?.find(
(element) => element.service?.serviceKey === coreServiceKey
)
if (!findCoreService) throw ErrorMessage(locale, CORE_SERVICE_NOT_FOUND)
const permission = findCoreService.userPermissions.find(
(element) => element.permissionType === "DEFAULT"
)
if (permission) user.userPermission.permissions = permission.permissions
user.userPermission.service = findCoreService.service
return user
}
const register = async (
locale = EN,
credentialKey = "",
coreServiceKey = "",
type,
data = {},
connection
) => {
if (!type) throw ErrorMessage(locale, TYPE_LOGIN_NOT_FOUND)
console.log(connection ? "have" : "not")
await ResourceOwnerModel(connection)
await ServiceModel(connection)
await ThemeModel(connection)
const app = await AppModel(connection)
.findOne({
credentials: { $elemMatch: { credentialKey } },
})
.populate({
path: "resourceOwners",
})
.populate({
path: "services.service",
match: { isActive: { $eq: true } },
})
if (!app) throw ErrorMessage(locale, APP_NOT_FOUND)
type = type.toUpperCase()
switch (type) {
case REGISTER.EMAIL: {
await checkFeatureKey(
locale,
credentialKey,
coreServiceKey,
[FEATURE_KEY.REGISTER],
true,
connection
)
if (!data.email) throw ErrorMessage(locale, EMAIL_ADDRESS_NOT_FOUND)
if (!data.password) throw ErrorMessage(locale, PASSWORD_NOT_FOUND)
if (!validator.isEmail(data.email) || validator.isEmpty(data.email))
throw ErrorMessage(locale, INVALID_EMAIL_ADDRESS)
return await createWithEmail(locale, data, app, connection)
}
case REGISTER.USERNAME: {
await checkFeatureKey(
locale,
credentialKey,
coreServiceKey,
[FEATURE_KEY.REGISTER],
true,
connection
)
if (!data.username) throw ErrorMessage(locale, USER_NAME_NOT_FOUND)
if (!data.password) throw ErrorMessage(locale, PASSWORD_NOT_FOUND)
return await createWithUsername(locale, data, app, connection)
}
default:
await ErrorMessage(locale, INVALID_REGISTER_TYPE)
}
return {}
}
const createWithEmail = async (locale = EN, data = {}, app, connection) => {
const { email, password, confirmPassword } = data
data.email = {}
await validatePassword(locale, password, confirmPassword)
const user = await ResourceOwnerModel(connection).findOne({
"email.value": email,
application: app._id,
})
if (user) throw ErrorMessage(locale, EMAIL_ALREADY_EXIST)
const coreServiceKey = process.env.SERVICE_KEY || ""
const service = app?.services?.find(
(element) => element?.service?.serviceKey === coreServiceKey
)
if (!service) throw ErrorMessage(locale, CORE_SERVICE_NOT_FOUND)
const checkFeature = service.featureKeys?.find(
(element) => element?.key === FEATURE_KEY.CONFIRM_EMAIL
)
if (checkFeature && checkFeature.enable) {
// Send verify
const verifyToken = await sendToVerifyEmail(locale, email, app)
data.verifyTokens = []
data.verifyTokens.push(verifyToken)
data.email.verifyStatus = "NO"
}
data.email.value = email
data = await addAttribute(data, app, locale, connection)
delete data.credential
const resourceOwner = new ResourceOwnerModel(connection)(data)
await resourceOwner.save().then((result) =>
result
.populate({
path: "application",
select: "_id name",
})
.populate({
path: "services.service",
select: "_id name name logo graphqlEndpointAdmin",
})
.populate({
path: "userPermission.service",
select: "_id name logo graphqlEndpointAdmin",
})
)
// let prevData = { ...app };
app.resourceOwners.push(resourceOwner)
await app.save()
resourceOwner.logMessage = CREATE_RESOURCE_SUCCESS
return resourceOwner
}
const createWithUsername = async (locale = EN, data = {}, app, connection) => {
const { username, password, confirmPassword } = data
data.username = {}
await validatePassword(locale, password, confirmPassword)
const user = await ResourceOwnerModel(connection).findOne({
"username.value": username,
application: app._id,
})
if (user) throw ErrorMessage(locale, USERNAME_ALREADY_EXIST)
data.username.value = username
data = await addAttribute(data, app, locale, connection)
delete data.credential
const resourceOwner = new ResourceOwnerModel(connection)(data)
await resourceOwner.save().then((result) =>
result
.populate({
path: "application",
select: "_id name",
})
.populate({
path: "services.service",
select: "_id name name logo graphqlEndpointAdmin",
})
.populate({
path: "userPermission.service",
select: "_id name logo graphqlEndpointAdmin",
})
)
// let prevData = { ...app };
app.resourceOwners.push(resourceOwner)
await app.save()
resourceOwner.logMessage = CREATE_RESOURCE_SUCCESS
return resourceOwner
}
module.exports = {
// addAttribute,
register,
}