mirror of
https://github.com/luxfi/pics.git
synced 2026-07-26 21:08:58 +00:00
web3 first commit, message signing
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"gulp/res/js/watchedthread.js",
|
||||
"gulp/res/js/threadwatcher.js",
|
||||
"gulp/res/js/socket.io.js",
|
||||
"gulp/res/js/web3.js",
|
||||
"gulp/res/js/tegaki.js"
|
||||
],
|
||||
"env": {
|
||||
|
||||
@@ -27,6 +27,7 @@ gulp/res/js/watchedthread.js
|
||||
gulp/res/js/pugruntime.js
|
||||
gulp/res/js/uploaditem.js
|
||||
gulp/res/js/socket.io.js
|
||||
gulp/res/js/web3.js
|
||||
|
||||
# some ide and testing files, artefacts, etc
|
||||
.idea/
|
||||
|
||||
@@ -140,6 +140,10 @@ module.exports = {
|
||||
//enable the webring (also copy configs/webring.json.example -> configs/webring.json and edit)
|
||||
enableWebring: false,
|
||||
|
||||
//web3
|
||||
enableWeb3: false,
|
||||
ethereumNode: '',
|
||||
|
||||
//extension for thumbnails
|
||||
thumbExtension: '.webp',
|
||||
//whether to animate gif thumbnails
|
||||
@@ -395,6 +399,7 @@ module.exports = {
|
||||
geoFlags: false, //show geo flags, requires nginx setup
|
||||
customFlags: false, //show custom flags
|
||||
enableTegaki: true,
|
||||
enableWeb3: false,
|
||||
userPostDelete: true, //allow users to delete their posts
|
||||
userPostSpoiler: true, //allow user to spoiler their post files
|
||||
userPostUnlink: true, //alow user to unlink files fomr their post
|
||||
|
||||
@@ -15,7 +15,7 @@ module.exports = {
|
||||
paramConverter: paramConverter({
|
||||
timeFields: ['hot_threads_max_age', 'inactive_account_time', 'ban_duration', 'board_defaults_filter_ban_duration', 'default_ban_duration', 'block_bypass_expire_after_time', 'dnsbl_cache_time', 'board_defaults_delete_protection_age'],
|
||||
trimFields: ['captcha_options_grid_question', 'captcha_options_grid_trues', 'captcha_options_grid_falses', 'captcha_options_font', 'allowed_hosts', 'dnsbl_blacklists', 'other_mime_types',
|
||||
'highlight_options_language_subset', 'global_limits_custom_css_filters', 'board_defaults_filters', 'filters', 'archive_links', 'reverse_links', 'language', 'board_defaults_language'],
|
||||
'highlight_options_language_subset', 'global_limits_custom_css_filters', 'board_defaults_filters', 'filters', 'archive_links', 'reverse_links', 'language', 'board_defaults_language', 'ethereum_node'],
|
||||
numberFields: ['inactive_account_action', 'abandoned_board_action', 'filter_mode', 'auth_level', 'captcha_options_text_wave', 'captcha_options_text_paint', 'captcha_options_text_noise',
|
||||
'captcha_options_grid_noise', 'captcha_options_grid_edge', 'captcha_options_generate_limit', 'captcha_options_grid_size', 'captcha_options_grid_image_size',
|
||||
'captcha_options_num_distorts_min', 'captcha_options_num_distorts_max', 'captcha_options_distortion', 'captcha_options_grid_icon_y_offset', 'flood_timers_same_content_same_ip', 'flood_timers_same_content_any_ip',
|
||||
|
||||
@@ -8,12 +8,13 @@ const makePost = require(__dirname+'/../../models/forms/makepost.js')
|
||||
, config = require(__dirname+'/../../lib/misc/config.js')
|
||||
, { Files } = require(__dirname+'/../../db/')
|
||||
, paramConverter = require(__dirname+'/../../lib/middleware/input/paramconverter.js')
|
||||
, { checkSchema, lengthBody, existsBody } = require(__dirname+'/../../lib/input/schema.js');
|
||||
, { checkSchema, lengthBody, existsBody } = require(__dirname+'/../../lib/input/schema.js')
|
||||
, web3EthAccounts = require('web3-eth-accounts');
|
||||
|
||||
module.exports = {
|
||||
|
||||
paramConverter: paramConverter({
|
||||
trimFields: ['message', 'name', 'subject', 'email', 'postpassword', 'password'],
|
||||
trimFields: ['message', 'name', 'subject', 'email', 'postpassword', 'password', 'signature'],
|
||||
allowedArrays: ['spoiler', 'strip_filename'],
|
||||
processMessageLength: true,
|
||||
numberFields: ['thread'],
|
||||
@@ -23,7 +24,7 @@ module.exports = {
|
||||
|
||||
const { __ } = res.locals;
|
||||
|
||||
const { globalLimits, disableAnonymizerFilePosting } = config.get;
|
||||
const { globalLimits, disableAnonymizerFilePosting, enableWeb3 } = config.get;
|
||||
|
||||
const hasNoMandatoryFile = globalLimits.postFiles.max !== 0 && res.locals.board.settings.maxFiles !== 0 && res.locals.numFiles === 0;
|
||||
const disableBoardAnonymizerFilePosting = res.locals.board.settings.disableAnonymizerFilePosting && !res.locals.permissions.get(Permissions.MANAGE_BOARD_GENERAL);
|
||||
@@ -50,6 +51,21 @@ module.exports = {
|
||||
{ result: lengthBody(req.body.name, 0, globalLimits.fieldLength.name), expected: false, error: __('Name must be %s characters or less', globalLimits.fieldLength.name) },
|
||||
{ result: lengthBody(req.body.subject, 0, globalLimits.fieldLength.subject), expected: false, error: __('Subject must be %s characters or less', globalLimits.fieldLength.subject) },
|
||||
{ result: lengthBody(req.body.email, 0, globalLimits.fieldLength.email), expected: false, error: __('Email must be %s characters or less', globalLimits.fieldLength.email) },
|
||||
{ result: async () => {
|
||||
if (enableWeb3 === true && res.locals.board.settings.enableWeb3 === true
|
||||
&& req.body.message && req.body.signature) {
|
||||
try {
|
||||
const fixedMessage = req.body.rawMessage.replace(/\r\n/igm, '\n');
|
||||
res.locals.recoveredAddress = await web3EthAccounts.recover(fixedMessage, req.body.signature);
|
||||
return true;
|
||||
} catch(e) {
|
||||
console.warn(e);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}, expected: true, error: __('Failed to verify message signature') },
|
||||
]);
|
||||
|
||||
if (errors.length > 0) {
|
||||
|
||||
@@ -635,6 +635,10 @@ td {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.web3-signature, .web3-address {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.modal-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -1536,7 +1540,8 @@ row.wrap.sb .col {
|
||||
#tab-7:target .tab-7,
|
||||
#tab-8:target .tab-8,
|
||||
#tab-9:target .tab-9,
|
||||
#tab-10:target .tab-10 {
|
||||
#tab-10:target .tab-10,
|
||||
#tab-11:target .tab-11 {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -1549,7 +1554,8 @@ row.wrap.sb .col {
|
||||
#tab-7:target a[href="#tab-7"],
|
||||
#tab-8:target a[href="#tab-8"],
|
||||
#tab-9:target a[href="#tab-9"],
|
||||
#tab-10:target a[href="#tab-10"] {
|
||||
#tab-10:target a[href="#tab-10"],
|
||||
#tab-11:target a[href="#tab-11"] {
|
||||
border-bottom: 1px solid var(--background-rest);
|
||||
background: var(--background-rest);
|
||||
}
|
||||
|
||||
@@ -118,6 +118,13 @@ class postFormHandler {
|
||||
this.tegakiButton.addEventListener('click', () => this.doTegaki());
|
||||
}
|
||||
|
||||
//if web3 signature button, attach the listener to open tegaki
|
||||
this.web3Button = form.querySelector('.web3-button');
|
||||
if (this.web3Button) {
|
||||
this.web3Button.addEventListener('click', () => this.doWeb3Sign());
|
||||
this.messageBox.addEventListener('input', () => this.form.elements.signature.value = '');
|
||||
}
|
||||
|
||||
//if file input, attach listeners for adding files, drag+drop, etc
|
||||
this.fileInput = form.querySelector('input[type="file"]');
|
||||
if (this.fileInput) {
|
||||
@@ -190,6 +197,20 @@ class postFormHandler {
|
||||
Tegaki.setColorPalette(2); //picks a better default color palette
|
||||
}
|
||||
|
||||
async doWeb3Sign() {
|
||||
const messageContent = this.messageBox.value || '';
|
||||
try {
|
||||
const accounts = await window.jschanweb3.eth.requestAccounts();
|
||||
const signature = await window.jschanweb3.currentProvider.request({
|
||||
method: 'personal_sign',
|
||||
params: [messageContent, accounts[0]],
|
||||
});
|
||||
this.form.elements.signature.value = signature;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
updateFlagField() {
|
||||
if (this.customFlagInput && this.customFlagInput.options.selectedIndex !== -1) {
|
||||
this.selectedFlagImage.src = this.customFlagInput.options[this.customFlagInput.options.selectedIndex].dataset.src || '';
|
||||
|
||||
@@ -8,6 +8,9 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
if (!postForm) {
|
||||
return;
|
||||
}
|
||||
history.replaceState({}, '', '#postform');
|
||||
postForm.style.display = 'flex';
|
||||
topPostButton.style.visibility = 'hidden';
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/* globals Web3 */
|
||||
|
||||
if (window.ethereum) {
|
||||
window.jschanweb3 = new Web3(window.ethereum);
|
||||
} else {
|
||||
document.querySelectorAll('.web3')
|
||||
.forEach(elem => elem.remove());
|
||||
}
|
||||
+16
-7
@@ -436,6 +436,7 @@ async function custompages() {
|
||||
yandexSiteKey: yandex ? yandex.siteKey : '',
|
||||
globalAnnouncement: config.get.globalAnnouncement,
|
||||
captchaOptions: config.get.captchaOptions,
|
||||
enableWeb3: config.get.enableWeb3,
|
||||
commit,
|
||||
version,
|
||||
globalLanguage: config.get.language,
|
||||
@@ -511,16 +512,15 @@ const extraLocals = ${JSON.stringify({ meta: config.get.meta, reverseImageLinksU
|
||||
fs.writeFileSync(`gulp/res/js/${templateName}.js`, compiledClient);
|
||||
});
|
||||
|
||||
//symlink web3
|
||||
await fs.symlink(__dirname+'/node_modules/web3/dist/web3.min.js', __dirname+'/gulp/res/js/web3.js', 'file')
|
||||
.catch(e => { console.warn(e); });
|
||||
//symlink socket.io file
|
||||
fs.symlinkSync(__dirname+'/node_modules/socket.io/client-dist/socket.io.min.js', __dirname+'/gulp/res/js/socket.io.js', 'file');
|
||||
await fs.symlink(__dirname+'/node_modules/socket.io/client-dist/socket.io.min.js', __dirname+'/gulp/res/js/socket.io.js', 'file')
|
||||
.catch(e => { console.warn(e); });
|
||||
|
||||
} catch (e) {
|
||||
|
||||
//ignore EEXIST, probably the socket.io
|
||||
if (e.code !== 'EEXIST') {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
gulp.src([
|
||||
@@ -549,10 +549,18 @@ const extraLocals = ${JSON.stringify({ meta: config.get.meta, reverseImageLinksU
|
||||
`!${paths.scripts.src}/catalog.js`,
|
||||
`!${paths.scripts.src}/time.js`,
|
||||
`!${paths.scripts.src}/timezone.js`,
|
||||
`!${paths.scripts.src}/renderweb3.js`,
|
||||
])
|
||||
.pipe(concat('all.js'))
|
||||
.pipe(uglify({compress:true}))
|
||||
.pipe(gulp.dest(paths.scripts.dest));
|
||||
|
||||
gulp.src([
|
||||
`${paths.scripts.src}/web3.js`,
|
||||
])
|
||||
.pipe(concat('web3.js'))
|
||||
// .pipe(uglify({compress:true})) //No need, we symlink from web3.min.js
|
||||
.pipe(gulp.dest(paths.scripts.dest));
|
||||
|
||||
return gulp.src([
|
||||
`${paths.scripts.src}/saveoverboard.js`,
|
||||
@@ -564,6 +572,7 @@ const extraLocals = ${JSON.stringify({ meta: config.get.meta, reverseImageLinksU
|
||||
`${paths.scripts.src}/watchlist.js`,
|
||||
`${paths.scripts.src}/catalog.js`,
|
||||
`${paths.scripts.src}/time.js`,
|
||||
`${paths.scripts.src}/renderweb3.js`,
|
||||
])
|
||||
.pipe(concat('render.js'))
|
||||
.pipe(uglify({compress:true}))
|
||||
|
||||
+3
-2
@@ -16,12 +16,12 @@ const { outputFile } = require('fs-extra')
|
||||
, config = require(__dirname+'/../../lib/misc/config.js');
|
||||
|
||||
let { language, archiveLinksURL, lockWait, globalLimits, boardDefaults, cacheTemplates,
|
||||
reverseImageLinksURL, meta, enableWebring, captchaOptions, globalAnnouncement } = config.get
|
||||
reverseImageLinksURL, meta, enableWebring, captchaOptions, globalAnnouncement, enableWeb3 } = config.get
|
||||
, renderLocals = null;
|
||||
|
||||
const updateLocals = () => {
|
||||
({ language, archiveLinksURL, lockWait, globalLimits, boardDefaults, cacheTemplates,
|
||||
reverseImageLinksURL, meta, enableWebring, captchaOptions, globalAnnouncement } = config.get);
|
||||
reverseImageLinksURL, meta, enableWebring, captchaOptions, globalAnnouncement, enableWeb3 } = config.get);
|
||||
renderLocals = {
|
||||
Permissions,
|
||||
cache: cacheTemplates,
|
||||
@@ -30,6 +30,7 @@ const updateLocals = () => {
|
||||
meta,
|
||||
commit,
|
||||
version,
|
||||
enableWeb3,
|
||||
defaultTheme: boardDefaults.theme,
|
||||
defaultCodeTheme: boardDefaults.codeTheme,
|
||||
postFilesSize: formatSize(globalLimits.postFilesSize.max),
|
||||
|
||||
@@ -33,6 +33,10 @@ module.exports = (options) => {
|
||||
processDateParam, processMessageLength, numberFields, numberArrays,
|
||||
objectIdParams, objectIdFields, objectIdArrays } = options;
|
||||
|
||||
if (req.body.message) {
|
||||
req.body.rawMessage = req.body.message;
|
||||
}
|
||||
|
||||
/* check all body fields, body-parser prevents this array being too big, so no worry.
|
||||
whitelist for fields that can be arrays, and convert singular of those fields to 1 length array */
|
||||
const bodyFields = Object.keys(req.body || {});
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
//NOTE: unused (for now)
|
||||
|
||||
const { Web3 } = require('web3')
|
||||
, config = require(__dirname+'/../misc/config.js')
|
||||
, { addCallback } = require(__dirname+'/../redis/redis.js')
|
||||
, web3 = new Web3(config.get.ethereumNode);
|
||||
|
||||
const updateWeb3Provider = () => {
|
||||
web3.setProvider(config.get.ethereumNode);
|
||||
};
|
||||
|
||||
addCallback('config', updateWeb3Provider);
|
||||
|
||||
module.exports = web3;
|
||||
@@ -31,6 +31,7 @@ const { Boards, Posts } = require(__dirname+'/../../db/')
|
||||
'allowedFileTypes.image': ['board', 'threads', 'catalog'],
|
||||
'enableTegaki': ['board', 'threads', 'catalog'],
|
||||
'hideBanners': ['board', 'threads', 'catalog'],
|
||||
'enableWeb3': ['board', 'threads', 'catalog'],
|
||||
});
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
@@ -73,6 +74,7 @@ module.exports = async (req, res) => {
|
||||
'geoFlags': booleanSetting(req.body.geo_flags),
|
||||
'customFlags': booleanSetting(req.body.custom_flags),
|
||||
'enableTegaki': booleanSetting(req.body.enable_tegaki),
|
||||
'enableWeb3': booleanSetting(req.body.enable_web3),
|
||||
'forceAnon': booleanSetting(req.body.force_anon),
|
||||
'sageOnlyEmail': booleanSetting(req.body.sage_only_email),
|
||||
'userPostDelete': booleanSetting(req.body.user_post_delete),
|
||||
|
||||
@@ -21,6 +21,7 @@ const { Boards } = require(__dirname+'/../../db/')
|
||||
'archiveLinksURL': ['deletehtml', 'custompages'],
|
||||
'reverseImageLinksURL': ['deletehtml', 'custompages'],
|
||||
'enableWebring': ['deletehtml', 'custompages'],
|
||||
'enableWeb3': ['deletehtml'],
|
||||
'thumbSize': ['deletehtml', 'css', 'scripts'],
|
||||
'previewReplies': ['deletehtml', 'custompages'],
|
||||
'stickyPreviewReplies': ['deletehtml', 'custompages'],
|
||||
@@ -140,12 +141,14 @@ module.exports = async (req, res) => {
|
||||
dontStoreRawIps: booleanSetting(req.body.dont_store_raw_ips, oldSettings.dontStoreRawIps),
|
||||
pruneIps: numberSetting(req.body.prune_ips, oldSettings.pruneIps),
|
||||
enableWebring: booleanSetting(req.body.enable_webring, oldSettings.enableWebring),
|
||||
enableWeb3: booleanSetting(req.body.enable_web3, oldSettings.enableWeb3),
|
||||
ethereumNode: trimSetting(req.body.ethereum_node, oldSettings.ethereumNode),
|
||||
following: arraySetting(req.body.webring_following, oldSettings.following),
|
||||
blacklist: arraySetting(req.body.webring_blacklist, oldSettings.blacklist),
|
||||
logo: arraySetting(req.body.webring_logos, oldSettings.logo),
|
||||
proxy: {
|
||||
enabled: booleanSetting(req.body.webring_proxy_enabled, oldSettings.proxy.enabled),
|
||||
address: trimSetting(req.body.webring_proxy_address, oldSettings.proxy.address),
|
||||
enabled: booleanSetting(req.body.proxy_enabled, oldSettings.proxy.enabled),
|
||||
address: trimSetting(req.body.proxy_address, oldSettings.proxy.address),
|
||||
},
|
||||
thumbExtension: trimSetting(req.body.thumb_extension, oldSettings.thumbExtension),
|
||||
highlightOptions: {
|
||||
|
||||
@@ -427,6 +427,14 @@ module.exports = async (req, res) => {
|
||||
const nomarkup = prepareMarkdown(req.body.message, true);
|
||||
const { message, quotes, crossquotes } = await messageHandler(nomarkup, req.params.board, req.body.thread, res.locals.permissions);
|
||||
|
||||
//web3 sig
|
||||
let signature = null
|
||||
, address = null;
|
||||
if (res.locals.recoveredAddress) {
|
||||
signature = req.body.signature;
|
||||
address = res.locals.recoveredAddress;
|
||||
}
|
||||
|
||||
//build post data for db. for some reason all the property names are lower case :^)
|
||||
const now = Date.now();
|
||||
const data = {
|
||||
@@ -445,6 +453,8 @@ module.exports = async (req, res) => {
|
||||
password,
|
||||
email,
|
||||
spoiler,
|
||||
signature,
|
||||
address,
|
||||
'banmessage': null,
|
||||
userId,
|
||||
'ip': res.locals.ip,
|
||||
|
||||
Generated
+1012
-4
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -54,7 +54,9 @@
|
||||
"socket.io": "^4.6.1",
|
||||
"socks-proxy-agent": "^6.2.1",
|
||||
"uid-safe": "^2.1.5",
|
||||
"unix-crypt-td-js": "^1.1.4"
|
||||
"unix-crypt-td-js": "^1.1.4",
|
||||
"web3": "^4.0.1",
|
||||
"web3-eth-accounts": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.36.0",
|
||||
|
||||
@@ -68,7 +68,7 @@ const config = require(__dirname+'/lib/misc/config.js')
|
||||
|
||||
const loadAppLocals = () => {
|
||||
const { language, cacheTemplates, boardDefaults, globalLimits, captchaOptions, archiveLinksURL,
|
||||
reverseImageLinksURL, meta, enableWebring, globalAnnouncement } = config.get;
|
||||
reverseImageLinksURL, meta, enableWebring, globalAnnouncement, enableWeb3 } = config.get;
|
||||
//cache loaded templates
|
||||
app.cache = {};
|
||||
app[cacheTemplates === true ? 'enable' : 'disable']('view cache');
|
||||
@@ -80,6 +80,7 @@ const config = require(__dirname+'/lib/misc/config.js')
|
||||
app.locals.archiveLinksURL = archiveLinksURL;
|
||||
app.locals.reverseImageLinksURL = reverseImageLinksURL;
|
||||
app.locals.enableWebring = enableWebring;
|
||||
app.locals.enableWeb3 = enableWeb3;
|
||||
app.locals.commit = commit;
|
||||
app.locals.version = version;
|
||||
app.locals.meta = meta;
|
||||
|
||||
+1
-1
@@ -238,7 +238,7 @@ module.exports = () => describe('login and create test board', () => {
|
||||
global_limits_asset_files_size_max: '10485760',
|
||||
global_limits_asset_files_max: '10',
|
||||
global_limits_asset_files_total: '50',
|
||||
webring_proxy_address: '',
|
||||
proxy_address: '',
|
||||
webring_following: '',
|
||||
webring_logos: '',
|
||||
webring_blacklist: '',
|
||||
|
||||
@@ -39,6 +39,10 @@ script(src=`/js/lang/${pageLanguage}.js?v=${commit}`)
|
||||
//- main script
|
||||
script(src=`/js/all.js?v=${commit}&ct=${captchaOptions.type}`)
|
||||
|
||||
//- optional web3 script
|
||||
if enableWeb3 || isBoard && board.settings.enableWeb3
|
||||
script(src=`/js/web3.js?v=${commit}`)
|
||||
|
||||
//- additional scripts included only if hcaptcha, recaptcha, or yandex smartcaptcha are used
|
||||
if captchaOptions.type === 'google'
|
||||
script(src='https://www.google.com/recaptcha/api.js' async defer)
|
||||
|
||||
@@ -40,6 +40,11 @@ section.form-wrapper.flex-center
|
||||
- const minLength = (isThread ? board.settings.minReplyMessageLength : board.settings.minThreadMessageLength) || 0;
|
||||
- const maxLength = Math.min((isThread ? board.settings.maxReplyMessageLength : board.settings.maxThreadMessageLength), globalLimits.fieldLength.message) || globalLimits.fieldLength.message;
|
||||
textarea#message(name='message', rows='5', autocomplete='off' minlength=minLength maxlength=maxLength required=messageRequired)
|
||||
if enableWeb3 === true && board.settings.enableWeb3 === true
|
||||
section.row.jsonly.web3
|
||||
.label #{__('Web3')}
|
||||
input.dummy-link.web3-button(type='button', value=__('Sign'))
|
||||
textarea.ml-1.no-resize(name='signature', rows='1', autocomplete='off' readonly)
|
||||
if board.settings.maxFiles > 0 && Object.values(board.settings.allowedFileTypes).some(x => x === true)
|
||||
- const maxFiles = board.settings.maxFiles;
|
||||
section.row
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
include ../mixins/web3signature.pug
|
||||
+web3signature(signature, address)
|
||||
@@ -1,5 +1,6 @@
|
||||
include ./report.pug
|
||||
include ./banmessage.pug
|
||||
include ./web3signature.pug
|
||||
mixin post(post, truncate, manage=false, globalmanage=false, ban=false, overboard=false)
|
||||
.anchor(id=post.postId)
|
||||
div(class=`post-container ${post.thread || ban === true ? '' : 'op'}`
|
||||
@@ -162,6 +163,8 @@ mixin post(post, truncate, manage=false, globalmanage=false, ban=false, overboar
|
||||
| #{lastEdited[1]}
|
||||
if post.banmessage
|
||||
+banmessage(post.banmessage)
|
||||
if post.signature && post.address
|
||||
+web3signature(post.signature, post.address)
|
||||
if truncatedMessage !== post.message
|
||||
div.cb.mt-5.ml-5
|
||||
| #{__('Message too long.')} #[a.viewfulltext(href=`${postURL}#${post.postId}`) #{__('View the full text')}]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
mixin web3signature(signature, address)
|
||||
.web3-address #{__('Address: %s', address)}
|
||||
.web3-signature #{__('Signature: %s', signature)}
|
||||
@@ -54,11 +54,13 @@ block content
|
||||
li
|
||||
a(href='#tab-7') #{__('Webring')}
|
||||
li
|
||||
a(href='#tab-8') #{__('Files & Thumbnails')}
|
||||
a(href='#tab-8') #{__('Web3')}
|
||||
li
|
||||
a(href='#tab-9') #{__('Frontend Script Defaults')}
|
||||
a(href='#tab-9') #{__('Files & Thumbnails')}
|
||||
li
|
||||
a(href='#tab-10') #{__('Board Defaults')}
|
||||
a(href='#tab-10') #{__('Frontend Script Defaults')}
|
||||
li
|
||||
a(href='#tab-11') #{__('Board Defaults')}
|
||||
.box-wrap
|
||||
.tab.tab-1
|
||||
.col
|
||||
@@ -170,6 +172,13 @@ block content
|
||||
.row
|
||||
.label #{__('Prune IPs Days')}
|
||||
input(type='number', name='prune_ips' value=settings.pruneIps)
|
||||
.row
|
||||
.label #{__('Use Socks Proxy')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='proxy_enabled', value='true' placeholder='socks5h://127.0.0.1:9050' checked=settings.proxy.enabled)
|
||||
.row
|
||||
.label #{__('Proxy Address')}
|
||||
input(type='text', name='proxy_address', value=settings.proxy.address)
|
||||
|
||||
.tab.tab-3
|
||||
.col
|
||||
@@ -527,13 +536,6 @@ block content
|
||||
.label #{__('Enable')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='enable_webring' value='true' checked=settings.enableWebring)
|
||||
.row
|
||||
.label #{__('Use Socks Proxy')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='webring_proxy_enabled', value='true' placeholder='socks5h://127.0.0.1:9050' checked=settings.proxy.enabled)
|
||||
.row
|
||||
.label #{__('Proxy Address')}
|
||||
input(type='text', name='webring_proxy_address', value=settings.proxy.address)
|
||||
.row
|
||||
.label #{__('Following')}
|
||||
textarea(name='webring_following' placeholder=__('Newline separated')) #{settings.following.join('\n')}
|
||||
@@ -545,6 +547,22 @@ block content
|
||||
textarea(name='webring_blacklist' placeholder=__('Newline separated')) #{settings.blacklist.join('\n')}
|
||||
|
||||
.tab.tab-8
|
||||
.col
|
||||
.row
|
||||
.label #{__('Enable')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='enable_web3' value='true' checked=settings.enableWeb3)
|
||||
.row
|
||||
.label
|
||||
| #{__('Ethereum Node')}
|
||||
|
|
||||
small
|
||||
| (
|
||||
a(rel='nofollow' referrerpolicy='same-origin' target='_blank' href='https://ethereumnodes.com/') #{__('Nodes')}
|
||||
| )
|
||||
input(type='text' name='ethereum_node' value=settings.ethereumNode)
|
||||
|
||||
.tab.tab-9
|
||||
.col
|
||||
.row
|
||||
.label #{__('Animated .gif Thumbnails')}
|
||||
@@ -588,7 +606,7 @@ block content
|
||||
.label #{__('Video Max Resolution')}
|
||||
input(type='text' name='global_limits_post_files_size_video_resolution' value=settings.globalLimits.postFilesSize.videoResolution)
|
||||
|
||||
.tab.tab-9
|
||||
.tab.tab-10
|
||||
.col
|
||||
.row
|
||||
.label #{__('Embeds Enabled')}
|
||||
@@ -685,7 +703,7 @@ block content
|
||||
.label #{__('Tegaki Height')}
|
||||
input(type='number', name='frontend_script_default_tegaki_height', value=settings.frontendScriptDefault.tegakiHeight)
|
||||
|
||||
.tab.tab-10
|
||||
.tab.tab-11
|
||||
.col
|
||||
.row
|
||||
.label #{__('SFW')}
|
||||
@@ -793,6 +811,10 @@ block content
|
||||
.label #{__('Enable Tegaki')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='board_defaults_enable_tegaki', value='true' checked=settings.boardDefaults.enableTegaki)
|
||||
.row
|
||||
.label #{__('Enable Web3')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='board_defaults_enable_web3', value='true' checked=settings.boardDefaults.enableWeb3)
|
||||
.row
|
||||
.label #{__('User Post Deletion')}
|
||||
label.postform-style.ph-5
|
||||
|
||||
@@ -118,6 +118,10 @@ block content
|
||||
.label #{__('Enable Tegaki')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='enable_tegaki', value='true' checked=board.settings.enableTegaki)
|
||||
.row
|
||||
.label #{__('Enable Web3')}
|
||||
label.postform-style.ph-5
|
||||
input(type='checkbox', name='enable_web3', value='true' checked=board.settings.enableWeb3)
|
||||
.row
|
||||
.label #{__('SFW')}
|
||||
label.postform-style.ph-5
|
||||
|
||||
Reference in New Issue
Block a user