Skip to content

Commit

Permalink
Get the Oauth Refresh token (#345)
Browse files Browse the repository at this point in the history
* Warn on missing .env
* Add typechecking to CI
* Add base-64 package
* Simplify
  • Loading branch information
NigelBreslaw authored Feb 11, 2024
1 parent 305de05 commit aba076f
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ jobs:
run: cd native_gg && pnpm lint
- name: format
run: cd native_gg && pnpm format:check
- name: type check
run: cd native_gg && pnpm type-check

5 changes: 5 additions & 0 deletions native_gg/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import { Image } from "expo-image";
import { LinearGradient } from "expo-linear-gradient";
import { useState } from "react";
import AuthUI from "./src/AuthUI.tsx";
import { clientID } from "./src/constants/env.ts";

export default function App() {
const [token, setToken] = useState("");
const [membershipID, setMembershipID] = useState("");

if (clientID === undefined) {
console.warn("No .ENV file found. Please create one.");
}

return (
<View style={styles.container}>
<LinearGradient
Expand Down
5 changes: 4 additions & 1 deletion native_gg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
"analyze:ios": "source-map-explorer 'dist/_expo/static/js/ios/*.js' 'dist/_expo/static/js/ios/*.js.map'",
"analyze:android": "source-map-explorer 'dist/_expo/static/js/android/*.js' 'dist/_expo/static/js/android/*.js.map'",
"lint": "biome lint ./src",
"lint:fix": "biome check --apply ./src"
"lint:fix": "biome check --apply ./src",
"type-check": "time tsc --noEmit"
},
"dependencies": {
"@babel/preset-env": "7.23.9",
"@expo/metro-runtime": "3.1.3",
"@expo/webpack-config": "19.0.1",
"base-64": "1.0.0",
"expo": "50.0.6",
"expo-build-properties": "0.11.1",
"expo-crypto": "12.8.0",
Expand All @@ -37,6 +39,7 @@
"devDependencies": {
"@babel/core": "7.23.9",
"@biomejs/biome": "1.5.3",
"@types/base-64": "1.0.2",
"@types/react": "18.2.55",
"source-map-explorer": "2.5.3",
"typescript": "5.3.3"
Expand Down
14 changes: 14 additions & 0 deletions native_gg/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion native_gg/src/AuthUI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function AuthUI(props: AuthProps) {
function startAuth() {
WebBrowser.openAuthSessionAsync(authURL, redirectURL).then((result) => {
// Only used for web.
if (result?.type === "success") {
if (result.type === "success") {
processURL(result.url);
}
});
Expand Down
70 changes: 62 additions & 8 deletions native_gg/src/Authentication.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { clientID, clientSecret } from "./constants/env.ts";
import { apiKey, clientID, clientSecret } from "./constants/env.ts";
import * as v from "valibot";
import * as base64 from "base-64";

const authJWTSchema = v.object({
const refreshTokenSchema = v.object({
access_token: v.string(),
expires_in: v.number(),
membership_id: v.string(),
refresh_expires_in: v.number(),
refresh_token: v.string(),
time_stamp: v.optional(v.string([v.isoTimestamp()])),
token_type: v.string(),
});

type InitialAuthJWT = v.Output<typeof authJWTSchema>;
type RefreshToken = v.Output<typeof refreshTokenSchema>;

export function handleAuthCode(code: string): Promise<string> {
return new Promise((resolve, reject) => {
getAuthToken(code)
getRefreshToken(code)
.then((initialJWT) => {
const membership_id = processInitialAuthJWT(initialJWT);

Expand All @@ -26,7 +28,7 @@ export function handleAuthCode(code: string): Promise<string> {
});
}

export function getAuthToken(bungieCode: string): Promise<JSON> {
export function getRefreshToken(bungieCode: string): Promise<JSON> {
const headers = new Headers();
headers.append("Content-Type", "application/x-www-form-urlencoded");

Expand Down Expand Up @@ -56,10 +58,62 @@ export function getAuthToken(bungieCode: string): Promise<JSON> {
});
}

function processInitialAuthJWT(jwtToken: unknown): string {
export function getAccessToken(token: RefreshToken): Promise<RefreshToken> {
const headers = new Headers();
headers.append("Content-Type", "application/x-www-form-urlencoded");
headers.append("X-API-Key", apiKey);
// TODO: base64 package can be removed soon as Hermes is adding support for these in 0.74
// https://github.com/facebook/hermes/issues/1178
headers.append("Authorization", `Basic ${base64.encode(`${clientID}:${clientSecret}`)}`);

const bodyParams = `grant_type=refresh_token&refresh_token=${token.refresh_token}`;

const requestOptions: RequestInit = {
method: "POST",
headers: headers,
body: bodyParams,
};

return new Promise((resolve, reject) => {
fetch("https://www.bungie.net/platform/app/oauth/token/", requestOptions)
.then((response) => {
if (!response.ok) {
console.error(response);
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
resolve(data);
})
.catch((error) => {
reject(error);
});
});
}

function processInitialAuthJWT(jwtToken: object): string {
try {
const result = v.parse(authJWTSchema, jwtToken);
return result.membership_id;
const initialToken = v.parse(refreshTokenSchema, jwtToken);

let token: RefreshToken;

getAccessToken(initialToken)
.then((newToken) => {
token = v.parse(refreshTokenSchema, newToken);
token.time_stamp = new Date().toISOString();
const tokenTime = new Date(token.time_stamp).getTime();
// pause for 10 seconds, but don't do anything else
setTimeout(() => {
const timeNow = new Date().getTime();
console.log("token time", Math.trunc((timeNow - tokenTime) / 1000));
}, 10000);
})
.catch((error) => {
console.error(error);
});

return initialToken.membership_id;
} catch (error) {
console.error(error);
return "";
Expand Down
6 changes: 3 additions & 3 deletions native_gg/src/constants/env.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Platform } from "react-native";

// @ts-ignore
export const apiKey = process.env.EXPO_PUBLIC_API_KEY;
export const apiKey: string = process.env.EXPO_PUBLIC_API_KEY;
// @ts-ignore
export const clientID = process.env.EXPO_PUBLIC_CLIENT_ID;
export const clientID: string = process.env.EXPO_PUBLIC_CLIENT_ID;
// @ts-ignore
export const clientSecret = process.env.EXPO_PUBLIC_CLIENT_SECRET;
export const clientSecret: string = process.env.EXPO_PUBLIC_CLIENT_SECRET;

const isLocalWeb = process.env.NODE_ENV === "development" && Platform.OS === "web";

Expand Down

0 comments on commit aba076f

Please sign in to comment.