Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions api/root.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ router.get('/', (_, res) => {
router.get('/login', hasQueryParams('user'), async (req, res, next) => {
try {
const { user, redirect, zone, product = PRODUCT_ATOM, nolink } = req.query
const normalizedEmail = user.trim().toLowerCase()
const { STAGE = 'dev' } = process.env
let origin = `${req.protocol}://${req.get('host')}`
if (STAGE) {
origin += `/${STAGE}`
}
// login user and send OTP email
const deliveryInfo = await loginUser({
user,
user: normalizedEmail,
redirect: decodeURIComponent(redirect || `${origin}/verify`),
zone: decodeURIComponent(zone || 'utc'),
product: product.toLowerCase(),
Expand All @@ -49,8 +50,8 @@ router.get('/login', hasQueryParams('user'), async (req, res, next) => {
})
}
return res.json({
message: `Login passcode sent to ${user} through email`,
user,
message: `Login passcode sent to ${normalizedEmail} through email`,
user: normalizedEmail,
})
} catch (err) {
if (err instanceof APIError) {
Expand All @@ -64,18 +65,19 @@ router.get('/login', hasQueryParams('user'), async (req, res, next) => {
router.get('/verify', hasQueryParams('user', 'otp'), async (req, res, next) => {
try {
const { user: email, otp, reset_uuid, product = PRODUCT_ATOM, timeout, future_access } = req.query
const normalizedEmail = email.trim().toLowerCase()
const { token, api_access, prefix, product: jwtProduct } = await verifyOTP({
email,
email: normalizedEmail,
otp,
reset_uuid: ['1', 'true'].includes(reset_uuid),
product: product.toLowerCase(),
timeout: timeout || undefined,
future_access: ['1', 'true'].includes(future_access),
})
return res.json({
message: `User ${email} verified, please store and use the token responsibly`,
email,
user: email, // for consistency with other routes
message: `User ${normalizedEmail} verified, please store and use the token responsibly`,
email: normalizedEmail,
user: normalizedEmail, // for consistency with other routes
token,
product: jwtProduct,
access: {
Expand Down
39 changes: 25 additions & 14 deletions modules/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const _checkEmpty = ({ ...params }) => {
}
}

const _normalizeEmail = (email) => email.trim().toLowerCase()

const selectUser = async ({ email, selects, conditions = [] }) => {
email = _normalizeEmail(email)
// returns user data, or undefined if user not found
_checkEmpty({ email })
const { rows = [] } = await rPool.query(`
Expand All @@ -40,6 +43,7 @@ const listUsers = async ({ selects, conditions }) => {
}

const insertUser = async ({ email, ...props }) => {
email = _normalizeEmail(email)
_checkEmpty({ email })
const entries = Object.entries({ email, ...props })
try {
Expand All @@ -60,6 +64,7 @@ const insertUser = async ({ email, ...props }) => {

// resolves to 1 if update successful
const updateUser = async ({ email, ...updates }) => {
email = _normalizeEmail(email)
_checkEmpty({ email })
const entries = Object.entries(updates)
return await wPool.transaction(async (query) => {
Expand All @@ -82,21 +87,27 @@ const updateUser = async ({ email, ...updates }) => {

}

const deleteUser = (email) => wPool.query(`
DELETE FROM equsers
WHERE email = $1;
`, [email])
const deleteUser = (email) => {
email = _normalizeEmail(email)
return wPool.query(`
DELETE FROM equsers
WHERE email = $1;
`, [email])
}

const getUserWL = (email) => rPool.query(`
SELECT
wl.logo,
wl.sender,
wl.company
FROM whitelabel AS wl
INNER JOIN equsers AS u
ON u.client->'wl'->(0) = wl.whitelabelid::text::jsonb
WHERE u.email = $1;
`, [email])
const getUserWL = (email) => {
email = _normalizeEmail(email)
return rPool.query(`
SELECT
wl.logo,
wl.sender,
wl.company
FROM whitelabel AS wl
INNER JOIN equsers AS u
ON u.client->'wl'->(0) = wl.whitelabelid::text::jsonb
WHERE u.email = $1;
`, [email])
}

module.exports = {
selectUser,
Expand Down