diff --git a/package-lock.json b/package-lock.json index 80f1eb2..aa958d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "archery", - "version": "0.1.7", + "version": "0.1.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "archery", - "version": "0.1.7", + "version": "0.1.8", "license": "MIT", "dependencies": { "body-parser": "^1.20.3", @@ -15,7 +15,8 @@ "express-ws": "^5.0.2", "pg": "^8.15.6", "pg-hstore": "^2.3.4", - "sequelize": "^6.37.7" + "sequelize": "^6.37.7", + "sqids": "0.3.0" }, "devDependencies": { "@types/csso": "5.0.4", @@ -1998,6 +1999,12 @@ "node": ">= 10.x" } }, + "node_modules/sqids": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/sqids/-/sqids-0.3.0.tgz", + "integrity": "sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==", + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", diff --git a/package.json b/package.json index f2063e9..82a7a8a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "archery", - "version": "0.1.7", + "version": "0.1.8", "description": "Build Arch packages through a web interface", "keywords": [ "docker", @@ -26,7 +26,8 @@ "express-ws": "^5.0.2", "pg": "^8.15.6", "pg-hstore": "^2.3.4", - "sequelize": "^6.37.7" + "sequelize": "^6.37.7", + "sqids": "0.3.0" }, "devDependencies": { "@types/csso": "5.0.4", diff --git a/src/DB.ts b/src/DB.ts index 9f922c4..5184a07 100644 --- a/src/DB.ts +++ b/src/DB.ts @@ -24,6 +24,7 @@ interface Build { endTime?: Date; status: Status; pid?: number; + sqid?: string; } interface LogChunk { @@ -51,7 +52,8 @@ class DB { this.sequelize = new Sequelize(config.db || 'archery', config.user || 'archery', process.env.PASSWORD || config.password || '', { host: config.host || 'localhost', port: config.port || 5432, - dialect: 'postgres' + dialect: 'postgres', + logging: false }); this.build = this.sequelize.define('builds', { id: { diff --git a/src/Web.ts b/src/Web.ts index 9471f2b..0d799f0 100644 --- a/src/Web.ts +++ b/src/Web.ts @@ -4,6 +4,7 @@ import type { Express } from "express"; import express from 'express'; import expressWs from "express-ws"; import bodyParser from "body-parser"; +import Sqids from 'sqids'; import type { DB, LogChunk } from "./DB.ts"; import type { BuildController, BuildEvent } from "./BuildController.ts"; @@ -41,6 +42,10 @@ class Web { private port: number; constructor(options: WebConfig = {}) { + const sqids = new Sqids({ + minLength: 6, + alphabet: 'abcdefghijkmnprstuvwxyz' + }); const app: Express = express(); const wsApp = this.app = expressWs(app).app; this.port = notStupidParseInt(process.env.PORT) || options['port'] as number || 8080; @@ -66,6 +71,9 @@ class Web { app.get('/', async (req, res) => { try { const builds = 'q' in req.query ? await this.db.searchBuilds(req.query.q as string) : await this.db.getBuildsBy(req.query); + builds.forEach(b => { + b.sqid = sqids.encode([b.id]); + }); res.render('index', { page: { title: 'Archery', @@ -100,22 +108,23 @@ class Web { req.body.distro || 'arch', req.body.dependencies || 'stable' ); - res.redirect(`/build/${buildId}`); + res.redirect(`/build/${sqids.encode([buildId])}`); this.buildController.triggerBuild(); }); - app.get('/build/:num/?', async (req, res) => { - const build = await this.db.getBuild(parseInt(req.params.num)); + app.get('/build/:id/?', async (req, res) => { + const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]); if (!build) { res.sendStatus(404); return; } + build.sqid = sqids.encode([build.id]); const log = splitLines(await this.db.getLog(build.id)); res.render('build', { page: { title: 'Archery', - titlesuffix: `Build #${req.params.num}`, + titlesuffix: `Build #${build.id}`, description: `Building ${build.repo} on ${build.distro}` }, build, @@ -124,8 +133,8 @@ class Web { }); }); - app.get('/build/:num/cancel', async (req, res) => { - const build = await this.db.getBuild(parseInt(req.params.num)); + app.get('/build/:id/cancel', async (req, res) => { + const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]); if (!build) { res.sendStatus(404); return; @@ -136,11 +145,11 @@ class Web { catch (ex) { console.error(ex); } - res.redirect(`/build/${build.id}`); + res.redirect(`/build/${req.params.id}`); }); - app.get('/build/:num/logs/?', async (req, res) => { - const build = await this.db.getBuild(parseInt(req.params.num)); + app.get('/build/:id/logs/?', async (req, res) => { + const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]); if (!build) { res.sendStatus(404); return; @@ -149,8 +158,8 @@ class Web { res.set('Content-Type', 'text/plain').send(log); }); - app.get('/build/:num/patch/?', async (req, res) => { - const build = await this.db.getBuild(parseInt(req.params.num)); + app.get('/build/:id/patch/?', async (req, res) => { + const build = await this.db.getBuild(sqids.decode(req.params.id)?.[0]); if (!build || !build.patch) { res.sendStatus(404); return; @@ -162,10 +171,10 @@ class Web { res.send('Healthy'); }); - wsApp.ws('/build/:num/ws', (ws, req) => { + wsApp.ws('/build/:id/ws', (ws, req) => { console.log('WS Opened'); const eventListener = (be: BuildEvent) => { - if (be.id === notStupidParseInt(req.params.num)) { + if (be.id === sqids.decode(req.params.id)?.[0]) { ws.send(JSON.stringify(be)); } }; diff --git a/views/build.ejs b/views/build.ejs index 4321d37..df1a2ec 100644 --- a/views/build.ejs +++ b/views/build.ejs @@ -14,7 +14,7 @@
<%= build.repo %> <% if (build.commit) { %><%= build.commit %><% } else { %>latest<% } %> - <% if (build.patch) { %>patch file<% } else { %>none<% } %> + <% if (build.patch) { %>patch file<% } else { %>none<% } %> <%= build.distro %> <%= build.dependencies %> <%= build.startTime %> @@ -22,10 +22,10 @@
<% if (!ended) { %>
- Cancel build + Cancel build
<% } %> -

Full logs

+

Full logs

<% (log || []).forEach(line => { %>

<%= line %>

<% }) %>
<% if (!ended) { %> diff --git a/views/index.ejs b/views/index.ejs index eab7e0b..968f361 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -20,7 +20,7 @@ <% builds.forEach(build => { %> - <%= build.repo %> + <%= build.repo %> <%= build.distro %> <%= build.startTime %> <%= timeElapsed(build.startTime, build.endTime) %>