feat: save session token to config
parent
8fcb758c97
commit
dd55ec6072
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.json
|
||||||
|
.vscode/
|
||||||
4
deps.ts
4
deps.ts
|
|
@ -3,4 +3,6 @@ export {
|
||||||
CookieJar,
|
CookieJar,
|
||||||
wrapFetch,
|
wrapFetch,
|
||||||
} from "https://deno.land/x/another_cookiejar@v4.1.4/mod.ts";
|
} 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";
|
||||||
|
|
|
||||||
9
iksm.ts
9
iksm.ts
|
|
@ -1,6 +1,6 @@
|
||||||
import { CookieJar, wrapFetch } from "./deps.ts";
|
import { CookieJar, wrapFetch } from "./deps.ts";
|
||||||
import { LoginState } from "./state.ts";
|
import { LoginState } from "./state.ts";
|
||||||
import { urlBase64Encode } from "./utils.ts";
|
import { readline, urlBase64Encode } from "./utils.ts";
|
||||||
|
|
||||||
const NSOAPP_VERSION = "2.3.1";
|
const NSOAPP_VERSION = "2.3.1";
|
||||||
|
|
||||||
|
|
@ -95,10 +95,11 @@ export async function loginManually(): Promise<LoginState> {
|
||||||
|
|
||||||
console.log("Navigate to this URL in your browser:");
|
console.log("Navigate to this URL in your browser:");
|
||||||
console.log(res.url);
|
console.log(res.url);
|
||||||
|
console.log(
|
||||||
const login = prompt(
|
'Log in, right click the "Select this account" button, copy the link address, and paste it below:',
|
||||||
'Log in, right click the "Select this account" button, copy the link address, and paste it below:\n',
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const login = await readline();
|
||||||
if (!login) {
|
if (!login) {
|
||||||
throw new Error("No login URL provided");
|
throw new Error("No login URL provided");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
77
s3si.ts
77
s3si.ts
|
|
@ -1,4 +1,77 @@
|
||||||
import { loginManually } from "./iksm.ts";
|
import { loginManually } from "./iksm.ts";
|
||||||
|
import { flags } from "./deps.ts";
|
||||||
|
import { DEFAULT_STATE, State } from "./state.ts";
|
||||||
|
|
||||||
const state = await loginManually();
|
type Opts = {
|
||||||
console.log(state);
|
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> 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();
|
||||||
|
|
|
||||||
5
state.ts
5
state.ts
|
|
@ -1,3 +1,8 @@
|
||||||
export type LoginState = {
|
export type LoginState = {
|
||||||
sessionToken: string;
|
sessionToken: string;
|
||||||
};
|
};
|
||||||
|
export type State = {
|
||||||
|
loginState?: LoginState;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DEFAULT_STATE: State = {};
|
||||||
|
|
|
||||||
12
utils.ts
12
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) {
|
export function urlBase64Encode(data: ArrayBuffer) {
|
||||||
return base64.encode(data)
|
return base64.encode(data)
|
||||||
|
|
@ -14,3 +16,11 @@ export function urlBase64Decode(data: string) {
|
||||||
.replaceAll("-", "/"),
|
.replaceAll("-", "/"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function readline() {
|
||||||
|
for await (const line of stdinLines) {
|
||||||
|
if (line !== "") {
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue