2021-01-22 11:11:24 +08:00
import { Context } from '@nuxt/types' ;
import { Inject } from '@nuxt/types/app' ;
import { User } from 'hangar-api' ;
2021-04-08 12:58:49 +08:00
import { AuthState } from '~/store/auth' ;
2021-01-22 11:11:24 +08:00
2021-02-05 04:30:47 +08:00
const createAuth = ( { app : { $cookies } , $axios , store , $api , redirect } : Context ) = > {
2021-01-22 11:11:24 +08:00
class Auth {
login ( redirect : string ) : void {
$cookies . set ( 'returnRoute' , redirect , {
path : '/' ,
maxAge : 120 ,
2021-03-17 01:43:58 +08:00
secure : process.env.nodeEnv === 'production' ,
2021-01-22 11:11:24 +08:00
} ) ;
2021-03-17 01:43:58 +08:00
location . replace ( ` /login?returnUrl= ${ process . env . publicHost } ${ redirect } ` ) ;
2021-01-22 11:11:24 +08:00
}
2021-02-03 07:47:15 +08:00
processLogin ( token : string ) : Promise < void > {
2021-01-22 11:11:24 +08:00
store . commit ( 'auth/SET_AUTHED' , true ) ;
2021-02-03 07:47:15 +08:00
return this . updateUser ( token ) ;
2021-01-22 11:11:24 +08:00
}
2021-02-05 04:30:47 +08:00
async logout ( shouldRedirect = true ) : Promise < void > {
2021-02-04 17:34:24 +08:00
store . commit ( 'auth/SET_USER' , null ) ;
store . commit ( 'auth/SET_TOKEN' , null ) ;
store . commit ( 'auth/SET_AUTHED' , false ) ;
2021-02-05 04:30:47 +08:00
await $axios . get ( '/invalidate' ) ;
2021-02-04 17:34:24 +08:00
$cookies . remove ( 'HangarAuth_REFRESH' , {
path : '/' ,
} ) ;
2021-02-05 04:30:47 +08:00
if ( shouldRedirect ) {
2021-03-25 19:32:55 +08:00
redirect ( '/logged-out' ) ;
2021-01-31 10:00:11 +08:00
}
2021-01-22 13:18:09 +08:00
}
2021-02-03 07:47:15 +08:00
updateUser ( token : string ) : Promise < void > {
2021-01-31 10:00:11 +08:00
return $api
2021-02-03 07:47:15 +08:00
. requestInternalWithToken < User > ( 'users/@me' , token )
2021-01-31 10:00:11 +08:00
. then ( ( user ) = > {
2021-04-08 12:58:49 +08:00
if ( process . server ) {
store . commit ( 'auth/SET_USER' , user ) ;
} else if ( process . env . NODE_ENV === 'production' ) {
store . commit ( 'auth/SET_USER' , user ) ;
} else {
// TODO hella hacky fix but it fixes the issue reproducible here https://codesandbox.io/s/nuxt-dev-reload-issue-mk16j (also, this only plagues dev env so I guess it doesn't matter?)
setTimeout ( ( ) = > {
store . commit ( 'auth/SET_USER' , user ) ;
} , 1000 ) ;
}
return Promise . resolve ( ) ;
2021-01-31 10:00:11 +08:00
} )
2021-02-03 07:47:15 +08:00
. catch ( ( err ) = > {
console . log ( err ) ;
2021-02-10 16:31:43 +08:00
console . log ( 'LOGGING OUT ON updateUser' ) ;
2021-03-28 06:41:20 +08:00
return this . logout ( process . client ) ;
2021-02-03 07:47:15 +08:00
} ) ;
2021-01-22 11:11:24 +08:00
}
2021-03-13 18:10:56 +08:00
refreshUser ( ) : Promise < void > {
return $api . getToken ( true ) . then ( ( token ) = > {
if ( token != null ) {
if ( store . state . auth . authenticated ) {
return this . updateUser ( token ) ;
} else {
return this . processLogin ( token ) ;
}
} else {
return this . logout ( process . client ) ;
}
} ) ;
}
2021-04-08 12:58:49 +08:00
isLoggedIn ( ) : boolean {
return ( store . state . auth as AuthState ) . authenticated ;
}
2021-01-22 11:11:24 +08:00
}
return new Auth ( ) ;
} ;
type authType = ReturnType < typeof createAuth > ;
declare module 'vue/types/vue' {
interface Vue {
$auth : authType ;
}
}
declare module '@nuxt/types' {
interface NuxtAppOptions {
$auth : authType ;
}
interface Context {
$auth : authType ;
}
}
declare module 'vuex/types/index' {
2021-01-31 10:00:11 +08:00
// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
2021-01-22 11:11:24 +08:00
interface Store < S > {
$auth : authType ;
}
}
export default ( ctx : Context , inject : Inject ) = > {
inject ( 'auth' , createAuth ( ctx ) ) ;
} ;