refactor: use fetcher

main
spacemeowx2 2022-11-18 03:25:04 +08:00 committed by imspace
parent b9b71843ce
commit b5e314eaf1
3 changed files with 54 additions and 51 deletions

View File

@ -14,9 +14,9 @@ export async function readline(
} }
export type Fetcher = { export type Fetcher = {
get(opts: { url: string; headers?: Headers }): Promise<Response>; get(opts: { url: string; headers?: HeadersInit }): Promise<Response>;
post( post(
opts: { url: string; body: BodyInit; headers?: Headers }, opts: { url: string; body?: BodyInit; headers?: HeadersInit },
): Promise<Response>; ): Promise<Response>;
}; };

View File

@ -1,4 +1,3 @@
import { CookieJar, wrapFetch } from "../deps.ts";
import { retry, urlBase64Encode } from "./utils.ts"; import { retry, urlBase64Encode } from "./utils.ts";
import { import {
DEFAULT_APP_USER_AGENT, DEFAULT_APP_USER_AGENT,
@ -7,13 +6,12 @@ import {
WEB_VIEW_VERSION, WEB_VIEW_VERSION,
} from "./constant.ts"; } from "./constant.ts";
import { APIError } from "./APIError.ts"; import { APIError } from "./APIError.ts";
import { Env } from "./env.ts"; import { Env, Fetcher } from "./env.ts";
export async function loginManually( export async function loginManually(
{ logger, readline }: Env, { logger, readline, newFetcher }: Env,
): Promise<string> { ): Promise<string> {
const cookieJar = new CookieJar(); const fetch = newFetcher();
const fetch = wrapFetch({ cookieJar });
const state = urlBase64Encode(random(36)); const state = urlBase64Encode(random(36));
const authCodeVerifier = urlBase64Encode(random(32)); const authCodeVerifier = urlBase64Encode(random(32));
@ -36,10 +34,9 @@ export async function loginManually(
const url = "https://accounts.nintendo.com/connect/1.0.0/authorize?" + const url = "https://accounts.nintendo.com/connect/1.0.0/authorize?" +
new URLSearchParams(body); new URLSearchParams(body);
const res = await fetch( const res = await fetch.get(
url,
{ {
method: "GET", url,
headers: { headers: {
"Host": "accounts.nintendo.com", "Host": "accounts.nintendo.com",
"Connection": "keep-alive", "Connection": "keep-alive",
@ -73,7 +70,7 @@ export async function loginManually(
} }
const sessionToken = await getSessionToken({ const sessionToken = await getSessionToken({
cookieJar, fetch,
sessionTokenCode, sessionTokenCode,
authCodeVerifier, authCodeVerifier,
}); });
@ -85,12 +82,12 @@ export async function loginManually(
} }
export async function getGToken( export async function getGToken(
{ fApi, sessionToken }: { fApi: string; sessionToken: string }, { fApi, sessionToken, env }: { fApi: string; sessionToken: string; env: Env },
) { ) {
const idResp = await fetch( const fetch = env.newFetcher();
"https://accounts.nintendo.com/connect/1.0.0/api/token", const idResp = await fetch.post(
{ {
method: "POST", url: "https://accounts.nintendo.com/connect/1.0.0/api/token",
headers: { headers: {
"Host": "accounts.nintendo.com", "Host": "accounts.nintendo.com",
"Accept-Encoding": "gzip", "Accept-Encoding": "gzip",
@ -117,9 +114,9 @@ export async function getGToken(
}); });
} }
const uiResp = await fetch( const uiResp = await fetch.get(
"https://api.accounts.nintendo.com/2.0.0/users/me",
{ {
url: "https://api.accounts.nintendo.com/2.0.0/users/me",
headers: { headers: {
"User-Agent": "NASDKAPI; Android", "User-Agent": "NASDKAPI; Android",
"Content-Type": "application/json", "Content-Type": "application/json",
@ -139,11 +136,11 @@ export async function getGToken(
fApi, fApi,
step: 1, step: 1,
idToken, idToken,
env,
}); });
const resp = await fetch( const resp = await fetch.post(
"https://api-lp1.znc.srv.nintendo.net/v3/Account/Login",
{ {
method: "POST", url: "https://api-lp1.znc.srv.nintendo.net/v3/Account/Login",
headers: { headers: {
"X-Platform": "Android", "X-Platform": "Android",
"X-ProductVersion": NSOAPP_VERSION, "X-ProductVersion": NSOAPP_VERSION,
@ -184,11 +181,11 @@ export async function getGToken(
step: 2, step: 2,
idToken, idToken,
fApi, fApi,
env,
}); });
const resp = await fetch( const resp = await fetch.post(
"https://api-lp1.znc.srv.nintendo.net/v2/Game/GetWebServiceToken",
{ {
method: "POST", url: "https://api-lp1.znc.srv.nintendo.net/v2/Game/GetWebServiceToken",
headers: { headers: {
"X-Platform": "Android", "X-Platform": "Android",
"X-ProductVersion": NSOAPP_VERSION, "X-ProductVersion": NSOAPP_VERSION,
@ -240,30 +237,30 @@ export async function getBulletToken(
appUserAgent = DEFAULT_APP_USER_AGENT, appUserAgent = DEFAULT_APP_USER_AGENT,
userLang, userLang,
userCountry, userCountry,
env,
}: { }: {
webServiceToken: string; webServiceToken: string;
appUserAgent?: string; appUserAgent?: string;
userLang: string; userLang: string;
userCountry: string; userCountry: string;
env: Env;
}, },
) { ) {
const resp = await fetch( const { post } = env.newFetcher();
"https://api.lp1.av5ja.srv.nintendo.net/api/bullet_tokens", const resp = await post({
{ url: "https://api.lp1.av5ja.srv.nintendo.net/api/bullet_tokens",
method: "POST", headers: {
headers: { "Content-Type": "application/json",
"Content-Type": "application/json", "Accept-Language": userLang,
"Accept-Language": userLang, "User-Agent": appUserAgent,
"User-Agent": appUserAgent, "X-Web-View-Ver": WEB_VIEW_VERSION,
"X-Web-View-Ver": WEB_VIEW_VERSION, "X-NACOUNTRY": userCountry,
"X-NACOUNTRY": userCountry, "Accept": "*/*",
"Accept": "*/*", "Origin": "https://api.lp1.av5ja.srv.nintendo.net",
"Origin": "https://api.lp1.av5ja.srv.nintendo.net", "X-Requested-With": "com.nintendo.znca",
"X-Requested-With": "com.nintendo.znca", "Cookie": `_gtoken=${webServiceToken}`,
"Cookie": `_gtoken=${webServiceToken}`,
},
}, },
); });
if (resp.status == 401) { if (resp.status == 401) {
throw new APIError({ throw new APIError({
@ -311,20 +308,17 @@ function random(size: number): ArrayBuffer {
} }
async function getSessionToken({ async function getSessionToken({
cookieJar, fetch,
sessionTokenCode, sessionTokenCode,
authCodeVerifier, authCodeVerifier,
}: { }: {
cookieJar: CookieJar; fetch: Fetcher;
sessionTokenCode: string; sessionTokenCode: string;
authCodeVerifier: string; authCodeVerifier: string;
}): Promise<string | undefined> { }): Promise<string | undefined> {
const fetch = wrapFetch({ cookieJar }); const resp = await fetch.post(
const resp = await fetch(
"https://accounts.nintendo.com/connect/1.0.0/api/session_token",
{ {
method: "POST", url: "https://accounts.nintendo.com/connect/1.0.0/api/session_token",
headers: { headers: {
"User-Agent": `OnlineLounge/${NSOAPP_VERSION} NASDKAPI Android`, "User-Agent": `OnlineLounge/${NSOAPP_VERSION} NASDKAPI Android`,
"Accept-Language": "en-US", "Accept-Language": "en-US",
@ -358,10 +352,16 @@ type IminkResponse = {
timestamp: number; timestamp: number;
}; };
async function callImink( async function callImink(
{ fApi, step, idToken }: { fApi: string; step: number; idToken: string }, { fApi, step, idToken, env }: {
fApi: string;
step: number;
idToken: string;
env: Env;
},
): Promise<IminkResponse> { ): Promise<IminkResponse> {
const resp = await fetch(fApi, { const { post } = env.newFetcher();
method: "POST", const resp = await post({
url: fApi,
headers: { headers: {
"User-Agent": USERAGENT, "User-Agent": USERAGENT,
"Content-Type": "application/json; charset=utf-8", "Content-Type": "application/json; charset=utf-8",

View File

@ -41,8 +41,9 @@ export class Splatnet3 {
}, },
variables, variables,
}; };
const resp = await fetch(SPLATNET3_ENDPOINT, { const { post } = this.env.newFetcher();
method: "POST", const resp = await post({
url: SPLATNET3_ENDPOINT,
headers: { headers: {
"Authorization": `Bearer ${state.loginState?.bulletToken}`, "Authorization": `Bearer ${state.loginState?.bulletToken}`,
"Accept-Language": state.userLang ?? "en-US", "Accept-Language": state.userLang ?? "en-US",
@ -99,6 +100,7 @@ export class Splatnet3 {
const { webServiceToken, userCountry, userLang } = await getGToken({ const { webServiceToken, userCountry, userLang } = await getGToken({
fApi: state.fGen, fApi: state.fGen,
sessionToken, sessionToken,
env: this.env,
}); });
const bulletToken = await getBulletToken({ const bulletToken = await getBulletToken({
@ -106,6 +108,7 @@ export class Splatnet3 {
userLang, userLang,
userCountry, userCountry,
appUserAgent: state.appUserAgent, appUserAgent: state.appUserAgent,
env: this.env,
}); });
await this.profile.writeState({ await this.profile.writeState({