This commit is contained in:
PaperStaple 2019-03-23 23:28:23 -07:00
commit 6efbb811a3
16 changed files with 755 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
node_modules
.env
cookies/bogdan.json
cookies/anonbot.json
*.jpeg
submission.jpeg
response.jpeg
package-lock.json
blacklist.txt
logs.json

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Matthew Stanciu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

53
README.md Normal file
View File

@ -0,0 +1,53 @@
# Anonbot
A bot for West Side students to submit confessions and announce anonymously!
# Rules
We want Anonbot to be a fun experience for everyone, so generally we allow you to post whatever you want. However, there are a few things there are a few exceptions that you need to be aware of before posting. Breaking these rules will get your post deleted, and repeated offenses will get you IPbanned.
**1. Don't post anything that goes against Instagram's terms of use.** Use common sense here. Don't post anything that discriminates against a group of people (e.g. racist, sexist, homophobic, etc.), anything that can cause people harm (e.g. telling someone to kill themself), or anything illegal (e.g. killing prominent figures and politicians). Essentially, don't post anything that can get reported and taken down by Instagram, and please don't post anything that will get the police called.
**2. Don't bully anyone.** Making lighthearted fun of people is part of what makes Anonbot fun. But if it crosses the line into bullying, it crosses over into rule 1. Don't deliberately put any one person or group down. **This includes making posts that shit-talk other people.** You should be able to understand the difference between making jokes and bullying someone.
**3. Don't spread false rumors.** This kind of goes along with rule 2. I wanted to give this point its own separate rule because I think it needs to be explicitly stated that this is not okay. Anonbot is not a place where you go to spread rumors about students at our school that could get them in trouble, both with other students and with the school administration. Imagine having your reputation ruined by an Instagram bot. That's incredibly stupid. Don't be a part of that.
**4. Don't spam.** This is one of the most annoying rules to have to enforce. *Don't spam.* Spam should be self-explanatory. Spamming will likely get you IPbanned quicker than anything else here.
**5. Don't excessively shitpost.** This kind of goes along with rule 4. Shitposting makes up a large part of Anonbot's posts, so it's okay to shitpost. It's part of what makes Anonbot fun. But please don't spam the Anonbot feed with stupid things like one-word posts or all-emoji posts. That's just annoying. Posting this kind of stuff probably won't get you banned (unless it crosses over to excessive spam territory), but it will probably get your post deleted. Just don't do it. You're not funny.
**Reporting:** If you see a post that you feel is breaking one or more of these rules and should be removed, please don't report it to Instagram! That will put Anonbot as a whole at risk of being deleted. Instead, please DM the account and we will take it down.
---
In order to enforce these rules and ban people who are repeatedly breaking rules, Anonbot temporarily logs *IP hashes* of everyone who posts something. See *What are IP hashes and can I be tracked with them?* (short answer: no) and *I've heard of something like this before where the creators released personal info anyway. How can I be sure this is not the case with Anonbot?* in the **FAQ** section for more info.
Anonbot has moderation tools that a group of moderators use to delete posts, make mod posts (posts with a red background), and IPban people who post things that warrant a ban. Please don't be the guy who turns on their VPN to keep spamming after we've already banned you. There are 8 of us. We will keep banning you until you give up. You have better things to do. Don't be an asshole.
Finally, if you've been banned and you feel your ban is unjust, or you want to try to be unbanned after you've done something wrong, please don't be afraid to DM the Instagram account. We really don't care who you are; we just want to keep Anonbot safe and spam-free. So if you just talk to us, we will probably be more than happy to unban you.
# FAQ
**Q: What are IP hashes and can I be tracked with them?**\
A: Every time you post, Anonbot retrives your IP and runs it through a SHA256 hashing algorithm. This algorithm encrypts your IP by converting it to a 64-character string of seemingly random characters. It is then stored in a database for a short period of time. It is impossible to reverse a hash function, which means it is impossible for us to see your IP. You are completely anonymous when you use Anonbot; **you can not be tracked at all.** [Read more about hashes and how they are used in cryptography](https://en.wikipedia.org/wiki/SHA-2)
**Q: Why do you log IP hashes?**\
A: We want to make sure Anonbot isn't ruined by spammers and trolls, so we store IP hashes for a short period of time in order to keep track of recent posts. If we find repeated violations of the rules above from one IP address, that person will be banned from using Anonbot.
**Q: I've heard of something like this before where the creators released personal info anyway. How can I be sure this is not the case with Anonbot?**\
A: Part of Anonbot's dedication to open-source code is to alleviate these kinds of worries. Anonbot does not store any personal information. We cannot use your IP hash to track you or find your personal information (see *What are IP hashes and can I be tracked with them?*). Your name, Instagram account, etc. are not stored. **Even if we wanted to, Anonbot is made in a way that does not allow us to find who submitted a post.** If you would like to verify this claim, you can look at the code for Anonbot, which is completely open-source (click on "View code on GitHub" at the bottom of the webpage and find the *server.js* file). Please DM if you'd like to be walked through the code.
**Q: I've just seen a post on Anonbot that I believe is inappropriate. How can I get it removed?**\
A: If you see a post that you believe to be inappropriate, please do not report it to Instagram (this puts Anonbot as a whole at risk!). Instead, please DM **@anonbot.wl** to contact a moderator for deletion. Doing this will help moderate Anonbot and keep track of those who break the rules without risking the deletion of Anonbot as a whole by Instagram.
**Q: Is the school administration okay with this?**\
A: Anonbot was first created on June 20th, 2018, and v2 was first implemented on July 14th, 2018. Because Anonbot was created during the summer, the school administration does not know about it (see the dislcaimers section). We do not believe Anonbot is breaking any school rules, but if any conflicts arise in the future, we will comply fully.
# Disclaimers
For moderation purposes, every submission, as well as a hash of the IP address of the submitter, is logged for 10 days. We do not use the hash of your IPs for any purpose other than to ban those who break the rules repeatedly. Furthermore, the hashes are irreversible and cannot be tracked back to the original IP. This should not affect you as long as you use Anonbot properly.
Anonbot is not endorsed by or affiliated with the West Lafayette High School in any way. This is simply a small and fun project created by West Side students.
If you believe a post should be taken down or have any questions/concerns about Anonbot, please email matthew@matthewstanciu.me or DM @anonbot.wl.
---
[View on Glitch](https://glitch.com/edit/#!/anonbotwl?path=README.md:1:0)

Binary file not shown.

Binary file not shown.

38
package.json Normal file
View File

@ -0,0 +1,38 @@
{
"name": "anonbotv2",
"version": "2.0.0",
"description": "A bot for West Side students to submit confessions and announce anonymously",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"airtable": "^0.5.6",
"bignumber-to-string": "^0.1.4",
"body-parser": "^1.18.3",
"bootstrap": "^4.1.2",
"canvas": "^2.0.0-alpha.12",
"clipboard": "^2.0.4",
"crypto-js": "^3.1.9-1",
"date-and-time": "^0.6.2",
"dotenv": "^6.0.0",
"express": "^4.16.3",
"instagram-id-to-url-segment": "0.0.0",
"instagram-private-api": "^0.6.8",
"png-to-jpeg": "^1.0.1",
"popper.js": "^1.14.3",
"word-wrap": "^1.2.3"
},
"engines": {
"node": "8.x"
},
"repository": {
"url": "https://glitch.com/edit/#!/hello-express"
},
"license": "MIT",
"keywords": [
"node",
"glitch",
"express"
]
}

131
public/style.css Normal file
View File

@ -0,0 +1,131 @@
html {
font-family: 'SourceCodePro';
font-size: 35px;
color: white;
text-align: center;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display:table;
}
body {
display: table-cell;
vertical-align:middle;
background: linear-gradient(-45deg, #7a0000, #606060, #151515);
background-size: 400% 400%;
-webkit-animation: AnimationName 30s ease infinite;
-moz-animation: AnimationName 30s ease infinite;
animation: AnimationName 30s ease infinite;
}
h1 {
margin-top: 20pt;
}
h1, h2, h3, h4 {
font-family: 'SourceCodeProBold';
font-weight: 500;
}
p {
font-size: 15px;
}
a {
color: white;
}
textarea {
border-radius: 25px;
border: 2px solid #191414;
padding: 15px;
width: 320px;
height: 125px;
font-family: 'SourceCodePro';
}
input {
border-radius: 25px;
border: 2px solid #191414;
padding: 15px;
width: 200px;
height: 5px;
font-family: 'SourceCodePro';
}
button {
border-radius: 20px;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border: 2px solid #191414;
width: 115px;
height: 40px;
background: white;
transition: 0.2s;
}
button:hover {
background: #878787;
transition: 0.2s;
}
@-webkit-keyframes AnimationName {
0%{background-position:0% 50%}
50%{background-position:100% 50%}
100%{background-position:0% 50%}
}
@-moz-keyframes AnimationName {
0%{background-position:0% 50%}
50%{background-position:100% 50%}
100%{background-position:0% 50%}
}
@keyframes AnimationName {
0%{background-position:0% 50%}
50%{background-position:100% 50%}
100%{background-position:0% 50%}
}
#snackbar {
visibility: hidden;
font-size: 15px;
min-width: 50px;
background-color: #FFF;
color: #333;
text-align: center;
border-radius: 2px;
padding: 16px;
position: fixed;
z-index: 1;
right: 25%;
left: 25%;
top: 30px;
}
/*Snackbar for if user comments on the wrong post*/
#snackbar.show {
visibility: visible;
-webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
@-webkit-keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 30px; opacity: 1;}
}
@keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 30px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {top: 30px; opacity: 1;}
to {top: 0; opacity: 0;}
}
@keyframes fadeout {
from {top: 30px; opacity: 1;}
to {top: 0; opacity: 0;}
}
@font-face {
font-family: 'SourceCodePro';
src: url('https://cdn.glitch.com/3269c758-900f-4003-a9b7-a3d1b265644c%2FSourceCodePro-Regular.ttf?1535915943477');
}
@font-face {
font-family: 'SourceCodeProBold';
src: url('https://cdn.glitch.com/3269c758-900f-4003-a9b7-a3d1b265644c%2FSourceCodePro-Bold.ttf?1535920143884');
}

