Skip to content

Commit

Permalink
cleaned up userinfo code, moved to node-nexus
Browse files Browse the repository at this point in the history
  • Loading branch information
insomnious committed Jul 19, 2023
1 parent 6e520e4 commit 252b66f
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 47 deletions.
4 changes: 2 additions & 2 deletions app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@
integrity sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==

"@nexusmods/nexus-api@Nexus-Mods/node-nexus-api#oauth":
version "1.4.7"
resolved "https://codeload.github.com/Nexus-Mods/node-nexus-api/tar.gz/efaeb06a350c508d29bdb772c4c43d904e3ce644"
version "1.4.16"
resolved "https://codeload.github.com/Nexus-Mods/node-nexus-api/tar.gz/d94f0745a6c0a215228998b778bc5371ec49c215"
dependencies:
form-data "^4.0.0"
jsonwebtoken "^9.0.0"
Expand Down
20 changes: 10 additions & 10 deletions src/extensions/nexus_integration/eventHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import * as semver from 'semver';
import { format as urlFormat } from 'url';
import { ITokenReply } from './util/oauth';
import { isLoggedIn } from './selectors';
import { getUserInfo } from './util/api';
//import { getUserInfo } from './util/api';

export function onChangeDownloads(api: IExtensionApi, nexus: Nexus) {
const state: IState = api.store.getState();
Expand Down Expand Up @@ -99,7 +99,7 @@ export function onChangeDownloads(api: IExtensionApi, nexus: Nexus) {
updateDebouncer.schedule(undefined, newValue);
}


/*
export function onForceTokenRefresh(api: IExtensionApi, nexus: Nexus) {
return () => {
Expand All @@ -121,7 +121,7 @@ export function onForceTokenRefresh(api: IExtensionApi, nexus: Nexus) {
nexus.forceJwtRefresh();
}
}
}
}*/



Expand Down Expand Up @@ -756,17 +756,17 @@ export function onGetLatestMods(api: IExtensionApi, nexus: Nexus) {
}


export function onRefreshUserInfo(api: IExtensionApi) {
export function onRefreshUserInfo(nexus: Nexus, api: IExtensionApi) {
return (): Promise<void> => {

const token = getOAuthTokenFromState(api);
//const token = getOAuthTokenFromState(api);

//log('info', 'onRefreshUserInfo()', token);

// we have an oauth token in state
if(token !== undefined) {
//if(token !== undefined) {
// get userinfo from api
return Promise.resolve(getUserInfo(token))
return Promise.resolve(nexus.getUserInfo())
.then(apiUserInfo => {
api.store.dispatch(setUserInfo(transformUserInfoFromApi(apiUserInfo)));
log('info', 'onRefreshUserInfo()', apiUserInfo);
Expand All @@ -777,9 +777,9 @@ export function onRefreshUserInfo(api: IExtensionApi) {
allowReport: false,
});
});
} else {
log('warn', 'onRefreshUserInfo() no oauth token');
}
//} else {
// log('warn', 'onRefreshUserInfo() no oauth token');
//}
};
}

Expand Down
24 changes: 18 additions & 6 deletions src/extensions/nexus_integration/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setDownloadModInfo, setForcedLogout, setModAttribute } from '../../actions';
import { clearOAuthCredentials, setDownloadModInfo, setForcedLogout, setModAttribute } from '../../actions';
import { IDialogResult, showDialog } from '../../actions/notifications';
import { IExtensionApi, IExtensionContext } from '../../types/IExtensionContext';
import { IModLookupResult } from '../../types/IModLookupResult';
Expand Down Expand Up @@ -889,7 +889,7 @@ function extendAPI(api: IExtensionApi, nexus: NexusT): INexusAPIExtension
nexusModUpdate: eh.onModUpdate(api, nexus),
nexusOpenCollectionPage: eh.onOpenCollectionPage(api),
nexusOpenModPage: eh.onOpenModPage(api),
nexusRequestNexusLogin: callback => requestLogin(api, callback),
nexusRequestNexusLogin: callback => requestLogin(nexus, api, callback),
nexusRequestOwnIssues: eh.onRequestOwnIssues(nexus),
nexusRetrieveCategoryList: (isUpdate: boolean) => retrieveCategories(api, isUpdate),
nexusGetModFiles: eh.onGetModFiles(api, nexus),
Expand Down Expand Up @@ -1004,9 +1004,10 @@ function once(api: IExtensionApi, callbacks: Array<(nexus: NexusT) => void>) {
} else {

if (oauthCred !== undefined) {
log('info', 'OAuth credentials found in state. Updating nexus token');
updateToken(api, nexus, oauthCred);
} else {
updateKey(api, nexus, apiKey);
//updateKey(api, nexus, apiKey);
}
}

Expand All @@ -1026,7 +1027,7 @@ function once(api: IExtensionApi, callbacks: Array<(nexus: NexusT) => void>) {
// register when window is focussed to do a userinfo check?
getApplication().window.on('focus', (event, win) => {
console.log('browser-window-focus');
userInfoDebouncer.schedule();
//userInfoDebouncer.schedule();
})
}

