11import * as express from 'express' ;
2- import { BadRequest , Unauthorized } from 'http-errors' ;
2+ import { BadRequest } from 'http-errors' ;
33import {
44 Body ,
55 Controller ,
@@ -38,6 +38,9 @@ type UserResponse = {
3838 email : string | null ;
3939} ;
4040
41+ const getApiBase = ( req : express . Request ) : string =>
42+ `${ req . protocol } ://${ required ( req . get ( 'host' ) , 'host' ) } ` ;
43+
4144@Route ( 'authentication' )
4245export class AuthenticationController extends Controller {
4346 @Security ( 'user-token' )
@@ -56,7 +59,7 @@ export class AuthenticationController extends Controller {
5659 ) : Promise < LoginResponse > {
5760 const userId = await getUserFromRequestOrCreateAndSetCookie ( req ) ;
5861 const { requestedEmail, returnToPath, requireVerifiedEmail } = loginRequest ;
59- const apiBase = ` ${ req . protocol } :// ${ required ( req . get ( 'host' ) , 'host' ) } ` ;
62+ const apiBase = getApiBase ( req ) ;
6063 const result = await UserService . processLoginRequest (
6164 requestedEmail ,
6265 userId ,
@@ -74,7 +77,7 @@ export class AuthenticationController extends Controller {
7477 }
7578
7679 /**
77- * We take the temporary token from the query string and set a permenant token in a cookie.
80+ * We take the temporary token from the query string and set a permanent token in a cookie.
7881 * @param magicToken A temporary token sent in a magic link
7982 * @param res
8083 * @param returnToPath The path to attach to the frontend base URL and redirect to after login
@@ -97,7 +100,23 @@ export class AuthenticationController extends Controller {
97100 const userId = UserService . getUserIdFromToken ( magicToken ) ;
98101
99102 if ( ! userId ) {
100- throw new Unauthorized ( 'The link contains in invalid or expired token' ) ;
103+ res . status ( 401 ) . type ( 'text/plain' ) ;
104+
105+ // If it's just expired, send a new link
106+ const userIdExpired = UserService . getUserIdFromToken ( magicToken , {
107+ ignoreExpiration : true ,
108+ } ) ;
109+ if ( typeof userIdExpired !== 'undefined' ) {
110+ await UserService . sendMagicLinkToUser (
111+ userIdExpired ,
112+ getApiBase ( req ) ,
113+ returnToPath
114+ ) ;
115+ res . send ( 'This link has expired. A new one has been emailed to you.' ) ;
116+ return ;
117+ }
118+ res . send ( 'This link contains an invalid token' ) ;
119+ return ;
101120 }
102121
103122 await UserService . markEmailVerified ( userId ) ;
0 commit comments