318
server.js Normal file
View File

@ -0,0 +1,318 @@
require('dotenv').config();
var fs = require('fs');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var http = require('http').Server(app);
var ref = require('instagram-id-to-url-segment');
let date = require('date-and-time');
var urlSegmentToInstagramId = ref.urlSegmentToInstagramId;
var Client = require('instagram-private-api').V1;
var device = new Client.Device('anonbot.wl');
var storage = new Client.CookieFileStorage(__dirname + '/cookies/anonbot.json');
const pngToJpeg = require('png-to-jpeg');
var wrap = require('word-wrap');
const { createCanvas, loadImage, registerFont } = require('canvas');
registerFont('./fonts/SourceCodePro-Regular.ttf', {family: 'SourceCodePro'});
const canvas = createCanvas(1080, 1080);
const ctx = canvas.getContext('2d');
var Airtable = require('airtable');
var logs = new Airtable({apiKey: process.env.AIRTABLE_API_KEY}).base('appDowHJJVQTHNJfk');
var blacklist = new Airtable({apiKey: process.env.AIRTABLE_API_KEY}).base('applZHoMDx5uF9h1Z');
var sha256 = require('crypto-js/sha256');
function createSubmission(text, fillStyle, ip, isResponse, responseText, color) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var formatted = wrap(text, {indent: '', width: 28});
var truncated = formatted.length > 355 ? formatted.substr(0, 356) + "\u2026" : formatted;
ctx.fillStyle = fillStyle;
ctx.fillRect(0, 0, 1080, 1080);
ctx.font = '62px "SourceCodePro"';
ctx.fillStyle = '#FFF';
ctx.fillText(truncated, 17, 65);
var buf = canvas.toBuffer();
fs.writeFileSync("submission.png", buf);
//convert to jpeg because currently api only supports jpeg
let buffer = fs.readFileSync("./submission.png");
pngToJpeg()(buffer)
.then(output => fs.writeFile("./submission.jpeg", output, function(err) {
if (err) console.log(err);
fs.exists("./submission.jpeg", function(exists) {
if (exists && isResponse) publish(responseText, ip, isResponse, color);
else if (exists && !isResponse) publish(text, ip, isResponse, color);
})
}));
fs.unlinkSync('./submission.png');
}
function createResponse(text, originalText, ip, color) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
var formatted = wrap(text, {indent: '', width: 28});
var truncated = formatted.length > 355 ? formatted.substr(0, 356) + "\u2026" : formatted;
if (color === "red") ctx.fillStyle = "#b20000";
else ctx.fillStyle = "#404040";
//ctx.fillStyle = "#c6c6c6";
ctx.fillRect(0, 0, 1080, 1080);
ctx.font = '62px "SourceCodePro"';
ctx.fillStyle = '#FFF';
ctx.fillText(truncated, 17, 65);
var buf = canvas.toBuffer();
fs.writeFileSync("response.png", buf);
let buffer = fs.readFileSync("./response.png");
pngToJpeg()(buffer)
.then(output => fs.writeFile("./response.jpeg", output, function(err) {
if (err) console.log(err);
fs.exists("./response.jpeg", function(exists) {
if (exists) {
console.log(color);
if (color === "gray") createSubmission(originalText, '#b20000', ip, true, text + "\n---\n" + originalText, "red");
else createSubmission(originalText, '#404040', ip, true, text + "\n---\n" + originalText, "gray");
}
})
}));
fs.unlinkSync('./response.png');
}
function publish(caption, ip, isResponse, color) {
if (isResponse) {
var photos = [
{
type: 'photo',
size: [1000,1000],
data: './response.jpeg'
},
{
type: 'photo',
size: [1000,1000],
data: './submission.jpeg'
}
], disabledComments = false;
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
Client.Upload.album(session, photos)
.then(function(payload) {
console.log("Uploaded new response!");
Client.Media.configureAlbum(session, payload, caption, disabledComments)
})
})
}
else {
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
Client.Upload.photo(session, './submission.jpeg')
.then(function(upload) {
console.log("uploading...");
return Client.Media.configurePhoto(session, upload.params.uploadId, caption);
})
.then(function(medium) {
console.log("photo uploaded at " + medium.params.webLink);
})
});
}
log(caption, ip);
}
function postComment(id, comment) {
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
console.log("posted comment " + comment);
return Client.Comment.create(session, ''+id, comment);
})
}
function postReponse(url, comment, ip) {
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
return Client.Media.getByUrl(session, url)
.then(function(data) {
getWhichColor().then(function(color) {
createResponse(comment, data._params.caption, ip, color);
})
})
})
}
function delPost(id) {
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
return Client.Media.delete(session, ''+id);
})
}
function log(caption, ip, color) {
var now = new Date();
// set to eastern time
now.setTime(now.getTime()+now.getTimezoneOffset()*60*1000);
var estDate = new Date(now.getTime() + -240*60*1000);
let formattedDate = date.format(estDate, 'YYYY/MM/DD HH:mm:ss');
logs('Anonbot Logs').create({
"Time": formattedDate,
"Post": caption,
"IP Hash": ""+sha256(ip)
}, function(err, record) {
if (err) { console.error(err); return; }
console.log("new log created! " + record.getId());
})
}
function getClientIP(req){ // Anonbot logs IPs for safety & moderation
var ip = (req.headers['x-forwarded-for'] || req.connection.remoteAddress).split(',');
return ip[0];
}
function determineIfBanned(address) {
var banned = false;
return new Promise(function(resolve, reject) {
blacklist('Blacklist').select({
view: "Grid view"
}).eachPage(function page(records, fetchNextPage) {
records.forEach(function(record) {
if (record.get('IP Hash') === ""+sha256(address)) {
console.log("A banned user tried to access the site!");
banned = true;
}
})
fetchNextPage();
}, function done(err) {
if (err) reject(err);
resolve(banned);
})
})
}
function getWhichColor() {
return new Promise(function(resolve, reject) {
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
session.getAccount()
.then(function(account) {
if (account.params.mediaCount % 2 === 0) resolve("gray");
else resolve("red");
})
})
})
}
function getShortcode(url) {
var parts = url.split('/');
return parts[4];
}
app.use('/public', express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post("/submission", function(req, res) {
console.log("received submission " + req.body.anon);
if (req.body.anon === "") return res.redirect('/');
getWhichColor().then(function(color) {
if (color === "red") createSubmission(req.body.anon, '#b20000', getClientIP(req), false, "", "gray");
else createSubmission(req.body.anon, '#404040', getClientIP(req), false, "", "red");
})
//createSubmission(req.body.anon, '#404040', getClientIP(req), false);
return res.redirect('/submitted');
});
app.post("/postcomment", function(req, res) {
var commentString = req.body.comment.split('::');
var comment = commentString[0];
var commentType = commentString[1];
console.log("received comment " + comment + " type " + commentType + " on " + req.body.url);
var shortcode = getShortcode(req.body.url);
Client.Session.create(device, storage, 'anonbot.wl', process.env.ANON_PASSWORD)
.then(function(session) {
return Client.Media.getByUrl(session, ''+req.body.url)
.then(function(data) {
if (data._params.user.username === "anonbot.wl") {
if (commentType === "comm") postComment(urlSegmentToInstagramId(shortcode), comment);
else postReponse(req.body.url, comment, getClientIP(req));
return res.redirect('/commented');
} else {
console.log("comment not posted: post is not an Anonbot post");
return res.redirect('/');
}
})
.catch(function(err) {
if (err) {
console.log("commment not posted: url is invalid");
return res.redirect('/');
}
})
})
});
app.post("/delpost", function(req, res) {
console.log("received deletion request for " + req.body.link);
if (req.body.key === process.env.MOD_KEY) {
var shortcode = getShortcode(req.body.url);
delPost(urlSegmentToInstagramId(shortcode));
console.log("deletion successful");
return res.redirect(req.body.url);
} else {
console.log("request denied: incorrect mod key");
return res.redirect('/');
}
});
app.post("/modpost", function(req, res) {
console.log("received mod post request " + req.body.mod);
if (req.body.key === process.env.MOD_KEY) {
createSubmission(req.body.mod, '#e59d0b', false); // prev. #b20000
return res.redirect('/submitted');
} else {
console.log("request denied: incorrect mod key");
return res.redirect('/');
}
})
app.post("/banip", function(req, res) {
console.log("received ban request for IP " + req.body.ip);
if (req. body.key === process.env.MOD_KEY) {
blacklist('Blacklist').create({
"IP": req.body.ip,
"Reason": req.body.reason
}, function(err) {
if (err) { console.error(err); return; }
console.log("banned " + req.body.ip);
res.redirect('/banned');
})
} else {
console.log("request denied: incorrect mod key");
return res.redirect('/');
}
})
app.get("/", function(request, response) {
determineIfBanned(getClientIP(request)).then(function(banned) {
if (banned) return response.sendFile(__dirname + '/views/banned.html');
else return response.sendFile(__dirname + '/views/index.html');
})
});
app.get("/submitted", function(request, response) {
response.sendFile(__dirname + '/views/submitted.html');
});
app.get("/delete", function(request, response) {
response.sendFile(__dirname + '/views/delete.html');
});
app.get("/modpost", function(request, response) {
response.sendFile(__dirname + '/views/modpost.html');
});
app.get("/respond", function(request, response) {
determineIfBanned(getClientIP(request)).then(function(banned) {
if (banned) return response.sendFile(__dirname + '/views/banned.html');
else return response.sendFile(__dirname + '/views/respond.html');
})
});
app.get("/commented", function(request, response) {
response.sendFile(__dirname + '/views/commented.html');
});
app.get("/ban", function(request, response) {
response.sendFile(__dirname + '/views/ban.html');
})
app.get("/banned", function(request, response) {
response.sendFile(__dirname + '/views/banned.html');
});
http.listen(3000);

19
views/ban.html Normal file
View File

@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h2>Ban an IP</h2>
<form action="/banip" method="post" id="d" class="d">
<input id="ip" name="ip" type="text" placeholder="Enter the IP to ban" autofocus>
<input id="reason" name="reason" type="text" placeholder="Enter the reason for banning">
<input id="key" name="key" type="text" placeholder="Enter the mod key">
</form>
<button type="submit" form="d"><strong>Submit</strong></button>
</body>
</html>

18
views/banned.html Normal file
View File

@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../../../favicon.ico">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h3>You have been IPbanned from Anonbot!</h3>
<p>You've broken one or more <a href="https://github.com/MatthewStanciu/Anonbotv2/blob/master/README.md#Rules" target="_blank">Anonbot rules</a>.
Please DM @anonbot.wl on Instagram or text (765) 409-3260 if you believe this is an error and/or wish to be unbanned.</p>
</body>
</html>

17
views/commented.html Normal file
View File

@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../../../favicon.ico">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h4>Your comment has been posted!</h4>
<p>Check the post you commented on to see your new comment!</p>
</body>
</html>

18
views/delete.html Normal file
View File

@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h2>Delete a post</h2>
<form action="/delpost" method="post" id="d" class="d">
<input id="link" name="url" type="text" placeholder="Enter the link of the post" autofocus>
<input id="key" name="key" type="text" placeholder="Enter the mod key">
</form>
<button type="submit" form="d"><strong>Submit</strong></button>
</body>
</html>

37
views/index.html Normal file
View File

@ -0,0 +1,37 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h1>Anonbot WL</h1>
<h6>While you're here, considering joining the <a href="https://groupme.com/join_group/48094446/rZP53SPl">Community GroupME!</a></h6>
<form action="/submission" method="post" id="f" class="f">
<textarea id="m" name="anon" type="text" cols="36" rows ="7" placeholder="Say something..." autofocus></textarea>
</form>
<button type="submit" form="f" onclick="this.disabled=true;this.value='Submitting...'; this.form.submit();">
<strong>Submit</strong></button>
<a href="https://anonbotwl.glitch.me/respond"><p>Want to anonymously respond to a post instead?</p></a>
<br/>
<a href="https://github.com/MatthewStanciu/Anonbotv2" target="_blank"><p>View code on GitHub</p></a>
<div id="snackbar">You can only comment on Anonbot posts!</div>
<script>
if (document.referrer === "http://localhost:3000/comment" || document.referrer === "https://anonbotwl.glitch.me/comment") {
showSnackbar();
}
function showSnackbar() {
var x = document.getElementById("snackbar");
x.className = "show";
setTimeout(function(){ x.className = x.className.replace("show", ""); }, 3000);
}
</script>
</body>
</html>

22
views/modpost.html Normal file
View File

@ -0,0 +1,22 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h2>Post as a moderator</h2>
<form action="/modpost" method="post" id="d" class="f">
<input id="key" name="key" type="text" placeholder="Enter the mod key">
<br/>
<textarea id="mod" name="mod" type="text" cols="36" rows ="7" placeholder="Say something as a moderator..." autofocus></textarea>
</form>
<p class="lead">
<button type="submit" form="d"><strong>Submit</strong></button>
</p>
</body>
</html>

35
views/respond.html Normal file
View File

@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h2 class="cover-heading">Respond to a post</h2>
<form action="/postcomment" method="post" id="d" class="f">
<input id="key" name="url" type="text" placeholder="Enter the post url">
<br/>
<textarea id="comment" name="comment" type="text" cols="36" rows ="7" placeholder="Comment something..." autofocus></textarea>
</form>
<button type="submit" id="comm" form="d" onclick="postAs('comm');">
<strong>Submit as comment</strong></button>
<button type="submit" id="response" form="d" onclick="postAs('response');">
<strong>Submit as response</strong></button>
<a href="https://www.notion.so/NEW-Responses-065ccb4aa7d2429c9f1f2f9838943654" target="_blank"><p>(What's this?)</p></a>
<script>
function postAs(type) {
document.getElementById(type).disabled = true;
var text = document.getElementById('comment');
text.value = text.value + '::'+type;
document.getElementById('d').submit();
}
</script>
</body>
</html>

18
views/submitted.html Normal file
View File

@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1 maximum-scale=1.0, user-scalable=0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Anonbot WL</title>
<link href="../public/style.css" rel="stylesheet">
</head>
<body>
<h4>Your submission has been sent!</h4>
<p>Expect it to appear on the Instagram page @anonbot.wl in a few seconds</p>
</body>
</html>