Skip to content

Commit

Permalink
Merge branch 'OAuth'
Browse files Browse the repository at this point in the history
  • Loading branch information
dragoni7 committed Jun 24, 2024
2 parents b6f8b0a + ae37530 commit b6a2865
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 130 deletions.
23 changes: 2 additions & 21 deletions src/app/routes/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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')
}
}
}

}, [])

Expand Down
22 changes: 22 additions & 0 deletions src/app/routes/Return.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
Authentication Error
</div>
)
}
9 changes: 8 additions & 1 deletion src/app/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -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 ([
Expand All @@ -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: (
Expand Down
32 changes: 32 additions & 0 deletions src/features/auth/AuthReturn.tsx
Original file line number Diff line number Diff line change
@@ -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
}
2 changes: 1 addition & 1 deletion src/features/auth/BungieLogin.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react"
import { authenticate } from "../../lib/AuthService"
import { authenticate } from "../../lib/bungie_api/AuthService"

const BungieLogin: React.FC = () => {

Expand Down
4 changes: 2 additions & 2 deletions src/features/membership/BungieAccount.ts
Original file line number Diff line number Diff line change
@@ -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() {

Expand Down
4 changes: 2 additions & 2 deletions src/features/profile/DestinyProfile.ts
Original file line number Diff line number Diff line change
@@ -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) {

Expand Down
101 changes: 0 additions & 101 deletions src/lib/TokenService.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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`)
Expand Down
File renamed without changes.
111 changes: 111 additions & 0 deletions src/lib/bungie_api/TokenService.ts
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions src/lib/bungie_api/utils.ts
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit b6a2865

Please sign in to comment.