Expand All @@ -1041,15 +1042,15 @@ function once(api: IExtensionApi, callbacks: Array<(nexus: NexusT) => void>) {
api.onAsync('endorse-nexus-mod', eh.onEndorseDirect(api, nexus));
api.onAsync('get-latest-mods', eh.onGetLatestMods(api, nexus));
api.onAsync('get-trending-mods', eh.onGetTrendingMods(api, nexus));
api.events.on('refresh-user-info', eh.onRefreshUserInfo(api));
api.events.on('refresh-user-info', eh.onRefreshUserInfo(nexus, api));
//api.events.on('force-token-refresh', eh.onForceTokenRefresh(api, nexus));
api.events.on('endorse-mod', eh.onEndorseMod(api, nexus));
api.events.on('submit-feedback', eh.onSubmitFeedback(nexus));
api.events.on('submit-collection', eh.onSubmitCollection(nexus));
api.events.on('mod-update', eh.onModUpdate(api, nexus));
api.events.on('open-collection-page', eh.onOpenCollectionPage(api));
api.events.on('open-mod-page', eh.onOpenModPage(api));
api.events.on('request-nexus-login', callback => requestLogin(api, callback));
api.events.on('request-nexus-login', callback => requestLogin(nexus, api, callback));
api.events.on('request-own-issues', eh.onRequestOwnIssues(nexus));
api.events.on('retrieve-category-list', (isUpdate: boolean) => {
retrieveCategories(api, isUpdate);
Expand Down Expand Up @@ -1530,6 +1531,17 @@ function init(context: IExtensionContextExt): boolean {

const tracking = new Tracking(context.api);

/*
context.registerAction('global-icons', 100, 'feedback', {}, 'Clear OAuth State', () => {
log('info', 'Clear OAuth State');
context.api.store.dispatch(clearOAuthCredentials(null));
});*/

context.registerAction('global-icons', 100, 'nexus', {}, 'Refresh User Info', () => {
log('info', 'Refresh User Info');
context.api.events.emit('refresh-user-info');
});

context.registerAction('mods-action-icons', 300, 'smart', {}, 'Fix missing IDs',
instanceIds => { fixIds(context.api, instanceIds); },
instanceIds => includesMissingMetaId(context.api, instanceIds));
Expand Down
69 changes: 44 additions & 25 deletions src/extensions/nexus_integration/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ const oauth = new OAuth({
redirectUrl: OAUTH_REDIRECT_URL,
});

export function requestLogin(api: IExtensionApi, callback: (err: Error) => void) {
export function requestLogin(nexus: Nexus, api: IExtensionApi, callback: (err: Error) => void) {
const stackErr = new Error();

return oauth.sendRequest(async (err: Error, token: ITokenReply) => {
Expand All @@ -256,10 +256,10 @@ export function requestLogin(api: IExtensionApi, callback: (err: Error) => void)

api.store.dispatch(setOAuthCredentials(token.access_token, token.refresh_token, tokenDecoded.fingerprint));

const apiUserInfo = await getUserInfo(token.access_token);
//const apiUserInfo = await getUserInfo(nexus);

api.store.dispatch(setUserInfo(transformUserInfoFromApi(apiUserInfo)));
log('info', 'apiUserInfo', apiUserInfo);
//api.store.dispatch(setUserInfo(transformUserInfoFromApi(apiUserInfo)));
//log('info', 'apiUserInfo', apiUserInfo);

callback(null);

Expand Down Expand Up @@ -403,6 +403,7 @@ function startDownloadCollection(api: IExtensionApi,
});
}

/*
export function getUserInfo(token:string) : Promise<NexusAPI.IUserInfo> {
return Promise.resolve((async () => {
try {
Expand All @@ -413,6 +414,18 @@ export function getUserInfo(token:string) : Promise<NexusAPI.IUserInfo> {
throw err;
}
})());
}*/

export function getUserInfo(nexus: Nexus) : Promise<NexusAPI.IUserInfo> {
return Promise.resolve((async () => {
try {
const userInfo = await nexus.getUserInfo();
return userInfo;
} catch (err) {
err['attachLogOnReport'] = true;
throw err;
}
})());
}

export interface IRemoteInfo {
Expand Down Expand Up @@ -1301,7 +1314,7 @@ export function getOAuthTokenFromState(api: IExtensionApi) {
const apiKey = state.confidential.account?.['nexus']?.['APIKey'];
const oauthCred:IOAuthCredentials = state.confidential.account?.['nexus']?.['OAuthCredentials'];

log('info', 'getOAuthTokenFromState()', { apiKey: apiKey, oauthCred: oauthCred });
//log('info', 'getOAuthTokenFromState()');
//log('info', 'api key', apiKey !== undefined);
//log('info', 'oauth cred', oauthCred !== undefined);

Expand All @@ -1313,6 +1326,8 @@ function updateUserInfo(api: IExtensionApi,
/*userInfo: IValidateKeyResponse*/)
: Promise<boolean> {



log('info', 'updateUserInfo()')

/**
Expand All @@ -1321,28 +1336,27 @@ function updateUserInfo(api: IExtensionApi,
* from the nexus api instead of the information that was supplied in
* oauth token itself as this could be out of date
*/
const token = getOAuthTokenFromState(api);
//const token = getOAuthTokenFromState(api);

// we have an oauth token in state
if(token !== undefined) {
if(isLoggedIn(api.getState())) {

// get userinfo from api
return getUserInfo(token)
.then(apiUserInfo => {
// update state with new info from endpoint
api.store.dispatch(setUserInfo(transformUserInfoFromApi(apiUserInfo)));
log('info', 'apiUserInfo', apiUserInfo);
return true;
})
.catch((err) => {
log('error', `onRefreshUserInfo() ${err.message}`, err);
showError(api.store.dispatch, 'An error occurred refreshing user info', err, {
allowReport: false,
return getUserInfo(nexus)
.then(apiUserInfo => {
// update state with new info from endpoint
api.store.dispatch(setUserInfo(transformUserInfoFromApi(apiUserInfo)));
log('info', 'apiUserInfo', apiUserInfo);
return true;
})
.catch((err) => {
log('error', `onRefreshUserInfo() ${err.message}`, err);
showError(api.store.dispatch, 'An error occurred refreshing user info', err, {
allowReport: false,
});
return false;
});
return false;
});
} else {
log('warn', 'updateUserInfo() no oauth token');
log('warn', 'updateUserInfo() not logged in');
}

return github.fetchConfig('api')
Expand Down Expand Up @@ -1383,6 +1397,9 @@ export function updateToken(api: IExtensionApi,
nexus: Nexus,
token: any)
: Promise<boolean> {

log('info', 'updateToken()', token);

setOauthToken(token);

return Promise.resolve(nexus.setOAuthCredentials({
Expand All @@ -1392,7 +1409,8 @@ export function updateToken(api: IExtensionApi,
}, {
id: OAUTH_CLIENT_ID,
}, (credentials: IOAuthCredentials) => onJWTTokenRefresh(api, credentials)))
.then(userInfo => updateUserInfo(api, nexus))
.then(userInfo => updateUserInfo(api, nexus))
.then(() => true)
.catch(err => {
api.showErrorNotification('Authentication failed, please log in again', err, {
allowReport: false,
Expand All @@ -1407,8 +1425,9 @@ export function updateToken(api: IExtensionApi,

export function updateKey(api: IExtensionApi, nexus: Nexus, key: string): Promise<boolean> {
setApiKey(key);
return Promise.resolve(nexus.setKey(key))
.then(userInfo => updateUserInfo(api, nexus))
return Promise.resolve(nexus.setKey(key))
.then(() => true)
//.then(userInfo => updateUserInfo(api, nexus))
// don't stop the login just because the github rate limit is exceeded
.catch(RateLimitExceeded, () => Promise.resolve(true))
.catch(TimeoutError, err => {
Expand Down
3 changes: 2 additions & 1 deletion src/extensions/nexus_integration/util/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface IUserInfo {
premium_expiry: number;
}

/*
export async function getUserInfo(token: string): Promise<IUserInfo> {
const headers: Headers = new Headers()
Expand Down Expand Up @@ -38,4 +39,4 @@ export async function getUserInfo(token: string): Promise<IUserInfo> {
const userInfo:IUserInfo = await response.json();
return userInfo;
}
}*/
3 changes: 2 additions & 1 deletion src/extensions/nexus_integration/views/LoginIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class LoginIcon extends ComponentEx<IProps, {}> {
const { userInfo } = this.props;

//this.context.api.events.emit('force-token-refresh');
this.context.api.events.emit('refresh-user-info');
//this.context.api.events.emit('refresh-user-info');

if (!this.isLoggedIn()) {
this.context.api.events.emit('analytics-track-click-event', 'Profile', 'Site profile');
Expand All @@ -182,6 +182,7 @@ class LoginIcon extends ComponentEx<IProps, {}> {

private isLoggedIn() {
const { isLoggedIn, userInfo } = this.props;
//return isLoggedIn;
return isLoggedIn && (userInfo !== undefined) && (userInfo !== null);
}

Expand Down
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1698,8 +1698,8 @@
integrity sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==

"@nexusmods/nexus-api@Nexus-Mods/node-nexus-api#oauth":
version "1.4.12"
resolved "https://codeload.github.com/Nexus-Mods/node-nexus-api/tar.gz/783984d4ef1f994621540e6b0f3365c59eb2ccf2"
version "1.4.16"
resolved "https://codeload.github.com/Nexus-Mods/node-nexus-api/tar.gz/d94f0745a6c0a215228998b778bc5371ec49c215"
dependencies:
form-data "^4.0.0"
jsonwebtoken "^9.0.0"
Expand Down

0 comments on commit 252b66f

Please sign in to comment.