add mobile email sign in route to api

This commit is contained in:
Satindar Dhillon
2022-07-26 23:40:44 -07:00
parent f44f768af7
commit 6a100051ac
9 changed files with 74 additions and 5 deletions

View File

@ -20,7 +20,7 @@ import Views
Task { await handleAppleToken(payload: payload, authenticator: authenticator) }
case let .failure(error):
switch error {
case .unauthorized, .unknown:
case .unauthorized, .unknown, .pendingEmailVerification:
break
case .network:
loginError = error
@ -34,7 +34,7 @@ import Views
} catch {
let submitTokenError = (error as? LoginError) ?? .unknown
switch submitTokenError {
case .unauthorized, .unknown:
case .unauthorized, .unknown, .pendingEmailVerification:
await handleAppleSignUp(authenticator: authenticator, payload: payload)
case .network:
loginError = submitTokenError

View File

@ -4,4 +4,5 @@ public enum LoginError: Error {
case unauthorized
case network
case unknown
case pendingEmailVerification
}

View File

@ -58,6 +58,8 @@ extension LoginError {
return .unauthorized
case .unknown:
return .unknown
case .pendingEmailVerification:
return .pendingEmailVerification
}
}
}

View File

@ -31,7 +31,7 @@ extension Authenticator {
switch loginError {
case .unauthorized, .unknown:
return await createPendingUser(idToken: idToken)
case .network:
case .network, .pendingEmailVerification:
return .loginError(error: .network)
}
}

View File

@ -10,11 +10,15 @@ public enum ServerError: String, Error {
case unauthenticated
case timeout
case unknown
case pendingEmailVerification
}
extension ServerError {
init(serverResponse: ServerResponse) {
switch serverResponse.httpUrlResponse?.statusCode {
case 418?:
self = .pendingEmailVerification
return
case 401?, 403?:
self = .unauthenticated
return

View File

@ -42,7 +42,7 @@ extension Networker {
let urlRequest = URLRequest.create(
baseURL: appEnvironment.serverBaseURL,
urlPath: "/api/mobile-auth/email-login",
urlPath: "/api/mobile-auth/email-sign-in",
requestMethod: .post(params: encodedParams)
)

View File

@ -25,6 +25,8 @@ private extension LoginError {
return LocalText.networkError
case .unknown:
return LocalText.genericError
case .pendingEmailVerification:
return "Please check your email for a verification message."
}
}
}

View File

@ -2,7 +2,10 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import express from 'express'
import { createMobileSignInResponse } from './sign_in'
import {
createMobileSignInResponse,
createMobileEmailSignInResponse,
} from './sign_in'
import { createMobileSignUpResponse } from './sign_up'
import { createMobileAccountCreationResponse } from './account_creation'
@ -15,6 +18,12 @@ export function mobileAuthRouter() {
res.status(payload.statusCode).json(payload.json)
})
router.post('/email-sign-in', async (req, res) => {
const { email, password } = req.body
const payload = await createMobileEmailSignInResponse(email, password)
res.status(payload.statusCode).json(payload.json)
})
router.post('/sign-up', async (req, res) => {
const { token, provider, name } = req.body
const payload = await createMobileSignUpResponse(token, provider, name)

View File

@ -8,6 +8,11 @@ import {
} from '../auth_types'
import { createMobileAuthPayload } from '../jwt_helpers'
import UserModel from '../../../datalayer/user'
import { initModels } from '../../../server'
import { sendConfirmationEmail } from '../../../services/send_emails'
import { kx } from '../../../datalayer/knex_config'
import { StatusType } from '../../../datalayer/user/model'
import { comparePassword } from '../../../utils/auth'
export async function createMobileSignInResponse(
token?: string,
@ -31,6 +36,52 @@ export async function createMobileSignInResponse(
}
}
export async function createMobileEmailSignInResponse(
email?: string,
password?: string
): Promise<JsonResponsePayload> {
try {
if (!email || !password) {
throw new Error('Missing username or password')
}
const models = initModels(kx, false)
const user = await models.user.getWhere({
email,
})
if (!user?.id || !user?.password) {
throw new Error('user not found')
}
const validPassword = await comparePassword(password, user.password)
if (!validPassword) {
throw new Error('password is invalid')
}
if (user.status === StatusType.Pending && user.email) {
await sendConfirmationEmail({
id: user.id,
email: user.email,
name: user.name,
})
return {
statusCode: 418,
json: { errorCodes: ['PENDING_VERIFICATION'] },
}
}
const mobileAuthPayload = await createMobileAuthPayload(user.id)
return {
statusCode: 200,
json: mobileAuthPayload,
}
} catch (e) {
return authFailedPayload
}
}
const authFailedPayload = {
statusCode: 403,
json: { errorCodes: ['AUTH_FAILED'] },