add mobile email sign in route to api
This commit is contained in:
@ -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
|
||||
|
||||
@ -4,4 +4,5 @@ public enum LoginError: Error {
|
||||
case unauthorized
|
||||
case network
|
||||
case unknown
|
||||
case pendingEmailVerification
|
||||
}
|
||||
|
||||
@ -58,6 +58,8 @@ extension LoginError {
|
||||
return .unauthorized
|
||||
case .unknown:
|
||||
return .unknown
|
||||
case .pendingEmailVerification:
|
||||
return .pendingEmailVerification
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
)
|
||||
|
||||
|
||||
@ -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."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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'] },
|
||||
|
||||
Reference in New Issue
Block a user