1
1
import NextAuth from 'next-auth'
2
+ import axios from 'axios'
2
3
3
4
// For more information on each option (and a full list of options) go to: https://next-auth.js.org/configuration/options
4
5
const authOptions = {
@@ -28,11 +29,21 @@ const authOptions = {
28
29
callbacks : {
29
30
async jwt ( { token, account, user } ) {
30
31
// Triggered on the initial sign in
31
- // TODO(alishaevn): account for the refresh token
32
32
if ( account && user ) {
33
- token . accessToken = account . access_token
33
+ return {
34
+ accessToken : account . access_token ,
35
+ refreshToken : account . refresh_token ,
36
+ user,
37
+ }
38
+ }
39
+
40
+ // Return previous token if the access token has not expired yet
41
+ if ( token . accessTokenExpires && ( Date . now ( ) < token . accessTokenExpires ) ) {
42
+ return token
34
43
}
35
- return token
44
+
45
+ // Access token has expired, try to update it
46
+ return refreshAccessToken ( token )
36
47
} ,
37
48
async session ( { session, token } ) {
38
49
// Send additional properties to the client
@@ -42,4 +53,41 @@ const authOptions = {
42
53
}
43
54
}
44
55
56
+ /**
57
+ * Takes a token, and returns a new token with an updated `accessToken`.
58
+ * If an error occurs, returns the old token and an error property
59
+ */
60
+ const refreshAccessToken = async ( token ) => {
61
+ try {
62
+ const url = `https://${ process . env . NEXT_PUBLIC_PROVIDER_NAME } .scientist.com/oauth/token`
63
+ const encodedString = Buffer . from ( `${ process . env . CLIENT_ID } :${ process . env . CLIENT_SECRET } ` ) . toString ( 'base64' )
64
+ const params = new URLSearchParams ( {
65
+ grant_type : 'refresh_token' ,
66
+ refresh_token : token . refreshToken ,
67
+ } )
68
+
69
+ const response = await axios . post ( url , params , {
70
+ headers : {
71
+ 'Authorization' : `Basic ${ encodedString } ` ,
72
+ } ,
73
+ } )
74
+ const refreshedTokens = response . data
75
+
76
+ if ( response . status !== 200 ) {
77
+ throw refreshedTokens
78
+ }
79
+
80
+ return {
81
+ ...token ,
82
+ accessToken : refreshedTokens . access_token ,
83
+ refreshToken : refreshedTokens . refresh_token ?? token . refreshToken , // Fall back to the old refresh token
84
+ }
85
+ } catch ( error ) {
86
+ return {
87
+ ...token ,
88
+ error : 'RefreshAccessTokenError' ,
89
+ }
90
+ }
91
+ }
92
+
45
93
export default NextAuth ( authOptions )
0 commit comments