Compare commits
No commits in common. "4c62124cee94fa28d4c1dbddf4403beb09e04f07" and "16ac99781c509a98b266337f1e3ac509be14bbb6" have entirely different histories.
4c62124cee
...
16ac99781c
8 changed files with 48 additions and 15 deletions
|
@ -69,7 +69,11 @@ block body
|
||||||
.grid--row-start2
|
.grid--row-start2
|
||||||
button.s-btn.s-btn__filled.htmx-indicator Invite
|
button.s-btn.s-btn__filled.htmx-indicator Invite
|
||||||
div
|
div
|
||||||
!= svg
|
-
|
||||||
|
let size = 105
|
||||||
|
let p = new URLSearchParams()
|
||||||
|
p.set("data", `https://bridge.cadence.moe/invite?nonce=${nonce}`)
|
||||||
|
img(width=size height=size src=rel(`/qr?${p}`))
|
||||||
|
|
||||||
h2.mt48.fs-headline1 Moderation
|
h2.mt48.fs-headline1 Moderation
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ const {H3Event, defineEventHandler, sendRedirect, useSession, createError, getVa
|
||||||
const {randomUUID} = require("crypto")
|
const {randomUUID} = require("crypto")
|
||||||
const {LRUCache} = require("lru-cache")
|
const {LRUCache} = require("lru-cache")
|
||||||
const Ty = require("../../types")
|
const Ty = require("../../types")
|
||||||
const uqr = require("uqr")
|
|
||||||
|
|
||||||
const {discord, as, sync, select} = require("../../passthrough")
|
const {discord, as, sync, select} = require("../../passthrough")
|
||||||
/** @type {import("../pug-sync")} */
|
/** @type {import("../pug-sync")} */
|
||||||
|
@ -94,17 +93,10 @@ as.router.get("/guild", defineEventHandler(async event => {
|
||||||
const nonce = randomUUID()
|
const nonce = randomUUID()
|
||||||
validNonce.set(nonce, guild_id)
|
validNonce.set(nonce, guild_id)
|
||||||
|
|
||||||
const data = `${reg.ooye.bridge_origin}/invite?nonce=${nonce}`
|
|
||||||
// necessary to scale the svg pixel-perfectly on the page
|
|
||||||
// https://github.com/unjs/uqr/blob/244952a8ba2d417f938071b61e11fb1ff95d6e75/src/svg.ts#L24
|
|
||||||
const generatedSvg = uqr.renderSVG(data, {pixelSize: 3})
|
|
||||||
const svg = generatedSvg.replace(/viewBox="0 0 ([0-9]+) ([0-9]+)"/, `data-nonce="${nonce}" width="$1" height="$2" $&`)
|
|
||||||
assert.notEqual(svg, generatedSvg)
|
|
||||||
|
|
||||||
// Unlinked guild
|
// Unlinked guild
|
||||||
if (!row) {
|
if (!row) {
|
||||||
const links = getChannelRoomsLinks(guild_id, [])
|
const links = getChannelRoomsLinks(guild_id, [])
|
||||||
return pugSync.render(event, "guild.pug", {guild, guild_id, svg, ...links})
|
return pugSync.render(event, "guild.pug", {guild, guild_id, nonce, ...links})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linked guild
|
// Linked guild
|
||||||
|
@ -113,7 +105,7 @@ as.router.get("/guild", defineEventHandler(async event => {
|
||||||
const banned = await api.getMembers(row.space_id, "ban")
|
const banned = await api.getMembers(row.space_id, "ban")
|
||||||
const rooms = await api.getFullHierarchy(row.space_id)
|
const rooms = await api.getFullHierarchy(row.space_id)
|
||||||
const links = getChannelRoomsLinks(guild_id, rooms)
|
const links = getChannelRoomsLinks(guild_id, rooms)
|
||||||
return pugSync.render(event, "guild.pug", {guild, guild_id, svg, mods, banned, ...links, ...row})
|
return pugSync.render(event, "guild.pug", {guild, guild_id, nonce, mods, banned, ...links, ...row})
|
||||||
}))
|
}))
|
||||||
|
|
||||||
as.router.get("/invite", defineEventHandler(async event => {
|
as.router.get("/invite", defineEventHandler(async event => {
|
||||||
|
|
|
@ -78,7 +78,7 @@ test("web guild: can view bridged guild", async t => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.match(content, /<h1[^<]*Psychonauts 3/)
|
t.match(content, /<h1[^<]*Psychonauts 3/)
|
||||||
nonce = content.match(/data-nonce="([a-f0-9-]+)"/)?.[1]
|
nonce = content.match(/nonce%3D([a-f0-9-]+)/)?.[1]
|
||||||
t.ok(nonce)
|
t.ok(nonce)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ const {defineEventHandler, getValidatedQuery, sendRedirect, getQuery, useSession
|
||||||
const {SnowTransfer} = require("snowtransfer")
|
const {SnowTransfer} = require("snowtransfer")
|
||||||
const DiscordTypes = require("discord-api-types/v10")
|
const DiscordTypes = require("discord-api-types/v10")
|
||||||
const fetch = require("node-fetch")
|
const fetch = require("node-fetch")
|
||||||
const getRelativePath = require("get-relative-path")
|
|
||||||
|
|
||||||
const {as, db} = require("../../passthrough")
|
const {as, db} = require("../../passthrough")
|
||||||
const {id} = require("../../../addbot")
|
const {id} = require("../../../addbot")
|
||||||
|
@ -91,8 +90,8 @@ as.router.get("/oauth", defineEventHandler(async event => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parsedQuery.data.guild_id) {
|
if (parsedQuery.data.guild_id) {
|
||||||
return sendRedirect(event, getRelativePath(event.path, `/guild?guild_id=${parsedQuery.data.guild_id}`), 302)
|
return sendRedirect(event, `/guild?guild_id=${parsedQuery.data.guild_id}`, 302)
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendRedirect(event, getRelativePath(event.path, "/"), 302)
|
return sendRedirect(event, "/", 302)
|
||||||
}))
|
}))
|
||||||
|
|
19
src/web/routes/qr.js
Normal file
19
src/web/routes/qr.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const {z} = require("zod")
|
||||||
|
const {defineEventHandler, getValidatedQuery} = require("h3")
|
||||||
|
|
||||||
|
const {as} = require("../../passthrough")
|
||||||
|
|
||||||
|
const uqr = require("uqr")
|
||||||
|
|
||||||
|
const schema = {
|
||||||
|
qr: z.object({
|
||||||
|
data: z.string().max(128)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
as.router.get("/qr", defineEventHandler(async event => {
|
||||||
|
const {data} = await getValidatedQuery(event, schema.qr.parse)
|
||||||
|
return new Response(uqr.renderSVG(data, {pixelSize: 3}), {headers: {"content-type": "image/svg+xml"}})
|
||||||
|
}))
|
17
src/web/routes/qr.test.js
Normal file
17
src/web/routes/qr.test.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
const {test} = require("supertape")
|
||||||
|
const {router} = require("../../../test/web")
|
||||||
|
const getStream = require("get-stream")
|
||||||
|
|
||||||
|
test("web qr: returns svg", async t => {
|
||||||
|
/** @type {Response} */
|
||||||
|
const res = await router.test("get", "/qr?data=hello+world", {
|
||||||
|
params: {
|
||||||
|
server_name: "cadence.moe",
|
||||||
|
media_id: "1"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.equal(res.status, 200)
|
||||||
|
t.equal(res.headers.get("content-type"), "image/svg+xml")
|
||||||
|
const content = await getStream(res.body)
|
||||||
|
t.match(content, /<svg/)
|
||||||
|
})
|
|
@ -27,6 +27,7 @@ sync.require("./routes/guild-settings")
|
||||||
sync.require("./routes/guild")
|
sync.require("./routes/guild")
|
||||||
sync.require("./routes/link")
|
sync.require("./routes/link")
|
||||||
sync.require("./routes/oauth")
|
sync.require("./routes/oauth")
|
||||||
|
sync.require("./routes/qr")
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
|
|
||||||
|
|
|
@ -151,4 +151,5 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
|
||||||
require("../src/web/routes/download-discord.test")
|
require("../src/web/routes/download-discord.test")
|
||||||
require("../src/web/routes/download-matrix.test")
|
require("../src/web/routes/download-matrix.test")
|
||||||
require("../src/web/routes/guild.test")
|
require("../src/web/routes/guild.test")
|
||||||
|
require("../src/web/routes/qr.test")
|
||||||
})()
|
})()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue