poc
This commit is contained in:
parent
00ddc08afd
commit
d85ebaf95d
|
@ -1,4 +1,4 @@
|
|||
distribution
|
||||
dist
|
||||
.idea
|
||||
node_modules
|
||||
.parcel-cache
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"build": "parcel build src/manifest.json --no-content-hash --no-source-maps --dist-dir distribution --detailed-report 0",
|
||||
"watch": "parcel watch src/manifest.json --dist-dir distribution --no-cache --no-hmr",
|
||||
"build": "parcel build src/manifest.json --no-content-hash --no-source-maps --dist-dir dist --detailed-report 0",
|
||||
"watch": "parcel watch src/manifest.json --dist-dir dist --no-cache --no-hmr",
|
||||
"run:chromium": "web-ext run -t chromium"
|
||||
},
|
||||
"author": {
|
||||
|
@ -24,7 +24,7 @@
|
|||
"since 2017-06"
|
||||
],
|
||||
"webExt": {
|
||||
"sourceDir": "distribution",
|
||||
"sourceDir": "dist",
|
||||
"run": {
|
||||
"startUrl": [
|
||||
"https://www.tribalwars.net"
|
||||
|
|
|
@ -3,6 +3,7 @@ import { optionsStorage } from './options-storage';
|
|||
import { decrypt, encrypt } from './crypto';
|
||||
|
||||
const COOKIE_NAME = 'sid';
|
||||
const HTTP_STATUS_OK = 200;
|
||||
|
||||
chrome.runtime.onMessage.addListener(
|
||||
(message: Message, sender, sendResponse) => {
|
||||
|
@ -14,27 +15,123 @@ chrome.runtime.onMessage.addListener(
|
|||
);
|
||||
|
||||
const handleLogin = async (message: LoginMessage) => {
|
||||
const cookie = await chrome.cookies.get({
|
||||
const sid = await chrome.cookies.get({
|
||||
name: COOKIE_NAME,
|
||||
url: message.url,
|
||||
});
|
||||
|
||||
console.log(cookie);
|
||||
console.log(sid);
|
||||
|
||||
if (cookie) {
|
||||
const opts = await optionsStorage.getAll();
|
||||
const test1 = await encrypt(cookie.value, opts.encryptionPassword);
|
||||
const test2 = await decrypt(test1, opts.encryptionPassword);
|
||||
console.log(opts.encryptionPassword, test1, test2);
|
||||
if (sid) {
|
||||
const success = await tryOpenOverview(message.url);
|
||||
if (success) {
|
||||
await createOrUpdateCookie(message.server, await encryptCookie(sid));
|
||||
await openOverview(message.url);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const url = new URL(message.url);
|
||||
url.pathname = '/game.php';
|
||||
url.searchParams.set('screen', 'overview_villages');
|
||||
const resp = await fetch(url.toString(), {
|
||||
const sidFromApi = await getSid(message.server);
|
||||
if (sidFromApi.length > 0) {
|
||||
await setSid(message.url, sidFromApi);
|
||||
if (await tryOpenOverview(message.url)) {
|
||||
await openOverview(message.url);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await fetch(message.loginUrl, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
redirect: 'manual',
|
||||
});
|
||||
console.log(resp.status, resp.redirected);
|
||||
|
||||
const newSid = await chrome.cookies.get({
|
||||
name: COOKIE_NAME,
|
||||
url: message.url,
|
||||
});
|
||||
if (!newSid) {
|
||||
return;
|
||||
}
|
||||
|
||||
await createOrUpdateCookie(message.server, await encryptCookie(newSid));
|
||||
await openOverview(message.url);
|
||||
};
|
||||
|
||||
const tryOpenOverview = async (base: string) => {
|
||||
try {
|
||||
const resp = await fetch(buildUrlToOverview(base), {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
redirect: 'error',
|
||||
});
|
||||
return resp.status == HTTP_STATUS_OK;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const openOverview = async (base: string) => {
|
||||
await chrome.tabs.update({
|
||||
url: buildUrlToOverview(base).toString(),
|
||||
});
|
||||
};
|
||||
|
||||
const buildUrlToOverview = (base: string) => {
|
||||
const url = new URL(base);
|
||||
url.pathname = '/game.php';
|
||||
url.searchParams.set('screen', 'overview_villages');
|
||||
return url;
|
||||
};
|
||||
|
||||
const createOrUpdateCookie = async (server: string, sid: string) => {
|
||||
const opts = await optionsStorage.getAll();
|
||||
|
||||
const url = new URL(opts.apiUrl);
|
||||
url.pathname = `/api/v1/user/sessions/${server}`;
|
||||
|
||||
await fetch(url, {
|
||||
method: 'PUT',
|
||||
body: sid,
|
||||
headers: {
|
||||
'X-Api-Key': opts.apiKey,
|
||||
'Content-Type': 'text/plain',
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const getSid = async (server: string): Promise<string> => {
|
||||
const opts = await optionsStorage.getAll();
|
||||
|
||||
const url = new URL(opts.apiUrl);
|
||||
url.pathname = `/api/v1/user/sessions/${server}`;
|
||||
|
||||
const resp = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-Api-Key': opts.apiKey,
|
||||
},
|
||||
});
|
||||
|
||||
const respBody = await resp.json();
|
||||
if (!respBody.data?.sid) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return respBody.data.sid;
|
||||
};
|
||||
|
||||
const encryptCookie = async (cookie: chrome.cookies.Cookie) => {
|
||||
const opts = await optionsStorage.getAll();
|
||||
return await encrypt(cookie.value, opts.encryptionPassword);
|
||||
};
|
||||
|
||||
const setSid = async (url: string, sid: string) => {
|
||||
const opts = await optionsStorage.getAll();
|
||||
await chrome.cookies.set({
|
||||
url,
|
||||
name: COOKIE_NAME,
|
||||
value: await decrypt(sid, opts.encryptionPassword),
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@ const handleClick = (e: MouseEvent) => {
|
|||
chrome.runtime.sendMessage({
|
||||
type: MessageType.LOGIN,
|
||||
server,
|
||||
loginUrl: url.toString(),
|
||||
url: url.protocol + '//' + url.host.replace('www', server),
|
||||
} as LoginMessage);
|
||||
};
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// https://github.com/bradyjoslin/webcrypto-example/blob/master/script.js
|
||||
|
||||
const ITERATIONS = 100000;
|
||||
|
||||
const enc = new TextEncoder();
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"default_title": "Sessions",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"permissions": ["storage", "cookies"],
|
||||
"permissions": ["storage", "cookies", "activeTab", "tabs"],
|
||||
"host_permissions": ["https://*.tribalwars.net/*"],
|
||||
"content_scripts": [
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ export enum MessageType {
|
|||
export type LoginMessage = {
|
||||
type: MessageType.LOGIN;
|
||||
url: string;
|
||||
loginUrl: string;
|
||||
server: string;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ import OptionsSync from 'webext-options-sync';
|
|||
|
||||
export const optionsStorage = new OptionsSync({
|
||||
defaults: {
|
||||
apiUrl: 'https://tribalwarshelp.com',
|
||||
apiToken: '',
|
||||
apiUrl: 'http://localhost:9234',
|
||||
apiKey: '',
|
||||
encryptionPassword: 'password',
|
||||
},
|
||||
migrations: [OptionsSync.migrations.removeUnused],
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
<input name="apiUrl" type="text" />
|
||||
</label>
|
||||
<label
|
||||
>API Token
|
||||
<input name="apiToken" type="text" />
|
||||
>API Key
|
||||
<input name="apiKey" type="text" />
|
||||
</label>
|
||||
<label
|
||||
>Encryption password
|
||||
|
|
Loading…
Reference in New Issue