forked from cadence/out-of-your-element
		
	Improve invite QR generation
This commit is contained in:
		
							parent
							
								
									84d61a1118
								
							
						
					
					
						commit
						4c62124cee
					
				
					 7 changed files with 12 additions and 46 deletions
				
			
		| 
						 | 
				
			
			@ -69,11 +69,7 @@ block body
 | 
			
		|||
        .grid--row-start2
 | 
			
		||||
          button.s-btn.s-btn__filled.htmx-indicator Invite
 | 
			
		||||
    div
 | 
			
		||||
      -
 | 
			
		||||
        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}`))
 | 
			
		||||
      != svg
 | 
			
		||||
 | 
			
		||||
  h2.mt48.fs-headline1 Moderation
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ const {H3Event, defineEventHandler, sendRedirect, useSession, createError, getVa
 | 
			
		|||
const {randomUUID} = require("crypto")
 | 
			
		||||
const {LRUCache} = require("lru-cache")
 | 
			
		||||
const Ty = require("../../types")
 | 
			
		||||
const uqr = require("uqr")
 | 
			
		||||
 | 
			
		||||
const {discord, as, sync, select} = require("../../passthrough")
 | 
			
		||||
/** @type {import("../pug-sync")} */
 | 
			
		||||
| 
						 | 
				
			
			@ -93,10 +94,17 @@ as.router.get("/guild", defineEventHandler(async event => {
 | 
			
		|||
	const nonce = randomUUID()
 | 
			
		||||
	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
 | 
			
		||||
	if (!row) {
 | 
			
		||||
		const links = getChannelRoomsLinks(guild_id, [])
 | 
			
		||||
		return pugSync.render(event, "guild.pug", {guild, guild_id, nonce, ...links})
 | 
			
		||||
		return pugSync.render(event, "guild.pug", {guild, guild_id, svg, ...links})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Linked guild
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +113,7 @@ as.router.get("/guild", defineEventHandler(async event => {
 | 
			
		|||
	const banned = await api.getMembers(row.space_id, "ban")
 | 
			
		||||
	const rooms = await api.getFullHierarchy(row.space_id)
 | 
			
		||||
	const links = getChannelRoomsLinks(guild_id, rooms)
 | 
			
		||||
	return pugSync.render(event, "guild.pug", {guild, guild_id, nonce, mods, banned, ...links, ...row})
 | 
			
		||||
	return pugSync.render(event, "guild.pug", {guild, guild_id, svg, mods, banned, ...links, ...row})
 | 
			
		||||
}))
 | 
			
		||||
 | 
			
		||||
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/)
 | 
			
		||||
	nonce = content.match(/nonce%3D([a-f0-9-]+)/)?.[1]
 | 
			
		||||
	nonce = content.match(/data-nonce="([a-f0-9-]+)"/)?.[1]
 | 
			
		||||
	t.ok(nonce)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +0,0 @@
 | 
			
		|||
// @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"}})
 | 
			
		||||
}))
 | 
			
		||||
| 
						 | 
				
			
			@ -1,17 +0,0 @@
 | 
			
		|||
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,7 +27,6 @@ sync.require("./routes/guild-settings")
 | 
			
		|||
sync.require("./routes/guild")
 | 
			
		||||
sync.require("./routes/link")
 | 
			
		||||
sync.require("./routes/oauth")
 | 
			
		||||
sync.require("./routes/qr")
 | 
			
		||||
 | 
			
		||||
// Files
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,5 +151,4 @@ file._actuallyUploadDiscordFileToMxc = function(url, res) { throw new Error(`Not
 | 
			
		|||
	require("../src/web/routes/download-discord.test")
 | 
			
		||||
	require("../src/web/routes/download-matrix.test")
 | 
			
		||||
	require("../src/web/routes/guild.test")
 | 
			
		||||
	require("../src/web/routes/qr.test")
 | 
			
		||||
})()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue