Compare commits

..

No commits in common. "89ea760ce382654981be507281aa4a2e883caadc" and "2b1e2d695a0a7bee7c6aac22359df213c7ac9f4b" have entirely different histories.

8 changed files with 25 additions and 151 deletions

View file

@ -77,7 +77,6 @@ export default class Client {
}
if (!options.getRaw && output.status && typeof(output.status) === 'number') {
let err = new Error(`Request failed [${output.status}]: ${output.message}`)
err.url = path
err.body = output
return reject(err)
}

View file

@ -1 +0,0 @@
package-lock=false

View file

@ -12,7 +12,7 @@
**/
const AlphabeticID = {
index:'WzPmtXQhwGnOiB8Vvu9fC1SL2l4F7MrUNc0RbD6dAayI3YTosejpZxJH5KqgEk', // abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
index:'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
/**
* [@function](https://twitter.com/function) AlphabeticID.encode

View file

@ -1,13 +1,11 @@
import { uploadMedia, deleteFile } from '../base/media/upload.mjs'
import { uploadMedia } from '../base/media/upload.mjs'
import config from '../base/config.mjs'
import AlphabeticID from './id.mjs'
export default class IndexPost {
constructor(opts = {}) {
Object.assign(this, {
frontend: opts.frontend,
uploadMedia: uploadMedia,
deleteFile: deleteFile,
})
}
@ -46,41 +44,12 @@ export default class IndexPost {
}
}
async getLink(ctx) {
return this.serve.serveIndex(ctx)
}
/** POST: / */
/** PUT: /api/auth/articles/:id */
async createNewLink(ctx) {
let hasMedia = ctx.req.files.media && ctx.req.files.media.size
ctx.state.video = ctx.req.body.video
ctx.state.image = ctx.req.body.image
let rateLimited = false
let redisKey = 'ratelimit_' + ctx.req.ip.replace(/:/g, '-')
try {
let val = (await ctx.redis.get(redisKey))
console.log(redisKey, val)
val = val && Number(val) || 0
if (val > 3) {
rateLimited = true
} else if (val > 2) {
await ctx.redis.setex(redisKey, 60 * 15, val + 1)
rateLimited = true
} else {
await ctx.redis.setex(redisKey, 15, val + 1)
}
} catch (err) {
ctx.log.error(err, 'Error checking rate limit for ' + redisKey)
}
if (rateLimited) {
ctx.state.error = 'You have reached rate limit. Please wait at least 15 minutes.'
return this.serve.serveIndex(ctx)
}
let hasMedia = ctx.req.files.media && ctx.req.files.media.size
let redirect = ''
let error = this.hasErrors(ctx, hasMedia)
@ -88,10 +57,6 @@ export default class IndexPost {
try {
let temp = await this.uploadMedia(ctx.req.files.media)
ctx.state.image = ctx.req.body.image = 'https://cdn.nfp.is' + temp.sizes.small.jpeg.path
await this.deleteFile(temp.filename).catch(err => {
ctx.log.error(err, 'Error removing ' + temp.filename)
})
}
catch (err) {
ctx.log.error(err)
@ -105,13 +70,9 @@ export default class IndexPost {
if (!error) {
try {
let params = [
ctx.state.video,
ctx.state.image,
ctx.req.ip,
]
let res = await ctx.db.safeCallProc('discord_embed.link_add', params)
let id = AlphabeticID.encode(res.first[0].id + 3843)
redirect = `${this.frontend}/${id}`
console.log(res)
}
catch (err) {
ctx.log.error(err)

View file

@ -4,7 +4,6 @@ import fs from 'fs/promises'
import fsSync from 'fs'
import dot from 'dot'
import config from '../base/config.mjs'
import AlphabeticID from './id.mjs'
export default class ServeHandler extends Parent {
loadTemplate(indexFile) {
@ -28,31 +27,12 @@ export default class ServeHandler extends Parent {
this.loadTemplate(indexFile)
}
let videoLink = ctx.query.get('v') || ''
let imageLink = ctx.query.get('i') || ''
if (ctx.url.match(/^\/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]+$/)) {
try {
let id = AlphabeticID.decode(ctx.url.slice(1))
if (id) {
let res = await ctx.db.safeCallProc('discord_embed.link_get', [id - 3843])
if (res.first.length) {
videoLink = res.first[0].video_link
imageLink = res.first[0].image_link
}
}
} catch (err) {
ctx.log.error(err)
ctx.state.error = 'Unknown error while fetching link.'
}
}
let payload = {
videoLink: videoLink,
imageLink: imageLink,
imageLink: ctx.query.get('i') || '',
videoLink: ctx.query.get('v') || '',
error: ctx.state.error || '',
inputVideo: ctx.state.video || videoLink || '',
inputImage: ctx.state.image || imageLink || '',
inputVideo: ctx.state.video || ctx.query.get('v') || '',
inputImage: ctx.state.image || ctx.query.get('i') || '',
siteUrl: this.frontend + ctx.url,
siteUrlBase: this.frontend + '/',
version: this.version,

View file

@ -1,4 +1,3 @@
import Redis from 'ioredis'
import config from '../base/config.mjs'
import Parent from '../base/server.mjs'
import IndexPost from './post.mjs'
@ -9,12 +8,6 @@ export default class Server extends Parent {
super.init()
let localUtil = new this.core.sc.Util(import.meta.url)
this.flaskaOptions.appendHeaders['Content-Security-Policy'] = `default-src 'self'; script-src 'self' 'nonce-0d1valZOnjp8ZpR6vBd4dg=='; style-src 'self' 'unsafe-inline'; img-src * data: blob:; media-src *; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'`
this.flaskaOptions.appendHeaders['Cross-Origin-Embedder-Policy'] = 'unsafe-none'
this.redis = new Redis(config.get('redis'))
this.redis.on('error', (err) => {
this.core.log.error(err)
})
this.routes = {
post: new IndexPost({
frontend: config.get('frontend:url'),
@ -26,13 +19,4 @@ export default class Server extends Parent {
frontend: config.get('frontend:url'),
})
}
runCreateServer() {
super.runCreateServer()
this.flaska.before((ctx) => {
ctx.redis = this.redis
})
}
}

View file

@ -1,5 +1,5 @@
{
"name": "discord_embed",
"name": "av1_embed",
"version": "1.0.0",
"port": 4120,
"description": "AV1 discord server embed helper",
@ -35,7 +35,6 @@
},
"homepage": "https://git.nfp.is/nfp/nfp_sites",
"dependencies": {
"bunyan-lite": "^1.2.1",
"dot": "^2.0.0-beta.1",
"flaska": "^1.3.0",
"formidable": "^1.2.6",

View file

@ -47,7 +47,6 @@ body {
text-rendering: optimizeSpeed;
line-height: 1.5;
font-size: 16px;
padding: 1rem 0.5rem;
font-family: sans-serif;
background: var(--bg);
color: var(--color);
@ -58,16 +57,16 @@ input, button, textarea, select {
}
h1 {
font-size: 1.88rem;
font-size: 2.488rem;
}
h2 {
font-size: 1.66rem;
font-size: 2.074rem;
}
h3 {
font-size: 1.44rem;
font-size: 1.728rem;
}
h4 {
font-size: 1.22rem;
font-size: 1.44rem;
}
h5 {
font-size: 1.0rem;
@ -124,8 +123,6 @@ input[type=submit] {
pre {
background: var(--bg-content-alt);
padding: 0.5rem;
white-space: break-spaces;
word-break: break-all;
}
.row {
@ -153,15 +150,6 @@ pre {
padding: 1rem 1rem 0;
}
.center {
text-align: center;
}
video {
max-width: calc(100vw - 2rem);
max-height: calc(100vh - 140px);
}
.inside {
width: 100%;
max-width: var(--content-max-width);
@ -174,24 +162,15 @@ video {
</style>
</head>
<body>
{{ if (videoLink && imageLink) { }}
<p>Your link is:</p>
<pre>{{=siteUrl}}</pre>
<div class="center">
<video controls poster="{{=imageLink}}">
<source src="{{=videoLink}}">
</video>
</div>
{{ } }}
<form action="/" method="post" enctype="multipart/form-data" class="inside">
<h1>Create/generate embed url</h1>
{{ if (error) { }}<p class="error">{{=error}}</p>{{ } }}
<label>Video link</label>
<input id="inputVideo" type="text" name="video" value="{{=inputVideo}}">
<input type="text" name="video" value="{{=inputVideo}}">
<div class="row">
<div class="row-item">
<label>Image link (required for proper discord embed)</label>
<input id="inputImage" type="text" name="image" value="{{=inputImage}}">
<input type="text" name="image" value="{{=inputImage}}">
</div>
<span class="row-inbetween">or</span>
<div class="row-item">
@ -200,41 +179,14 @@ video {
</div>
</div>
<input type="submit" value="Generate short url">
<input type="submit" value="Generate embed url">
<p>
Alternatively, you can generate a link yourself using the following syntax:
</p>
<pre>
{{=siteUrlBase}}?v=&lt;video link&gt;&amp;i=&lt;image link&gt;
</pre>
</form>
<p>
Alternatively, copy paste the following full url:
</p>
<pre id="generateurl">
{{=siteUrlBase}}?v=&lt;video link&gt;&amp;i=&lt;image link&gt;
</pre>
<script type="text/javascript" nonce="{{=nonce}}">
var baseSite = '{{=siteUrlBase}}';
var generateurl = document.getElementById('generateurl');
var inputVideo = document.getElementById('inputVideo');
var inputImage = document.getElementById('inputImage');
var isExample = true;
function checkChange() {
var currentIsExample = true;
if (inputVideo.value && inputImage.value) {
currentIsExample = false;
}
if (isExample && currentIsExample) { return; }
isExample = currentIsExample;
if (isExample) {
generateurl.innerText = baseSite + '?v=<video link>&i=<image link>';
} else {
generateurl.innerText = baseSite + '?v=' + encodeURI(inputVideo.value) + '&i=' + encodeURI(inputImage.value);
}
};
inputVideo.addEventListener('change', checkChange);
inputImage.addEventListener('change', checkChange);
inputVideo.addEventListener('keyup', checkChange);
inputImage.addEventListener('keyup', checkChange);
checkChange()
</script>
</body>
</html>