Increase limit for parental controls

This commit is contained in:
Samuel Elliott 2022-07-27 16:12:38 +01:00
parent 3bb18d0b46
commit bd1cd6cf91
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
3 changed files with 13 additions and 8 deletions

View File

@ -65,7 +65,7 @@ export async function getToken(
const existingToken: SavedToken | undefined = await storage.getItem('NsoToken.' + token);
if (!existingToken || existingToken.expires_at <= Date.now()) {
if (ratelimit) await checkUseLimit(storage, 'coral', jwt.payload.sub);
await checkUseLimit(storage, 'coral', jwt.payload.sub, ratelimit);
console.warn('Authenticating to Nintendo Switch Online app');
debug('Authenticating to znc with session token');

View File

@ -4,10 +4,13 @@ import { ZNMA_CLIENT_ID } from '../../api/moon.js';
import { NintendoAccountSessionTokenJwtPayload, NintendoAccountToken, NintendoAccountUser } from '../../api/na.js';
import { Jwt } from '../../util/jwt.js';
import MoonApi from '../../api/moon.js';
import { checkUseLimit, SHOULD_LIMIT_USE } from './util.js';
import { checkUseLimit, LIMIT_REQUESTS, SHOULD_LIMIT_USE } from './util.js';
const debug = createDebug('nxapi:auth:moon');
// Higher rate limit for parental controls, as the token expires sooner
const LIMIT_PERIOD = 15 * 60 * 1000; // 15 minutes
export interface SavedMoonToken {
nintendoAccountToken: NintendoAccountToken;
user: NintendoAccountUser;
@ -41,7 +44,7 @@ export async function getPctlToken(storage: persist.LocalStorage, token: string,
const existingToken: SavedMoonToken | undefined = await storage.getItem('MoonToken.' + token);
if (!existingToken || existingToken.expires_at <= Date.now()) {
if (ratelimit) await checkUseLimit(storage, 'moon', jwt.payload.sub);
await checkUseLimit(storage, 'moon', jwt.payload.sub, ratelimit, [LIMIT_REQUESTS, LIMIT_PERIOD]);
console.warn('Authenticating to Nintendo Switch Parental Controls app');
debug('Authenticating to pctl with session token');

View File

@ -9,19 +9,21 @@ const debug = createDebug('nxapi:auth:util');
// if it fails. The Electron app overrides this as the parent process (probably) won't be a
// terminal, but most attempts to call getToken won't be automated.
export const SHOULD_LIMIT_USE = !process.stdout.isTTY;
const LIMIT_REQUESTS = 4;
const LIMIT_PERIOD = 60 * 60 * 1000; // 60 minutes
export const LIMIT_REQUESTS = 4;
export const LIMIT_PERIOD = 60 * 60 * 1000; // 60 minutes
type RateLimitAttempts = number[];
export async function checkUseLimit(
storage: persist.LocalStorage,
key: string, user: string
key: string, user: string,
/** Set to false to count the attempt but ignore the limit */ ratelimit = true,
/** [requests, period_ms] */ limits: [number, number] = [LIMIT_REQUESTS, LIMIT_PERIOD]
) {
let attempts: RateLimitAttempts = await storage.getItem('RateLimitAttempts-' + key + '.' + user) ?? [];
attempts = attempts.filter(a => a >= Date.now() - LIMIT_PERIOD);
attempts = attempts.filter(a => a >= Date.now() - limits[1]);
if (attempts.length >= LIMIT_REQUESTS) {
if (ratelimit && attempts.length >= limits[0]) {
throw new Error('Too many attempts to authenticate');
}