Update third-party API usage text

This commit is contained in:
Samuel Elliott
2025-07-25 21:10:34 +01:00
parent 706e41133d
commit 8492db43d9
5 changed files with 45 additions and 41 deletions

View File

@@ -107,15 +107,6 @@ export const na_auth = {
znca_api_use: {
title: 'Verwendung einer Drittanbieter-API',
text: `Um Zugriff auf die API der Nintendo Switch Online App zu erhalten, muss nxapi einige Daten an Drittanbieter-APIs senden. Dieser Schritt wird benötigt, um Daten zu generieren, damit Nintendo denkt, dass du die echte Nintendo Switch Online App verwendest.
Standardmäßig wird nxapi-znca-api.fancy.org.uk oder api.imink.app benutzt. Ein anderer Service kann ebenfalls benutzt werden, indem eine Umgebungsvariable gesetzt wird. Die standardmäßige API könnte sich jederzeit ohne Hinweis ändern, wenn du keinen spezifischen Service erzwingst.
Die gesendeten Daten beinhalten:
- Deine Nintendo Account ID
- Bei Authorisierung mit der Nintendo Switch Online App: Ein Nintendo Account ID Token, welcher dein Land beinhaltet und für 15 Minuten gültig ist
- Bei Authorisierung mit Spielspezifischen Services: Deine Coral (Nintendo Switch Online App) User ID und ein Coral ID Token, welcher deine aktuelle Nintendo Switch Online Mitgliedschaft und Altersbeschränkungsstatus beinhaltet und für 2 Stunden gültig ist`,
ok: 'OK',
cancel: 'Abbrechen',
more_information: 'Weitere Informationen',

View File

@@ -107,16 +107,6 @@ export const na_auth = {
znca_api_use: {
title: 'Uso de API de terceros',
text: `Para acceder a la API de la aplicación Nintendo Switch Online, nxapi debe enviar algunos datos a APIs de terceros. Esto es necesario para generar ciertos datos y hacer que Nintendo piense que estás utilizando la aplicación real de Nintendo Switch Online.
Por defecto se utiliza nxapi-znca-api.fancy.org.uk o api.imink.app, pero se puede utilizar otro servicio mediante la configuración de una variable de entorno. La API predeterminada puede cambiar sin previo aviso si no se especifica un servicio específico.
Los datos enviados incluyen:
- La ID de tu cuenta Nintendo
- Al autenticar a la aplicación Nintendo Switch Online: un token de la cuenta Nintendo que contiene tu país, válido durante 15 minutos
- Al autenticar en servicios específicos de juegos: tu ID de usuario de Coral (aplicación Nintendo Switch Online) y un token ID de Coral que contiene tu estado de suscripción a Nintendo Switch Online y el estado de restricciones en tu cuenta, válido durante 2 horas`,
ok: 'OK',
cancel: 'Cancelar',
more_information: 'Más Información',

View File

@@ -12,7 +12,7 @@ import { createModalWindow, createWindow } from './windows.js';
import { sendToAllWindows, setupIpc } from './ipc.js';
import { askUserForUri, buildElectronProxyAgent, showErrorDialog } from './util.js';
import { setAppInstance, updateMenuLanguage } from './app-menu.js';
import { handleAuthUri } from './na-auth.js';
import { checkZncaApiUseAllowed, handleAuthUri } from './na-auth.js';
import { DiscordPresenceConfiguration, LoginItem, LoginItemOptions, WindowType } from '../common/types.js';
import { init as initGlobals } from '../../common/globals.js';
import { CREDITS_NOTICE, GITLAB_URL, LICENCE_NOTICE } from '../../common/constants.js';
@@ -413,6 +413,32 @@ export class Store extends EventEmitter {
// ratelimit = false, as most users.get calls are triggered by user interaction (or at startup)
this.users = Users.coral(this, process.env.ZNC_PROXY_URL, false);
this.setAskZncaApiConsent();
}
private _znca_api_use_consent_promise: Promise<void> | null = null;
private setAskZncaApiConsent() {
// @ts-expect-error
const get_user = this.users._get;
// @ts-expect-error
this.users._get = async token => {
if (!this._znca_api_use_consent_promise) {
this._znca_api_use_consent_promise = checkZncaApiUseAllowed(this.app)
// Don't clear _znca_api_use_consent_promise on completion as if successful this
// doesn't need to be called again anyway
.catch(err => {
this._znca_api_use_consent_promise = null;
throw err;
});
}
await this._znca_api_use_consent_promise;
return get_user.call(null, token);
};
}
async getLoginItem(): Promise<LoginItem> {

View File

@@ -11,7 +11,7 @@ import { getToken } from '../../common/auth/coral.js';
import { getPctlToken } from '../../common/auth/moon.js';
import createDebug from '../../util/debug.js';
import { Jwt } from '../../util/jwt.js';
import { ZNCA_API_USE_TEXT, ZNCA_API_USE_URL } from '../../common/constants.js';
import { ZNCA_API_USE_TEXT, ZNCA_API_USE_URL, ZNCA_API_USE_VERSION } from '../../common/constants.js';
import { InvalidNintendoAccountTokenError } from '../../common/auth/na.js';
const debug = createDebug('app:main:na-auth');
@@ -395,32 +395,25 @@ export async function askAddNsoAccount(app: App, iab = true) {
}
}
async function checkZncaApiUseAllowed(app: App, window?: BrowserWindow, force = false) {
export async function checkZncaApiUseAllowed(app: App, window?: BrowserWindow, force = false) {
if (!force) {
if (await app.store.storage.getItem('ZncaApiConsent')) {
const saved = await app.store.storage.getItem('ZncaApiConsent');
const consent_version = typeof saved === 'number' ? saved :
typeof saved === 'boolean' ? (saved ? 1 : null) : null;
if (consent_version && consent_version === ZNCA_API_USE_VERSION) {
return;
}
if (process.env.ZNC_PROXY_URL) {
debug('Skipping znca API consent; znc proxy URL set');
await app.store.storage.setItem('ZncaApiConsent', true);
return;
}
const ids: string[] | undefined = await app.store.storage.getItem('NintendoAccountIds');
for (const id of ids ?? []) {
const nsotoken: string | undefined = await app.store.storage.getItem('NintendoAccountToken.' + id);
if (!nsotoken) continue;
debug('Skipping znca API consent; Nintendo Switch Online account already linked');
await app.store.storage.setItem('ZncaApiConsent', true);
await app.store.storage.setItem('ZncaApiConsent', ZNCA_API_USE_VERSION);
return;
}
}
if (await askZncaApiUseAllowed(app, window)) {
await app.store.storage.setItem('ZncaApiConsent', true);
await app.store.storage.setItem('ZncaApiConsent', ZNCA_API_USE_VERSION);
} else {
throw new Error('Cannot continue without third-party APIs allowed');
}

View File

@@ -21,14 +21,18 @@ export const CREDITS_NOTICE = `
This product uses services provided by Nintendo (https://nintendo.co.jp), Samuel Elliott (https://gitlab.fancy.org.uk/samuel/nxapi-znca-api) and Jone Wang (https://imink.app).
`.trim();
export const ZNCA_API_USE_TEXT = `
To access the Nintendo Switch Online app API, nxapi must send some data to third-party APIs. This is required to generate some data to make Nintendo think you\'re using the real Nintendo Switch Online app.
export const ZNCA_API_USE_VERSION = 2;
By default, this uses nxapi-znca-api.fancy.org.uk or api.imink.app, but another service can be used by setting an environment variable. The default API may change without notice if you do not force use of a specific service.
export const ZNCA_API_USE_TEXT = `
To access the Nintendo Switch App API, nxapi must send some data to third-party APIs. This is required to make Nintendo\'s API think you\'re using the real Nintendo Switch App.
This uses nxapi-znca-api.fancy.org.uk, but another service can be used by setting an environment variable. The default API may change without notice if you do not force use of a specific service.
The data sent includes:
- Your Nintendo Account ID
- When authenticating to the Nintendo Switch Online app: a Nintendo Account ID token, containing your Nintendo Account country, which is valid for 15 minutes
- When authenticating to game-specific services: your Coral (Nintendo Switch Online app) user ID and a Coral ID token, containing your Nintendo Switch Online membership status, and Nintendo Account child restriction status, which is valid for 2 hours
- When authenticating to the Nintendo Switch App API: a Nintendo Account ID token, containing your Nintendo Account country
- When authenticating to game-specific services, your Coral (Nintendo Switch Online app) user ID and a Coral token, containing your Nintendo Switch Online membership status, and Nintendo Account child restriction status
Since June 2025 (v3.0.1), all data sent to/from the Nintendo Switch App API must also be sent for encryption.
`.trim();