Add server to generate f parameters for NSO app authentication

This commit is contained in:
Samuel Elliott
2022-03-17 15:16:49 +00:00
parent 4de8373e0b
commit 2005f34780
8 changed files with 1108 additions and 76 deletions

View File

@@ -4,6 +4,7 @@ import { ErrorResponse } from './util.js';
const debugS2s = createDebug('api:s2s');
const debugFlapg = createDebug('api:flapg');
const debugZncaApi = createDebug('api:znca-api');
export async function getLoginHash(token: string, timestamp: string | number) {
debugS2s('Getting login hash');
@@ -56,6 +57,51 @@ export async function flapg(token: string, timestamp: string | number, guid: str
return data.result;
}
export async function genf(url: string, token: string, timestamp: string | number, uuid: string, type: FlapgIid) {
debugZncaApi('Getting f parameter', {
url, token, timestamp, uuid,
});
const req: AndroidZncaFRequest = {
type,
token,
timestamp: '' + timestamp,
uuid,
};
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(req),
});
const data = await response.json() as AndroidZncaFResponse | AndroidZncaFError;
if ('error' in data) {
debugZncaApi('Error getting f parameter "%s"', data.error);
throw new ErrorResponse('[znca-api] ' + data.error, response, data);
}
debugZncaApi('Got f parameter "%s"', data.f);
return data.f;
}
export async function genfc(url: string, token: string, timestamp: string | number, uuid: string, type: FlapgIid) {
const f = await genf(url, token, timestamp, uuid, type);
return {
f,
p1: token,
p2: '' + timestamp,
p3: uuid,
url,
};
}
export interface LoginHashApiResponse {
hash: string;
}
@@ -78,3 +124,16 @@ export interface FlapgApiResponse {
p3: string;
};
}
export interface AndroidZncaFRequest {
type: FlapgIid;
token: string;
timestamp: string;
uuid: string;
}
export interface AndroidZncaFResponse {
f: string;
}
export interface AndroidZncaFError {
error: string;
}

View File

@@ -1,7 +1,7 @@
import fetch from 'node-fetch';
import { v4 as uuidgen } from 'uuid';
import createDebug from 'debug';
import { flapg, FlapgIid } from './f.js';
import { flapg, FlapgIid, genfc } from './f.js';
import { AccountLogin, ActiveEvent, Announcement, CurrentUser, Friends, WebService, WebServiceToken, ZncResponse } from './znc-types.js';
import { getNintendoAccountToken, getNintendoAccountUser } from './na.js';
import { ErrorResponse } from './util.js';
@@ -76,14 +76,16 @@ export default class ZncApi {
const uuid = uuidgen();
const timestamp = '' + Math.floor(Date.now() / 1000);
const data = await flapg(nintendoAccountToken, timestamp, uuid, FlapgIid.APP);
const data = process.env.ZNCA_API_URL ?
await genfc(process.env.ZNCA_API_URL + '/f', nintendoAccountToken, timestamp, uuid, FlapgIid.APP) :
await flapg(nintendoAccountToken, timestamp, uuid, FlapgIid.APP);
const req = {
id,
registrationToken: nintendoAccountToken,
f: data.f,
requestId: data.p3,
timestamp: data.p2,
requestId: uuid,
timestamp,
};
return this.fetch<WebServiceToken>('/v2/Game/GetWebServiceToken', 'POST', JSON.stringify({
@@ -118,7 +120,9 @@ export default class ZncApi {
// Nintendo Account user data
const user = await getNintendoAccountUser(nintendoAccountToken);
const flapgdata = await flapg(nintendoAccountToken.id_token, timestamp, uuid, FlapgIid.NSO);
const flapgdata = process.env.ZNCA_API_URL ?
await genfc(process.env.ZNCA_API_URL + '/f', nintendoAccountToken.id_token, timestamp, uuid, FlapgIid.NSO) :
await flapg(nintendoAccountToken.id_token, timestamp, uuid, FlapgIid.NSO);
debug('Getting Nintendo Switch Online app token');
@@ -132,12 +136,12 @@ export default class ZncApi {
},
body: JSON.stringify({
parameter: {
naIdToken: flapgdata.p1,
naIdToken: nintendoAccountToken.id_token,
naBirthday: user.birthday,
naCountry: user.country,
language: user.language,
timestamp: flapgdata.p2,
requestId: flapgdata.p3,
timestamp,
requestId: uuid,
f: flapgdata.f,
},
}),