From dd55ec6072759610f78bfb74319ad7d48d567c20 Mon Sep 17 00:00:00 2001 From: spacemeowx2 Date: Tue, 18 Oct 2022 21:16:51 +0800 Subject: [PATCH] feat: save session token to config --- .gitignore | 2 ++ deps.ts | 4 ++- iksm.ts | 9 ++++--- s3si.ts | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- state.ts | 5 ++++ utils.ts | 12 ++++++++- 6 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a62cf7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.json +.vscode/ diff --git a/deps.ts b/deps.ts index 62d8cee..e674c6a 100644 --- a/deps.ts +++ b/deps.ts @@ -3,4 +3,6 @@ export { CookieJar, wrapFetch, } from "https://deno.land/x/another_cookiejar@v4.1.4/mod.ts"; -export * as base64 from "https://deno.land/std@0.95.0/encoding/base64.ts"; +export * as base64 from "https://deno.land/std@0.160.0/encoding/base64.ts"; +export * as flags from "https://deno.land/std@0.160.0/flags/mod.ts"; +export * as io from "https://deno.land/std@0.160.0/io/mod.ts"; diff --git a/iksm.ts b/iksm.ts index 4307caf..9d43cdc 100644 --- a/iksm.ts +++ b/iksm.ts @@ -1,6 +1,6 @@ import { CookieJar, wrapFetch } from "./deps.ts"; import { LoginState } from "./state.ts"; -import { urlBase64Encode } from "./utils.ts"; +import { readline, urlBase64Encode } from "./utils.ts"; const NSOAPP_VERSION = "2.3.1"; @@ -95,10 +95,11 @@ export async function loginManually(): Promise { console.log("Navigate to this URL in your browser:"); console.log(res.url); - - const login = prompt( - 'Log in, right click the "Select this account" button, copy the link address, and paste it below:\n', + console.log( + 'Log in, right click the "Select this account" button, copy the link address, and paste it below:', ); + + const login = await readline(); if (!login) { throw new Error("No login URL provided"); } diff --git a/s3si.ts b/s3si.ts index 528cd7e..2f7feb1 100644 --- a/s3si.ts +++ b/s3si.ts @@ -1,4 +1,77 @@ import { loginManually } from "./iksm.ts"; +import { flags } from "./deps.ts"; +import { DEFAULT_STATE, State } from "./state.ts"; -const state = await loginManually(); -console.log(state); +type Opts = { + configPath: string; + help?: boolean; +}; + +const DEFAULT_OPTS = { + configPath: "./config.json", + help: false, +}; + +class App { + state: State = DEFAULT_STATE; + constructor(public opts: Opts) { + if (this.opts.help) { + console.log( + `Usage: deno run --allow-net --allow-read --allow-write ${Deno.mainModule} [options] + +Options: + --config-path Path to config file (default: ./config.json) + --help Show this help message and exit`, + ); + Deno.exit(0); + } + } + async writeState() { + const encoder = new TextEncoder(); + const data = encoder.encode(JSON.stringify(this.state, undefined, 2)); + await Deno.writeFile(this.opts.configPath + ".swap", data); + await Deno.rename(this.opts.configPath + ".swap", this.opts.configPath); + } + async readState() { + const decoder = new TextDecoder(); + try { + const data = await Deno.readFile(this.opts.configPath); + const json = JSON.parse(decoder.decode(data)); + this.state = json; + } catch (e) { + console.warn( + `Failed to read config file, create new config file. (${e})`, + ); + await this.writeState(); + } + } + async run() { + await this.readState(); + if (!this.state.loginState?.sessionToken) { + const { sessionToken } = await loginManually(); + this.state.loginState = { + ...this.state.loginState, + sessionToken, + }; + await this.writeState(); + } + } +} + +const parseArgs = (args: string[]) => { + const parsed = flags.parse(args, { + string: ["configPath"], + boolean: ["help"], + alias: { + "help": "h", + "configPath": ["c", "config-path"], + }, + }); + return parsed; +}; + +const app = new App({ + ...DEFAULT_OPTS, + ...parseArgs(Deno.args), +}); +await app.run(); diff --git a/state.ts b/state.ts index 94112ab..6cc651b 100644 --- a/state.ts +++ b/state.ts @@ -1,3 +1,8 @@ export type LoginState = { sessionToken: string; }; +export type State = { + loginState?: LoginState; +}; + +export const DEFAULT_STATE: State = {}; diff --git a/utils.ts b/utils.ts index 53545cb..3b315a0 100644 --- a/utils.ts +++ b/utils.ts @@ -1,4 +1,6 @@ -import { base64 } from "./deps.ts"; +import { base64, io } from "./deps.ts"; + +const stdinLines = io.readLines(Deno.stdin); export function urlBase64Encode(data: ArrayBuffer) { return base64.encode(data) @@ -14,3 +16,11 @@ export function urlBase64Decode(data: string) { .replaceAll("-", "/"), ); } + +export async function readline() { + for await (const line of stdinLines) { + if (line !== "") { + return line; + } + } +}