251 lines
10 KiB
JavaScript
251 lines
10 KiB
JavaScript
const {
|
|
updateCustomer,
|
|
updateCustomerAddressById,
|
|
deleteCustomerAddressById,
|
|
addCustomerAddress,
|
|
validateCredentials,
|
|
getCustomerById,
|
|
} = require("../lib/bigcommerceRestAPI")
|
|
const { withAccount } = require("../lib/utils")
|
|
const { getJwt } = require("../lib/utils")
|
|
const emailRegex =
|
|
/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/
|
|
;(function () {
|
|
if (context.user.auth()) return
|
|
let data = context.data
|
|
const r = context.request()
|
|
const customerId = r.param("id")
|
|
|
|
const backendAuth = context.user.auth()
|
|
|
|
let returnCustomer = undefined
|
|
if (!backendAuth) {
|
|
// require authorization header with jwt
|
|
const token = getJwt(context)
|
|
/** @type {JWTPwResetClaims} */ // @ts-ignore
|
|
const pwResetClaims = token.claims
|
|
/** @type {Customer} */ // @ts-ignore
|
|
const customer = context.db.find("bigCommerceCustomer", {
|
|
filter: { _id: pwResetClaims.tibiId },
|
|
})[0]
|
|
|
|
if (!customer) {
|
|
throw {
|
|
status: 404,
|
|
error: "customer not found",
|
|
log: false,
|
|
}
|
|
}
|
|
|
|
if (data.operation === "resetPassword") {
|
|
if (pwResetClaims && pwResetClaims.tibiId && pwResetClaims.check) {
|
|
// is password reset token since it has .check
|
|
if (pwResetClaims.tibiId != customerId)
|
|
throw {
|
|
status: 403,
|
|
error: "token not valid for this id",
|
|
log: false,
|
|
}
|
|
|
|
if (pwResetClaims.check != customer.currentToken)
|
|
throw {
|
|
status: 403,
|
|
error: "password reset token expired",
|
|
log: false,
|
|
}
|
|
updateCustomer({
|
|
authentication: {
|
|
force_password_reset: false,
|
|
new_password: data.password,
|
|
},
|
|
id: Number(customer.bigCommerceId),
|
|
})
|
|
|
|
throw {
|
|
status: 200,
|
|
log: false,
|
|
}
|
|
} else {
|
|
throw {
|
|
status: 403,
|
|
error: "invalid token",
|
|
log: false,
|
|
}
|
|
}
|
|
}
|
|
withAccount((loginClaims) => {
|
|
/** @type {BigCommerceCustomer} */
|
|
const customer = data.customer
|
|
if (customer) customer.id = Number(loginClaims.bigCommerceId)
|
|
if (data.operation === "updateCustomer") {
|
|
customer.email = loginClaims.email
|
|
const index = customer.form_fields.findIndex((f) => f.name === "username")
|
|
const internalCustomer = context.db.find("bigCommerceCustomer", {
|
|
filter: { email: customer.email },
|
|
})[0]
|
|
if (index >= 0) customer.form_fields[index].value = internalCustomer.username
|
|
const response = updateCustomer(customer)
|
|
|
|
throw {
|
|
status: 200,
|
|
data: response,
|
|
message: "customer updated",
|
|
log: false,
|
|
}
|
|
} else if (data.operation == "updateInternalCustomer") {
|
|
const customer = data.customer
|
|
returnCustomer = customer
|
|
} else if (data.operation === "updateCustomerAddress") {
|
|
/** @type {BigCommerceAddress} */
|
|
const address = data.address
|
|
address.customer_id = Number(loginClaims.bigCommerceId)
|
|
const response = updateCustomerAddressById(address)
|
|
throw {
|
|
status: 200,
|
|
message: "customer addresses updated",
|
|
data: response,
|
|
log: false,
|
|
}
|
|
} else if (data.operation === "deleteCustomerAddress") {
|
|
deleteCustomerAddressById(Number(loginClaims.bigCommerceId), data.addressId)
|
|
throw {
|
|
status: 200,
|
|
message: "customer address deleted",
|
|
data: {
|
|
success: true,
|
|
},
|
|
log: false,
|
|
}
|
|
} else if (data.operation === "addCustomerAddress") {
|
|
/** @type {BigCommerceAddress} */
|
|
const address = data.address
|
|
address.customer_id = Number(loginClaims.bigCommerceId)
|
|
delete address.id
|
|
const response = addCustomerAddress(address)
|
|
throw {
|
|
status: 200,
|
|
message: "customer addresses updated",
|
|
data: response,
|
|
log: false,
|
|
}
|
|
} else if (data.operation === "changePassword") {
|
|
const res = validateCredentials(loginClaims.email, data.currentPassword)
|
|
if (!res.is_valid) {
|
|
throw {
|
|
status: 403,
|
|
error: "current password incorrect",
|
|
log: false,
|
|
}
|
|
}
|
|
const resPw = updateCustomer({
|
|
authentication: {
|
|
force_password_reset: false,
|
|
new_password: data.newPassword,
|
|
},
|
|
id: Number(loginClaims.bigCommerceId),
|
|
})
|
|
throw {
|
|
status: 200,
|
|
message: "password reset successful",
|
|
log: false,
|
|
}
|
|
} else if (data.operation === "updateEmail") {
|
|
const resValidation = validateCredentials(loginClaims.email, data.password)
|
|
if (!resValidation.is_valid) {
|
|
throw {
|
|
status: 403,
|
|
error: "password incorrect",
|
|
log: false,
|
|
}
|
|
}
|
|
if (!data.email)
|
|
throw {
|
|
status: 400,
|
|
error: "email is required",
|
|
log: false,
|
|
}
|
|
data.email = data.email.toLowerCase()
|
|
const customers = context.db.find("bigCommerceCustomer", {
|
|
filter: { email: data.email },
|
|
})
|
|
if (customers.length > 0)
|
|
throw {
|
|
status: 409,
|
|
error: "email already in use",
|
|
log: false,
|
|
}
|
|
if (emailRegex.test(data.email) === false) {
|
|
throw {
|
|
status: 400,
|
|
error: "invalid email",
|
|
log: false,
|
|
}
|
|
}
|
|
const res = updateCustomer({ id: Number(loginClaims.bigCommerceId), email: data.email })
|
|
context.db.update("bigCommerceCustomer", loginClaims.tibiId, { email: data.email })
|
|
throw {
|
|
status: 200,
|
|
message: "customer updated",
|
|
data: res,
|
|
log: false,
|
|
}
|
|
} else if (data.operation === "updateUsername") {
|
|
const resValidation = validateCredentials(loginClaims.email, data.password)
|
|
if (!resValidation.is_valid) {
|
|
throw {
|
|
status: 403,
|
|
error: "password incorrect",
|
|
log: false,
|
|
}
|
|
}
|
|
/**@type {string} */
|
|
let username = data.username
|
|
if (!username)
|
|
throw {
|
|
status: 400,
|
|
error: "username is required",
|
|
log: false,
|
|
}
|
|
username = username.toLowerCase()
|
|
|
|
const userWithUsername = context.db.find("bigCommerceCustomer", {
|
|
filter: { username: username },
|
|
})[0]
|
|
if (userWithUsername)
|
|
throw {
|
|
status: 409,
|
|
message: "username already in use",
|
|
}
|
|
const internalCustomer = context.db.find("bigCommerceCustomer", {
|
|
filter: { email: loginClaims.email },
|
|
})[0]
|
|
internalCustomer.username = username
|
|
if (internalCustomer) {
|
|
context.db.update("bigCommerceCustomer", internalCustomer.id, internalCustomer)
|
|
}
|
|
|
|
//update bigcommerce customer too : get it and then update it with username swapped
|
|
const bCCustomer = getCustomerById(loginClaims.bigCommerceId)
|
|
if (!bCCustomer.form_fields) bCCustomer.form_fields = []
|
|
const usernameIndex = bCCustomer.form_fields.findIndex((f) => f.name === "username")
|
|
if (usernameIndex >= 0) bCCustomer.form_fields[usernameIndex].value = username
|
|
else bCCustomer.form_fields = [...bCCustomer.form_fields, { name: "username", value: username }]
|
|
updateCustomer(bCCustomer)
|
|
|
|
throw {
|
|
status: 200,
|
|
message: "customer updated",
|
|
data: internalCustomer,
|
|
log: false,
|
|
}
|
|
}
|
|
})
|
|
}
|
|
if (returnCustomer) {
|
|
return {
|
|
data: returnCustomer,
|
|
}
|
|
}
|
|
throw { status: 401, error: "unauthorized", log: false }
|
|
})()
|