1
Fork 0

Compare commits

..

No commits in common. "99180035e3d974aa4adfcb15d9d516b705e5089d" and "809943edcc01fc3c81ec59ebdfabfb7f8669656a" have entirely different histories.

5 changed files with 27 additions and 65 deletions

View File

@ -35,10 +35,9 @@ const sourceDir = toAbsolutePath("../source");
await fsp.mkdir(outDir, {recursive: true}); await fsp.mkdir(outDir, {recursive: true});
// Write the WebExtension manifest file. // Write the WebExtension manifest file.
const manifest = createManifest(browser);
await fsp.writeFile( await fsp.writeFile(
path.join(outDir, "manifest.json"), path.join(outDir, "manifest.json"),
JSON.stringify(manifest), JSON.stringify(createManifest(browser)),
); );
// Write the web-ext configuration file. // Write the web-ext configuration file.
@ -74,7 +73,6 @@ const options: esbuild.BuildOptions = {
$browser: JSON.stringify(browser), $browser: JSON.stringify(browser),
$dev: JSON.stringify(dev), $dev: JSON.stringify(dev),
$test: JSON.stringify(test), $test: JSON.stringify(test),
$version: JSON.stringify(manifest.version),
}, },
entryPoints: [ entryPoints: [
path.join(sourceDir, "background/setup.ts"), path.join(sourceDir, "background/setup.ts"),

View File

@ -1,10 +1,5 @@
import {Component, render} from "preact"; import {Component, render} from "preact";
import { import {log, pluralize, querySelectorAll} from "../../utilities/exports.js";
log,
makeIntercoolerRequest,
pluralize,
querySelectorAll,
} from "../../utilities/exports.js";
export function runGroupListSubscribeButtonFeature(): void { export function runGroupListSubscribeButtonFeature(): void {
const count = addSubscribeButtonsToGroupList(); const count = addSubscribeButtonsToGroupList();
@ -19,6 +14,14 @@ function addSubscribeButtonsToGroupList(): number {
return 0; return 0;
} }
const csrfToken = document.querySelector<HTMLMetaElement>(
'meta[name="csrftoken"]',
)?.content;
if (csrfToken === undefined) {
log("No CSRF token found", true);
return 0;
}
let count = 0; let count = 0;
for (const listItem of querySelectorAll<HTMLLIElement>( for (const listItem of querySelectorAll<HTMLLIElement>(
".group-list li:not(.trx-group-list-subscribe-button)", ".group-list li:not(.trx-group-list-subscribe-button)",
@ -31,7 +34,14 @@ function addSubscribeButtonsToGroupList(): number {
} }
const button = document.createDocumentFragment(); const button = document.createDocumentFragment();
render(<SubscribeButton group={group} listItem={listItem} />, button); render(
<SubscribeButton
csrfToken={csrfToken}
group={group}
listItem={listItem}
/>,
button,
);
const activity = const activity =
listItem.querySelector(".group-list-activity") ?? undefined; listItem.querySelector(".group-list-activity") ?? undefined;
@ -49,6 +59,7 @@ function addSubscribeButtonsToGroupList(): number {
} }
type Props = { type Props = {
csrfToken: string;
listItem: HTMLLIElement; listItem: HTMLLIElement;
group: string; group: string;
}; };
@ -69,15 +80,21 @@ class SubscribeButton extends Component<Props, State> {
} }
clickHandler = async () => { clickHandler = async () => {
const {group} = this.props; const {csrfToken, group} = this.props;
const {isSubscribed} = this.state; const {isSubscribed} = this.state;
const response = await makeIntercoolerRequest( const response = await window.fetch(
`https://tildes.net/api/web/group/${group}/subscribe`, `https://tildes.net/api/web/group/${group}/subscribe`,
{ {
headers: {
"X-CSRF-Token": csrfToken,
"X-IC-Request": "true",
},
method: isSubscribed ? "DELETE" : "PUT", method: isSubscribed ? "DELETE" : "PUT",
referrer: "https://tildes.net",
}, },
); );
if (response.status !== 200) { if (response.status !== 200) {
log(`Unexpected status code: ${response.status}`, true); log(`Unexpected status code: ${response.status}`, true);
return; return;

1
source/types.d.ts vendored
View File

@ -12,5 +12,4 @@ declare global {
const $browser: "chromium" | "firefox"; const $browser: "chromium" | "firefox";
const $dev: boolean; const $dev: boolean;
const $test: boolean; const $test: boolean;
const $version: string;
} }

View File

@ -3,7 +3,6 @@ export * from "./components/link.js";
export * from "./elements.js"; export * from "./elements.js";
export * from "./globals.js"; export * from "./globals.js";
export * from "./groups.js"; export * from "./groups.js";
export * from "./http.js";
export * from "./logging.js"; export * from "./logging.js";
export * from "./query-selectors.js"; export * from "./query-selectors.js";
export * from "./report-a-bug.js"; export * from "./report-a-bug.js";

View File

@ -1,51 +0,0 @@
import {log} from "./logging.js";
/**
* Make an HTTP request to the Tildes API that is normally used by Intercooler.
* This should only be used when using HTML elements from Tildes itself isn't
* feasible.
* @param url The API URL to call.
* @param request Any extra request details, note that some of these values will
* be overridden by the ones required to make a proper Intercooler request.
*/
export async function makeIntercoolerRequest(
url: string,
request: RequestInit,
): Promise<Response> {
if (!url.startsWith("https://tildes.net")) {
throw new Error(`Can't make Intercooler request to non-Tildes URL: ${url}`);
}
const csrfToken = document.querySelector<HTMLMetaElement>(
'meta[name="csrftoken"]',
)!.content;
const ic: RequestInit = {
headers: {
// Change the user agent and add an extra header so it's clear this isn't
// a request actually sent by Intercooler but by Tildes ReExtended.
"User-Agent": `Tildes ReExtended (${$browser}, version ${$version})`,
"X-CSRF-Token": csrfToken,
"X-IC-Request": "true",
"X-TRX-Request": "true",
},
referrer: "https://tildes.net",
};
request.headers =
request.headers === undefined
? ic.headers
: {
...request.headers,
// Apply the Intercooler headers last so they can't be overridden.
...ic.headers,
};
request.referrer = request.referrer ?? ic.referrer;
// Explicitly log the request because content script HTTP calls don't show up
// in the Network DevTools.
log("Making Intercooler request:");
log(request);
return window.fetch(url, request);
}