Compare commits
No commits in common. "dd0957f70087ed581d5a9bea5353b12e431bb9d8" and "84bc53e66c66730f8521094ae029627370a9c7e0" have entirely different histories.
dd0957f700
...
84bc53e66c
|
@ -7,12 +7,8 @@ module.exports = (req, res, next) => {
|
||||||
|
|
||||||
|
|
||||||
res.template = async (file, data) => {
|
res.template = async (file, data) => {
|
||||||
|
|
||||||
let t_data = {};
|
|
||||||
if (data) t_data = {...data};
|
|
||||||
|
|
||||||
res.send(await Helpers.ViewLoader.load(file, {
|
res.send(await Helpers.ViewLoader.load(file, {
|
||||||
...t_data,
|
...data,
|
||||||
current_route: req.originalUrl,
|
current_route: req.originalUrl,
|
||||||
req,
|
req,
|
||||||
res,
|
res,
|
||||||
|
|
|
@ -1,9 +1,72 @@
|
||||||
const { Model, DataTypes } = require('sequelize');
|
const { Model, DataTypes } = require('sequelize');
|
||||||
const { sequelize } = require('.');
|
const { sequelize } = require('.');
|
||||||
|
|
||||||
|
/** @type {{data: Permission[], updated: number, expired: function}} */
|
||||||
|
let cached = {
|
||||||
|
data: undefined,
|
||||||
|
updated: 0,
|
||||||
|
expired: () => {
|
||||||
|
return (Date.now() - updated) >= 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Permission extends Model {
|
class Permission extends Model {
|
||||||
static async getAllForUser(user) {
|
static async cache() {
|
||||||
return await this.findAll({where: {user}});
|
if (!cached.expired()) return;
|
||||||
|
|
||||||
|
cached.data = await Permission.findAll();
|
||||||
|
cached.updated = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value from cache
|
||||||
|
* @param {number} user
|
||||||
|
* @param {string} permission
|
||||||
|
* @returns {Permission?}
|
||||||
|
*/
|
||||||
|
static async findFromCache(user, permission) {
|
||||||
|
await this.cache();
|
||||||
|
for (const perm of cached.data) {
|
||||||
|
if (perm.user == userid && perm.permission == permission)
|
||||||
|
return perm;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a permission for user
|
||||||
|
* @param {number} user
|
||||||
|
* @param {string} permission
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async forUser(user, permission) {
|
||||||
|
await this.cache();
|
||||||
|
const data = await this.findFromCache(user, permission);
|
||||||
|
if (!data) return false;
|
||||||
|
return data.value != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a permission for user
|
||||||
|
* @param {number} user
|
||||||
|
* @param {string} permission
|
||||||
|
* @param {number} value
|
||||||
|
* @returns {Permission}
|
||||||
|
*/
|
||||||
|
static async set(user, permission, value) {
|
||||||
|
const existing = await Permission.findOne({where: {user, permission}});
|
||||||
|
|
||||||
|
let perm;
|
||||||
|
|
||||||
|
if (!existing) perm = await Permission.create({user, permission, value});
|
||||||
|
else perm = await Permission.update({user, permission, value}, {where: {user, permission}});
|
||||||
|
await this.cache();
|
||||||
|
|
||||||
|
return perm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async userAllowed(user, permission) {
|
||||||
|
return this.forUser(user, permission);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +81,12 @@ Permission.structure = {
|
||||||
type: DataTypes.BIGINT,
|
type: DataTypes.BIGINT,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
},
|
},
|
||||||
perms: {
|
permission: {
|
||||||
type: DataTypes.JSONB,
|
type: DataTypes.TEXT,
|
||||||
|
allowNull: false
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: DataTypes.BIGINT,
|
||||||
allowNull: false
|
allowNull: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -109,18 +109,3 @@ span.flag_btn {
|
||||||
span.au_flag {
|
span.au_flag {
|
||||||
background: url(/content/au_flag.jpg);
|
background: url(/content/au_flag.jpg);
|
||||||
}
|
}
|
||||||
|
|
||||||
table.border_table, table.border_table tr td {
|
|
||||||
border: 1px solid #c2c4c2;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
table.border_table tr td, table.border_table tr th {
|
|
||||||
padding: 4px 10px;
|
|
||||||
border: 1px solid #c2c4c2;
|
|
||||||
}
|
|
||||||
table.border_table tr th {
|
|
||||||
border-bottom: 3px double #caccca;
|
|
||||||
padding: 2px 10px;
|
|
||||||
font-size: 90%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB |
|
@ -1,24 +0,0 @@
|
||||||
div#resume_js_app {
|
|
||||||
background: #303030;
|
|
||||||
width:640px;
|
|
||||||
height:480px;
|
|
||||||
border: 1px solid #e1e1e1;
|
|
||||||
font-family: monospace;
|
|
||||||
box-shadow: 0 2px 4px #30303060;
|
|
||||||
padding: 10px 8px;
|
|
||||||
color: #e1e1e1;
|
|
||||||
|
|
||||||
position: fixed;
|
|
||||||
top:50%;left:50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
div#resume_js_app * {
|
|
||||||
padding: 0; margin: 0;
|
|
||||||
}
|
|
||||||
div#resume_js_app p.js_loading_indicator {
|
|
||||||
position: relative;
|
|
||||||
top: 50%; left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: fit-content;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
const handler = require('express-async-handler');
|
|
||||||
|
|
||||||
async function services(req, res) {
|
|
||||||
res.template('page/services.pug');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function resume(req, res) {
|
|
||||||
res.template('page/resume.pug');
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = (router) => {
|
|
||||||
router.get('/services', handler(services))
|
|
||||||
router.get('/resume', handler(resume))
|
|
||||||
}
|
|
|
@ -9,9 +9,7 @@ block root
|
||||||
"Guestbook": "/guestbook",
|
"Guestbook": "/guestbook",
|
||||||
"Articles": "/articles",
|
"Articles": "/articles",
|
||||||
"hr_2": "hr",
|
"hr_2": "hr",
|
||||||
"Sources": "/sources",
|
"Sources": "/sources"
|
||||||
"Services": "/services",
|
|
||||||
"Resume": "/resume"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doctype html
|
doctype html
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
extends ../layout/main.pug
|
|
||||||
block root
|
|
||||||
- var title = 'Resume'
|
|
||||||
link(rel='stylesheet' href='/static/ui/resume.css')
|
|
||||||
|
|
||||||
block content
|
|
||||||
h2 My online resume
|
|
||||||
hr
|
|
||||||
div(id='resume_js_app')
|
|
||||||
p(class='js_loading_indicator')
|
|
||||||
| JS is loading. Please hold on...
|
|
||||||
br
|
|
||||||
img(src='/static/ui/load.gif' style='border-radius:6px;margin-top:6px')
|
|
|
@ -1,44 +0,0 @@
|
||||||
extends ../layout/main.pug
|
|
||||||
block root
|
|
||||||
- var title = 'Services'
|
|
||||||
include ../ui/label.pug
|
|
||||||
|
|
||||||
block content
|
|
||||||
h2 My self-hosted services
|
|
||||||
hr
|
|
||||||
table(class='border_table' style='font-size:11pt')
|
|
||||||
tr
|
|
||||||
th Name
|
|
||||||
th Link
|
|
||||||
th Description
|
|
||||||
tr
|
|
||||||
td Excalidraw
|
|
||||||
td
|
|
||||||
a(href='https://draw.blek.codes' class='web_link') draw.blek.codes
|
|
||||||
td
|
|
||||||
| A draw board. Has real-time collaborative features.
|
|
||||||
a(href='https://excalidraw.com') Official site
|
|
||||||
tr
|
|
||||||
td Gitea
|
|
||||||
td
|
|
||||||
a(href='https://git.blek.codes' class='web_link') git.blek.codes
|
|
||||||
td
|
|
||||||
| My gitea instance. I store all my new work here, although it is mirrored to github.
|
|
||||||
tr
|
|
||||||
td blek! Bin
|
|
||||||
td
|
|
||||||
a(href='https://bin.blek.codes' class='web_link') bin.blek.codes
|
|
||||||
td
|
|
||||||
| A privacy-respecting, js-free pastebin alternative (inspired by
|
|
||||||
a(href='https://github.com/hnhx/librebin') Librebin
|
|
||||||
| )
|
|
||||||
a(href='/project/blek_bin' class='web_link') Project page
|
|
||||||
tr
|
|
||||||
td Mailcow
|
|
||||||
td No public web gui
|
|
||||||
td
|
|
||||||
| A set of programs to run a mail service.
|
|
||||||
a(href='https://mailcow.email' class='web_link') Official site
|
|
||||||
p
|
|
||||||
a(href='http://kuma.blek.codes/status/all')
|
|
||||||
+label('Status page', '#58ac58')
|
|
Loading…
Reference in New Issue