diff --git a/src/app/routes/Landing.tsx b/src/app/routes/Landing.tsx
index 0bd4f03..4333587 100644
--- a/src/app/routes/Landing.tsx
+++ b/src/app/routes/Landing.tsx
@@ -2,18 +2,13 @@ import { useNavigate } from 'react-router'
import { useEffect} from "react"
import BungieLogin from '../../features/auth/BungieLogin'
-import { generateToken, regenerateTokens } from '../../lib/TokenService'
-import { isAuthenticated } from '../../lib/AuthService'
+import { generateToken, regenerateTokens } from '../../lib/bungie_api/TokenService'
+import { isAuthenticated } from '../../lib/bungie_api/AuthService'
export const LandingRoute = () => {
const navigate = useNavigate()
-
- function getAuthCodeFromURL(): string | null {
- return window.location.href.includes("code=") ? window.location.href.split('code=')[1] : null
- }
-
useEffect( () => {
if (isAuthenticated()) {
@@ -24,20 +19,6 @@ export const LandingRoute = () => {
console.log("Token regenerated and authenticated")
navigate('/app')
}
- else {
- console.log("Not authenticated")
- const authCode = getAuthCodeFromURL()
-
- if (authCode !== null) {
- console.log("Auth code found, storing and attempting token generation")
- localStorage.setItem("authCode", "" + authCode)
-
- if (generateToken(false)) {
- console.log("Fresh token generated")
- navigate('/app')
- }
- }
- }
}, [])
diff --git a/src/app/routes/Return.tsx b/src/app/routes/Return.tsx
new file mode 100644
index 0000000..595763d
--- /dev/null
+++ b/src/app/routes/Return.tsx
@@ -0,0 +1,22 @@
+import { useEffect } from "react"
+import { useNavigate } from "react-router-dom"
+import { handleAuthReturn } from "../../features/auth/AuthReturn"
+
+export const ReturnRoute = () => {
+
+ const navigate = useNavigate()
+
+ useEffect( () => {
+
+ if (handleAuthReturn()) {
+ navigate('/')
+ }
+
+ }, [])
+
+ return (
+
+ Authentication Error
+
+ )
+}
\ No newline at end of file
diff --git a/src/app/routes/index.tsx b/src/app/routes/index.tsx
index fe85dac..9a50442 100644
--- a/src/app/routes/index.tsx
+++ b/src/app/routes/index.tsx
@@ -1,6 +1,6 @@
import { createBrowserRouter } from 'react-router-dom';
import { Dashboard } from './Dashboard';
-import { ProtectedRoute } from '../../lib/AuthService';
+import { ProtectedRoute } from '../../lib/bungie_api/AuthService';
export const createRouter = () => {
return createBrowserRouter ([
@@ -11,6 +11,13 @@ export const createRouter = () => {
return { Component: LandingRoute }
}
},
+ {
+ path: '/return',
+ lazy: async () => {
+ const { ReturnRoute } = await import ('./Return')
+ return { Component: ReturnRoute }
+ }
+ },
{
path: '/app',
element: (
diff --git a/src/features/auth/AuthReturn.tsx b/src/features/auth/AuthReturn.tsx
new file mode 100644
index 0000000..cbd6461
--- /dev/null
+++ b/src/features/auth/AuthReturn.tsx
@@ -0,0 +1,32 @@
+import { generateToken } from "../../lib/bungie_api/TokenService"
+import { setTokens } from "../../lib/bungie_api/TokensStore"
+
+function getAuthCodeFromURL(): string | null {
+ return window.location.href.includes("code=") ? window.location.href.split('code=')[1] : null
+}
+
+export function handleAuthReturn(): boolean {
+
+ const code = getAuthCodeFromURL()
+
+ if (!code?.length) {
+ console.log("Could not find authorization code")
+ return false
+ }
+
+ try {
+ const tokens = generateToken(false, code)
+
+ if (tokens) {
+ setTokens(tokens)
+
+ return true
+ }
+
+ }
+ catch (error) {
+ console.log(error)
+ }
+
+ return false
+}
\ No newline at end of file
diff --git a/src/features/auth/BungieLogin.tsx b/src/features/auth/BungieLogin.tsx
index 4156187..114bf75 100644
--- a/src/features/auth/BungieLogin.tsx
+++ b/src/features/auth/BungieLogin.tsx
@@ -1,5 +1,5 @@
import React from "react"
-import { authenticate } from "../../lib/AuthService"
+import { authenticate } from "../../lib/bungie_api/AuthService"
const BungieLogin: React.FC = () => {
diff --git a/src/features/membership/BungieAccount.ts b/src/features/membership/BungieAccount.ts
index 9f51ef9..e4d75e8 100644
--- a/src/features/membership/BungieAccount.ts
+++ b/src/features/membership/BungieAccount.ts
@@ -1,5 +1,5 @@
-import { _get } from "../../lib/BungieApiClient";
-import { getMembershipId, getTokens } from "../../lib/TokenStoreService";
+import { _get } from "../../lib/bungie_api/BungieApiClient";
+import { getMembershipId, getTokens } from "../../lib/bungie_api/TokensStore";
export function getCurrentMembershipData() {
diff --git a/src/features/profile/DestinyProfile.ts b/src/features/profile/DestinyProfile.ts
index 445a86a..e521211 100644
--- a/src/features/profile/DestinyProfile.ts
+++ b/src/features/profile/DestinyProfile.ts
@@ -1,5 +1,5 @@
-import { _get } from "../../lib/BungieApiClient"
-import { getTokens } from "../../lib/TokenStoreService"
+import { _get } from "../../lib/bungie_api/BungieApiClient"
+import { getTokens } from "../../lib/bungie_api/TokensStore"
export function getProfile(destinyMembershipId: string) {
diff --git a/src/lib/TokenService.ts b/src/lib/TokenService.ts
deleted file mode 100644
index 3b70b53..0000000
--- a/src/lib/TokenService.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { Token, Tokens, getTokens, setTokens } from "./TokenStoreService"
-import { _post } from "./BungieApiClient"
-
-export function canTokensRefresh() {
- const tokens = getTokens()
-
- if (!tokens) {
- return false
- }
-
- return tokens && !isTokenExpired(tokens.refreshToken)
-}
-
-export function expireTokens() {
- const tokens = getTokens()
-
- if (tokens) {
- tokens.accessToken.acquired = 0
- tokens.accessToken.expires = 0
- setTokens(tokens)
- }
-}
-
-export function isTokenExpired(token?: Token) {
-
- if (!token) {
- return true
- }
-
- const expiration = getTokenExpiration(token)
-
- return Date.now() > expiration
-}
-
-function getTokenExpiration(token?: Token): number {
- return (token && 'acquired' in token && 'expires' in token) ? token.acquired + token.expires * 1000 : 0
-}
-
-export function generateToken(refresh: boolean): boolean {
-
- const CLIENT_ID = import.meta.env.VITE_CLIENT_ID
- const CLIENT_SECRET = import.meta.env.VITE_CLIENT_SECRET
- const AUTH_CODE = localStorage.getItem("authCode")
- const REFRESH_TOKEN = getTokens()?.refreshToken
-
- let body = refresh === false ?
- `grant_type=authorization_code&code=${AUTH_CODE}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}` :
- `grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}`
-
- _post('/Platform/App/OAuth/Token/', body, {
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Authorization': `Basic ${window.btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)}`
- }
- })
- .then(response => {
- if (response.data.access_token) {
-
- const aquired = Date.now()
-
- const accessToken: Token = {
- value: response.data.access_token,
- expires: response.data.expires_in,
- name: 'access',
- acquired: aquired
- }
-
- const refreshToken: Token = {
- value: response.data.refresh_token,
- expires: response.data.refresh_expires_in,
- name: 'refresh',
- acquired: aquired
- }
-
- const tokens: Tokens = {
- accessToken,
- refreshToken,
- membershipId: response.data.membership_id
- }
-
- setTokens(tokens)
-
- return true
- }
- else {
- console.log("Could not get access token")
- return false
- }
- })
-
- return false
-}
-
-export function regenerateTokens(): boolean {
-
- if (canTokensRefresh()) {
- return generateToken(true)
- }
-
- return false
-}
\ No newline at end of file
diff --git a/src/lib/AuthService.tsx b/src/lib/bungie_api/AuthService.tsx
similarity index 93%
rename from src/lib/AuthService.tsx
rename to src/lib/bungie_api/AuthService.tsx
index 7b9ccd2..e94a914 100644
--- a/src/lib/AuthService.tsx
+++ b/src/lib/bungie_api/AuthService.tsx
@@ -1,6 +1,6 @@
import { Navigate } from "react-router-dom"
import { isTokenExpired } from "./TokenService"
-import { getTokens } from "./TokenStoreService"
+import { getTokens } from "./TokensStore"
export function authenticate(): void {
window.location.replace(`https://www.bungie.net/en/OAuth/Authorize?client_id=${import.meta.env.VITE_CLIENT_ID}&response_type=code`)
diff --git a/src/lib/BungieApiClient.ts b/src/lib/bungie_api/BungieApiClient.ts
similarity index 100%
rename from src/lib/BungieApiClient.ts
rename to src/lib/bungie_api/BungieApiClient.ts
diff --git a/src/lib/bungie_api/TokenService.ts b/src/lib/bungie_api/TokenService.ts
new file mode 100644
index 0000000..be22f52
--- /dev/null
+++ b/src/lib/bungie_api/TokenService.ts
@@ -0,0 +1,111 @@
+import { Token, Tokens, getTokens, setTokens } from "./TokensStore"
+import { _post } from "./BungieApiClient"
+import { CLIENT_ID, CLIENT_SECRET } from "./utils"
+import { AxiosResponse } from "axios"
+
+export function canTokensRefresh() {
+ const tokens = getTokens()
+
+ if (!tokens) {
+ return false
+ }
+
+ return tokens && !isTokenExpired(tokens.refreshToken)
+}
+
+export function expireTokens() {
+ const tokens = getTokens()
+
+ if (tokens) {
+ tokens.accessToken.acquired = 0
+ tokens.accessToken.expires = 0
+ setTokens(tokens)
+ }
+}
+
+export function isTokenExpired(token?: Token) {
+
+ if (!token) {
+ return true
+ }
+
+ const expiration = getTokenExpiration(token)
+
+ return Date.now() > expiration
+}
+
+function getTokenExpiration(token?: Token): number {
+ return (token && 'acquired' in token && 'expires' in token) ? token.acquired + token.expires * 1000 : 0
+}
+
+export function generateToken(refresh: boolean, authCode=""): Tokens | null {
+ const REFRESH_TOKEN = getTokens()?.refreshToken
+ var returnToken = null
+
+ let body = refresh === false ?
+ `grant_type=authorization_code&code=${authCode}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}` :
+ `grant_type=refresh_token&refresh_token=${REFRESH_TOKEN}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}`
+
+ _post('/Platform/App/OAuth/Token/', body, {
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'Authorization': `Basic ${window.btoa(`${CLIENT_ID}:${CLIENT_SECRET}`)}`
+ }
+ })
+ .then(response => {
+
+ returnToken = handleTokenResponse(response)
+
+ if (refresh) {
+ setTokens(returnToken)
+ console.log("Tokens successfully generated")
+ }
+ })
+ .catch(error => {
+ throw new Error(error)
+ })
+
+ return returnToken
+}
+
+function handleTokenResponse(response: AxiosResponse): Tokens {
+ if (response.data.access_token) {
+
+ const aquired = Date.now()
+
+ const accessToken: Token = {
+ value: response.data.access_token,
+ expires: response.data.expires_in,
+ name: 'access',
+ acquired: aquired
+ }
+
+ const refreshToken: Token = {
+ value: response.data.refresh_token,
+ expires: response.data.refresh_expires_in,
+ name: 'refresh',
+ acquired: aquired
+ }
+
+ const tokens: Tokens = {
+ accessToken,
+ refreshToken,
+ membershipId: response.data.membership_id
+ }
+
+ return tokens
+ }
+ else {
+ throw new Error(`Invalid response: ${JSON.stringify(response)}`)
+ }
+}
+
+export function regenerateTokens(): boolean {
+
+ if (canTokensRefresh()) {
+ generateToken(true)
+ return true
+ }
+
+ return false
+}
\ No newline at end of file
diff --git a/src/lib/TokenStoreService.ts b/src/lib/bungie_api/TokensStore.ts
similarity index 96%
rename from src/lib/TokenStoreService.ts
rename to src/lib/bungie_api/TokensStore.ts
index dd2f2a8..87d37aa 100644
--- a/src/lib/TokenStoreService.ts
+++ b/src/lib/bungie_api/TokensStore.ts
@@ -12,7 +12,7 @@ export interface Tokens {
membershipId: string
}
-const key = 'Tokens'
+const key = 'authTokens'
export function getTokens(): Tokens | null {
const tokenString = localStorage.getItem(key)
diff --git a/src/lib/bungie_api/utils.ts b/src/lib/bungie_api/utils.ts
new file mode 100644
index 0000000..4171a17
--- /dev/null
+++ b/src/lib/bungie_api/utils.ts
@@ -0,0 +1,6 @@
+
+export const API_KEY = import.meta.env.VITE_API_KEY
+
+export const CLIENT_ID = import.meta.env.VITE_CLIENT_ID
+
+export const CLIENT_SECRET = import.meta.env.VITE_CLIENT_SECRET
\ No newline at end of file