Fix web service ID type in token request, handle errors requesting a new token

This commit is contained in:
Samuel Elliott
2022-09-10 16:50:19 +01:00
parent 0b91bf87db
commit c9c91a874d
10 changed files with 57 additions and 27 deletions

View File

@@ -205,7 +205,7 @@ export default class CoralApi {
});
}
async getWebServiceToken(id: string) {
async getWebServiceToken(id: number) {
const data = await f(this.token, HashMethod.WEB_SERVICE, this.useragent ?? getAdditionalUserAgents());
const req = {

View File

@@ -9,7 +9,7 @@ import { timeoutSignal } from '../util/misc.js';
const debug = createDebug('nxapi:api:nooklink');
export const NOOKLINK_WEBSERVICE_ID = '4953919198265344';
export const NOOKLINK_WEBSERVICE_ID = 4953919198265344;
export const NOOKLINK_WEBSERVICE_URL = 'https://web.sd.lp1.acbaa.srv.nintendo.net';
export const NOOKLINK_WEBSERVICE_USERAGENT = 'Mozilla/5.0 (Linux; Android 8.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.125 Mobile Safari/537.36';

View File

@@ -11,7 +11,7 @@ import { toSeasonId, Rule as XPowerRankingRule, Season } from './splatnet2-xrank
const debug = createDebug('nxapi:api:splatnet2');
export const SPLATNET2_WEBSERVICE_ID = '5741031244955648';
export const SPLATNET2_WEBSERVICE_ID = 5741031244955648;
export const SPLATNET2_WEBSERVICE_URL = 'https://app.splatoon2.nintendo.net/';
export const SPLATNET2_WEBSERVICE_USERAGENT = 'Mozilla/5.0 (Linux; Android 8.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.125 Mobile Safari/537.36';

View File

@@ -9,7 +9,7 @@ import { BankaraBattleHistoriesResult, BattleHistoryCurrentPlayerResult, BulletT
const debug = createDebug('nxapi:api:splatnet3');
export const SPLATNET3_WEBSERVICE_ID = '4834290508791808';
export const SPLATNET3_WEBSERVICE_ID = 4834290508791808;
export const SPLATNET3_WEBSERVICE_URL = 'https://api.lp1.av5ja.srv.nintendo.net';
export const SPLATNET3_WEBSERVICE_USERAGENT = 'Mozilla/5.0 (Linux; Android 8.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.125 Mobile Safari/537.36';

View File

@@ -132,7 +132,7 @@ export default class ZncProxyApi implements CoralApi {
throw new Error('Not supported in ZncProxyApi');
}
async getWebServiceToken(id: string) {
async getWebServiceToken(id: number) {
const result = await this.fetch<{token: WebServiceToken}>('/webservice/' + id + '/token');
return createResult(result, result.token);
}

View File

@@ -64,9 +64,8 @@ export function setupIpc(appinstance: App, ipcMain: IpcMain) {
store.users.get(token).then(u => openWebService(store, token, u.nso, u.data, webservice, qs)
.catch(err => dialog.showMessageBox(BrowserWindow.fromWebContents(e.sender)!, {
type: 'error',
title: (err instanceof Error ? err.name : 'Error') + ' opening web service',
message: err.message,
detail: (err instanceof Error ? err.stack ?? '' : err) + '\n\n' + util.inspect({
message: (err instanceof Error ? err.name : 'Error') + ' opening web service',
detail: (err instanceof Error ? err.stack ?? err.message : err) + '\n\n' + util.inspect({
webservice: {
id: webservice.id,
name: webservice.name,

View File

@@ -2,8 +2,9 @@ import * as path from 'node:path';
import { constants } from 'node:fs';
import * as fs from 'node:fs/promises';
import { Buffer } from 'node:buffer';
import * as util from 'node:util';
import createDebug from 'debug';
import { app, BrowserWindow, dialog, IpcMainInvokeEvent, Menu, MenuItem, nativeTheme, ShareMenu, shell, WebContents } from './electron.js';
import { app, BrowserWindow, dialog, IpcMainInvokeEvent, nativeTheme, ShareMenu, shell, WebContents } from './electron.js';
import fetch from 'node-fetch';
import CoralApi from '../../api/coral.js';
import { dev } from '../../util/product.js';
@@ -76,7 +77,7 @@ export default async function openWebService(
return {action: 'deny'};
});
const webserviceToken = await nso.getWebServiceToken('' + webservice.id);
const webserviceToken = await nso.getWebServiceToken(webservice.id);
const url = new URL(webservice.uri);
url.search = new URLSearchParams({
@@ -277,13 +278,43 @@ export class WebServiceIpc {
}
async requestGameWebToken(event: IpcMainInvokeEvent): Promise<string> {
const {nso, nsoAccount, webservice} = this.getWindowData(event.sender);
const {nso, user, nsoAccount, webservice} = this.getWindowData(event.sender);
debug('Web service %s, user %s, called requestGameWebToken', webservice.name, nsoAccount.user.name);
const webserviceToken = await nso.getWebServiceToken('' + webservice.id);
try {
const webserviceToken = await nso.getWebServiceToken(webservice.id);
return webserviceToken.accessToken;
return webserviceToken.accessToken;
} catch (err) {
const window = BrowserWindow.fromWebContents(event.sender)!;
const result = await dialog.showMessageBox(window, {
type: 'error',
message: (err instanceof Error ? err.name : 'Error') + ' requesting web service token',
detail: (err instanceof Error ? err.stack ?? err.message : err) + '\n\n' + util.inspect({
webservice: {
id: webservice.id,
name: webservice.name,
uri: webservice.uri,
},
user_na_id: user.id,
user_nsa_id: nsoAccount.user.nsaId,
user_coral_id: nsoAccount.user.id,
}, {compact: true}),
buttons: ['Retry', 'Close ' + webservice.name, 'Ignore'],
});
if (result.response === 0) {
return this.requestGameWebToken(event);
}
if (result.response === 1) {
window.close();
throw new Error('Error requesting web service token, closing web service');
}
throw err;
}
}
async restorePersistentData(event: IpcMainInvokeEvent): Promise<string | undefined> {

View File

@@ -43,14 +43,18 @@ declare global {
// Unused
sendMessage?(data: string): void;
// Unused
// SplatNet 3
copyToClipboard?(data: string): void;
// SplatNet 3
openQRCodeReaderForCheckin?(data: string): void;
onQRCodeReadForCheckin?(data: string): void;
// SplatNet 3
downloadImages?(imagesJson: string): void;
// SplatNet 3
completeLoading?(): void;
// SplatNet 3
closeWebView?(): void;
// SplatNet 3
reloadExtension?(): void;
}
}
@@ -58,8 +62,6 @@ declare global {
//
// Share
//
// Used by SplatNet 2 and Smash World (but both have a different implementation because Nintendo)
//
export interface NativeShareRequest {
text: string;
@@ -90,14 +92,14 @@ window.invokeNativeShareUrl = invokeNativeShareUrl;
//
// Web service token
//
// Used by NookLink
//
function requestGameWebToken() {
debug('requestGameWebToken called');
ipc.requestGameWebToken().then(token => {
window.onGameWebTokenReceive?.call(null, token);
}).catch(async err => {
debug('Error requesting web service token', err);
});
}
@@ -106,8 +108,6 @@ window.requestGameWebToken = requestGameWebToken;
//
// Persistent data
//
// Used by NookLink
//
function restorePersistentData() {
debug('restorePersistentData called');
@@ -131,8 +131,6 @@ window.storePersistentData = storePersistentData;
//
// QR code scanner
//
// Used by NookLink
//
function openQrCodeReader(data: string) {
debug('openQRCodeReader called', data);
@@ -179,14 +177,16 @@ window.openQRCodeReaderForCheckin = openQRCodeReaderForCheckin;
function sendMessage(data: string) {
//
debug('sendMessage called', data);
}
function copyToClipboard(data: string) {
//
debug('copyToClipboard called', data);
}
function downloadImages(imagesJson: string) {
//
debug('downloadImages called', imagesJson);
}
function completeLoading() {
@@ -198,7 +198,7 @@ function closeWebView() {
}
function reloadExtension() {
//
debug('reloadExtension called');
}
window.sendMessage = sendMessage;

View File

@@ -627,7 +627,7 @@ function createApp(
app.get('/api/znc/webservice/:id/token', nsoAuth, async (req, res) => {
try {
const token = await req.znc!.getWebServiceToken(req.params.id);
const token = await req.znc!.getWebServiceToken(parseInt(req.params.id));
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({token}));

View File

@@ -61,7 +61,7 @@ export async function handler(argv: ArgumentsCamelCase<Arguments>) {
if (!active) throw new Error('Nintendo Switch Online membership required');
}
const webserviceToken = await nso.getWebServiceToken(argv.id);
const webserviceToken = await nso.getWebServiceToken(webservice.id);
// https://app.splatoon2.nintendo.net/?lang=en-GB&na_country=GB&na_lang=en-GB
const url = new URL(webservice.uri);