mirror of
https://github.com/PretendoNetwork/juxtaposition-ui.git
synced 2026-08-24 02:05:26 -05:00
Auth flow overhaul
This commit is contained in:
@@ -1,172 +0,0 @@
|
||||
const config = require('../../config.json');
|
||||
const util = require('../util');
|
||||
const moment = require('moment/moment');
|
||||
const db = require('../database');
|
||||
|
||||
async function auth(request, response, next) {
|
||||
const discovery = await db.getEndPoint(config.server_environment);
|
||||
|
||||
if (!discovery || discovery.status !== 0) {
|
||||
let message = '';
|
||||
const status = discovery ? discovery.status : -1;
|
||||
switch (status) {
|
||||
case 3:
|
||||
message = 'Juxtaposition is currently under maintenance. Please try again later.';
|
||||
break;
|
||||
case 4:
|
||||
message = 'Juxtaposition is now closed. Thank you for your support!';
|
||||
break;
|
||||
default:
|
||||
message = 'Juxtaposition is currently unavailable. Please try again later.';
|
||||
break;
|
||||
}
|
||||
if (request.directory === 'web') {
|
||||
return response.render('web/login.ejs', {toast: message, cdnURL: config.CDN_domain,});
|
||||
} else {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get pid and fetch user data
|
||||
if (request.cookies.access_token && request.directory === 'web') {
|
||||
try {
|
||||
request.user = await util.data.getUserDataFromToken(request.cookies.access_token);
|
||||
} catch (e) {
|
||||
response.clearCookie('access_token');
|
||||
response.clearCookie('refresh_token');
|
||||
if (request.path === '/login') {
|
||||
request.lang = util.data.processLanguage();
|
||||
request.token = request.cookies.access_token;
|
||||
request.paramPackData = null;
|
||||
return next();
|
||||
} else {
|
||||
//return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
|
||||
return response.redirect('/login');
|
||||
}
|
||||
}
|
||||
request.pid = request.user ? request.user.pid : null;
|
||||
} else if (request.headers['x-nintendo-servicetoken'] && request.directory !== 'web') {
|
||||
request.pid = request.headers['x-nintendo-servicetoken'] ? await util.data.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
|
||||
request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
|
||||
} else {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Juxtaposition is currently unavailable. Please try again later.'
|
||||
});
|
||||
}
|
||||
|
||||
// Set headers
|
||||
request.paramPackData = request.headers['x-nintendo-parampack'] ? util.data.decodeParamPack(request.headers['x-nintendo-parampack']) : null;
|
||||
response.header('X-Nintendo-WhiteList', config.whitelist);
|
||||
|
||||
// Ban check
|
||||
if (request.user) {
|
||||
if (config.server_environment !== 'prod' && request.user.serverAccessLevel !== 'test' && request.user.serverAccessLevel !== 'dev') {
|
||||
response.status(500);
|
||||
return response.send('No access. Must be tester or dev');
|
||||
}
|
||||
// Set moderator status
|
||||
request.moderator = request.user.accessLevel == 2 || request.user.accessLevel == 3;
|
||||
const user = await db.getUserSettings(request.pid);
|
||||
if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
|
||||
user.account_status = 0;
|
||||
await user.save();
|
||||
}
|
||||
// This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
|
||||
// assuming we support more gradual bans on PNID's
|
||||
if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
|
||||
if (includes(request, 'juxt')) {
|
||||
let banMessage = '';
|
||||
switch (user.account_status) {
|
||||
case 2:
|
||||
banMessage = `${request.user.username} has been banned until: ${ moment(user.ban_lift_date) }. \n\nReason: ${user.ban_reason}. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
break;
|
||||
case 3:
|
||||
banMessage = `${request.user.username} has been banned forever. \n\nReason: ${user.ban_reason}. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
break;
|
||||
default:
|
||||
banMessage = `${request.user.username} has been banned. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
}
|
||||
return response.render('web/login.ejs', {toast: banMessage, cdnURL: config.CDN_domain,});
|
||||
} else {
|
||||
response.render(request.directory + '/partials/ban_notification.ejs', {
|
||||
user: user,
|
||||
moment: moment,
|
||||
cdnURL: config.CDN_domain,
|
||||
lang: request.lang,
|
||||
pid: request.pid
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Juxt Website
|
||||
if (request.directory === 'web') {
|
||||
request.token = request.cookies.access_token;
|
||||
|
||||
// Open access pages
|
||||
if (isStartOfPath(request.path, '/users/') ||
|
||||
(isStartOfPath(request.path, '/titles/') && request.path !== '/titles/show') ||
|
||||
(isStartOfPath(request.path, '/posts/') && !request.path.includes('/empathy'))) {
|
||||
if (!request.pid) {
|
||||
request.pid = 1000000000;
|
||||
}
|
||||
return next();
|
||||
}
|
||||
// Login endpoint
|
||||
if (request.path === '/login') {
|
||||
if (request.pid) {
|
||||
return response.redirect('/titles/show?src=login');
|
||||
}
|
||||
return next();
|
||||
}
|
||||
if (!request.pid) {
|
||||
return response.redirect('/login');
|
||||
}
|
||||
|
||||
return next();
|
||||
} else {
|
||||
// This section includes checks if a user is a developer and adds exceptions for these cases
|
||||
if (!request.pid) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Unable to parse service token. Are you using a Nintendo Network ID?'
|
||||
});
|
||||
}
|
||||
if (!request.user) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Unable to fetch user data. Please try again later.'
|
||||
});
|
||||
}
|
||||
if (request.user.accessLevel < 3 && !request.paramPackData) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Missing auth headers'
|
||||
});
|
||||
}
|
||||
const userAgent = request.headers['user-agent'];
|
||||
if (request.user.accessLevel < 3 && (request.cookies.access_token || (!userAgent.includes('Nintendo WiiU') && !userAgent.includes('Nintendo 3DS')))) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Invalid authentication method used.'
|
||||
});
|
||||
}
|
||||
|
||||
request.lang = util.data.processLanguage(request.paramPackData);
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
||||
function isStartOfPath(path, value) {
|
||||
return path.indexOf(value) === 0;
|
||||
}
|
||||
|
||||
function includes(request, domain) {
|
||||
return request.subdomains.findIndex(element => element.includes(domain)) !== -1;
|
||||
}
|
||||
|
||||
module.exports = auth;
|
||||
63
src/middleware/checkBan.js
Normal file
63
src/middleware/checkBan.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const config = require('../../config.json');
|
||||
const moment = require('moment/moment');
|
||||
const db = require('../database');
|
||||
|
||||
async function checkBan(request, response, next) {
|
||||
if (!request.user && !request.guest_access && request.path !== '/login') {
|
||||
return response.status(401).send('Ban Check Failed: No user or guest access');
|
||||
} else if (!request.user && (request.guest_access || request.path === '/login')) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (config.server_environment !== 'prod' && request.user.serverAccessLevel !== 'test' && request.user.serverAccessLevel !== 'dev') {
|
||||
response.status(500);
|
||||
if (request.directory === 'web') {
|
||||
return response.render('web/login.ejs', {toast: 'No access. Must be tester or dev', cdnURL: config.CDN_domain,});
|
||||
} else {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'No access. Must be tester or dev'
|
||||
});
|
||||
}
|
||||
}
|
||||
// Set moderator status
|
||||
request.moderator = request.user.accessLevel == 2 || request.user.accessLevel == 3;
|
||||
const user = await db.getUserSettings(request.pid);
|
||||
if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
|
||||
user.account_status = 0;
|
||||
await user.save();
|
||||
}
|
||||
// This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
|
||||
// assuming we support more gradual bans on PNID's
|
||||
if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
|
||||
if (request.directory === 'web') {
|
||||
let banMessage = '';
|
||||
switch (user.account_status) {
|
||||
case 2:
|
||||
banMessage = `${request.user.username} has been banned until: ${ moment(user.ban_lift_date) }. \n\nReason: ${user.ban_reason}. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
break;
|
||||
case 3:
|
||||
banMessage = `${request.user.username} has been banned forever. \n\nReason: ${user.ban_reason}. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
break;
|
||||
default:
|
||||
banMessage = `${request.user.username} has been banned. \n\nIf you have any questions contact the developers in the Discord server.`;
|
||||
}
|
||||
return response.render('web/login.ejs', {toast: banMessage, cdnURL: config.CDN_domain,});
|
||||
} else {
|
||||
return response.render(request.directory + '/partials/ban_notification.ejs', {
|
||||
user: user,
|
||||
moment: moment,
|
||||
cdnURL: config.CDN_domain,
|
||||
lang: request.lang,
|
||||
pid: request.pid,
|
||||
PNID: request.user.username,
|
||||
networkBan: request.user.accessLevel < 0
|
||||
});
|
||||
}
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
module.exports = checkBan;
|
||||
@@ -1,41 +1,18 @@
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
/* eslint-disable require-atomic-updates */
|
||||
const config = require('../../config.json');
|
||||
const util = require('../util');
|
||||
const moment = require('moment/moment');
|
||||
const db = require('../database');
|
||||
|
||||
async function auth(request, response, next) {
|
||||
// Get pid and fetch user data
|
||||
if (request.headers['x-nintendo-servicetoken']) {
|
||||
request.pid = request.headers['x-nintendo-servicetoken'] ? await util.data.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
|
||||
request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
|
||||
}
|
||||
request.pid = request.headers['x-nintendo-servicetoken'] ? await util.data.processServiceToken(request.headers['x-nintendo-servicetoken']) : null;
|
||||
request.user = request.pid ? await util.data.getUserDataFromPid(request.pid) : null;
|
||||
|
||||
// Set headers
|
||||
request.paramPackData = request.headers['x-nintendo-parampack'] ? util.data.decodeParamPack(request.headers['x-nintendo-parampack']) : null;
|
||||
response.header('X-Nintendo-WhiteList', config.whitelist);
|
||||
|
||||
// Ban check
|
||||
if (request.user) {
|
||||
// Set moderator status
|
||||
request.moderator = request.user.accessLevel >= 2;
|
||||
const user = await db.getUserSettings(request.pid);
|
||||
if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
|
||||
user.account_status = 0;
|
||||
await user.save();
|
||||
}
|
||||
// This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
|
||||
// assuming we support more gradual bans on PNID's
|
||||
if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
|
||||
response.render(request.directory + '/partials/ban_notification.ejs', {
|
||||
user: user,
|
||||
moment: moment,
|
||||
cdnURL: config.CDN_domain,
|
||||
lang: request.lang,
|
||||
pid: request.pid
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// This section includes checks if a user is a developer and adds exceptions for these cases
|
||||
if (!request.pid) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
@@ -43,18 +20,18 @@ async function auth(request, response, next) {
|
||||
error: 'Unable to parse service token. Are you using a Nintendo Network ID?'
|
||||
});
|
||||
}
|
||||
if (request.user.accessLevel < 3 && !request.paramPackData) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Missing auth headers'
|
||||
});
|
||||
}
|
||||
if (!request.user) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Unable to fetch user data. Please try again later.'
|
||||
});
|
||||
}
|
||||
if (request.user.accessLevel < 3 && !request.paramPackData) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: 'Missing auth headers'
|
||||
});
|
||||
}
|
||||
const userAgent = request.headers['user-agent'];
|
||||
if (request.user.accessLevel < 3 && (request.cookies.access_token || (!userAgent.includes('Nintendo WiiU') && !userAgent.includes('Nintendo 3DS')))) {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
@@ -64,7 +41,6 @@ async function auth(request, response, next) {
|
||||
}
|
||||
|
||||
request.lang = util.data.processLanguage(request.paramPackData);
|
||||
request.directory = request.subdomains[1];
|
||||
return next();
|
||||
}
|
||||
|
||||
|
||||
37
src/middleware/discovery.js
Normal file
37
src/middleware/discovery.js
Normal file
@@ -0,0 +1,37 @@
|
||||
const config = require('../../config.json');
|
||||
const db = require('../database');
|
||||
|
||||
async function checkDiscovery(request, response, next) {
|
||||
const discovery = await db.getEndPoint(config.server_environment);
|
||||
|
||||
if (!discovery || discovery.status !== 0) {
|
||||
let message = '';
|
||||
const status = discovery ? discovery.status : -1;
|
||||
switch (status) {
|
||||
case 3:
|
||||
message = 'Juxtaposition is currently under maintenance. Please try again later.';
|
||||
break;
|
||||
case 4:
|
||||
message = 'Juxtaposition is now closed. Thank you for your support!';
|
||||
break;
|
||||
default:
|
||||
message = 'Juxtaposition is currently unavailable. Please try again later.';
|
||||
break;
|
||||
}
|
||||
if (request.directory === 'web') {
|
||||
return response.render('web/login.ejs', {toast: message, cdnURL: config.CDN_domain,});
|
||||
} else {
|
||||
return response.render('portal/partials/ban_notification.ejs', {
|
||||
user: null,
|
||||
error: message
|
||||
});
|
||||
}
|
||||
} else {
|
||||
request.guest_access = discovery ? discovery.guest_access : false;
|
||||
request.new_users = discovery ? discovery.new_users : false;
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
module.exports = checkDiscovery;
|
||||
@@ -1,51 +1,37 @@
|
||||
const config = require('../../config.json');
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const util = require('../util');
|
||||
const moment = require('moment/moment');
|
||||
const db = require('../database');
|
||||
|
||||
async function auth(request, response, next) {
|
||||
async function webAuth(request, response, next) {
|
||||
// Get pid and fetch user data
|
||||
request.lang = util.data.processLanguage();
|
||||
request.paramPackData = null;
|
||||
request.directory = 'web';
|
||||
request.token = request.cookies.access_token;
|
||||
if (request.cookies.access_token) {
|
||||
try {
|
||||
request.user = await util.data.getUserDataFromToken(request.token);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (request.path === '/login') {
|
||||
return next();
|
||||
}
|
||||
return response.render('web/login.ejs', {toast: 'Unable to reach the account server. Try again later.', cdnURL: config.CDN_domain,});
|
||||
try {
|
||||
request.user = await util.data.getUserDataFromToken(request.cookies.access_token);
|
||||
request.pid = request.user.pid;
|
||||
} catch (e) {
|
||||
const domain = request.get('host').replace('juxt', '');
|
||||
response.clearCookie('access_token', {domain: domain, path: '/'});
|
||||
response.clearCookie('refresh_token', {domain: domain, path: '/'});
|
||||
response.clearCookie('token_type', {domain: domain, path: '/'});
|
||||
if (request.path === '/login') {
|
||||
request.lang = util.data.processLanguage();
|
||||
request.token = request.cookies.access_token;
|
||||
request.paramPackData = null;
|
||||
return next();
|
||||
}
|
||||
request.pid = request.user ? request.user.pid : null;
|
||||
}
|
||||
|
||||
// Ban check
|
||||
if (request.user) {
|
||||
// Set moderator status
|
||||
request.moderator = request.user.accessLevel >= 2;
|
||||
const user = await db.getUserSettings(request.pid);
|
||||
if (user && moment(user.ban_lift_date) <= moment() && user.account_status !== 3) {
|
||||
user.account_status = 0;
|
||||
await user.save();
|
||||
}
|
||||
// This includes ban checks for both Juxt specifically and the account server, ideally this should be squashed
|
||||
// assuming we support more gradual bans on PNID's
|
||||
if (user && (user.account_status < 0 || user.account_status > 1 || request.user.accessLevel < 0)) {
|
||||
return response.render('web/login.ejs', {toast: 'Your account has been suspended. For more information, log into https://pretendo.network/account', cdnURL: config.CDN_domain,});
|
||||
}
|
||||
}
|
||||
request.token = request.cookies.access_token;
|
||||
|
||||
// Open access pages
|
||||
if (isStartOfPath(request.path, '/users/') ||
|
||||
(isStartOfPath(request.path, '/titles/') && request.path !== '/titles/show') ||
|
||||
(isStartOfPath(request.path, '/posts/') && !request.path.includes('/empathy'))) {
|
||||
if (!request.pid) {
|
||||
(isStartOfPath(request.path, '/titles/') && request.path !== '/titles/show') ||
|
||||
(isStartOfPath(request.path, '/posts/') && !request.path.includes('/empathy'))) {
|
||||
if (!request.pid && request.guest_access) {
|
||||
request.pid = 1000000000;
|
||||
return next();
|
||||
} else if (!request.pid) {
|
||||
return response.redirect('/login');
|
||||
}
|
||||
return next();
|
||||
}
|
||||
// Login endpoint
|
||||
if (request.path === '/login') {
|
||||
@@ -54,8 +40,7 @@ async function auth(request, response, next) {
|
||||
}
|
||||
return next();
|
||||
}
|
||||
console.log(request.route);
|
||||
if (!request.user && request.path !== '/') {
|
||||
if (!request.pid) {
|
||||
return response.redirect('/login');
|
||||
}
|
||||
|
||||
@@ -66,4 +51,6 @@ function isStartOfPath(path, value) {
|
||||
return path.indexOf(value) === 0;
|
||||
}
|
||||
|
||||
module.exports = auth;
|
||||
|
||||
|
||||
module.exports = webAuth;
|
||||
|
||||
@@ -5,6 +5,10 @@ const endpointSchema = new Schema({
|
||||
server_access_level: String,
|
||||
topics: Boolean,
|
||||
guest_access: Boolean,
|
||||
new_users: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
host: String,
|
||||
api_host: String,
|
||||
portal_host: String,
|
||||
|
||||
@@ -3,7 +3,6 @@ const express = require('express');
|
||||
const morgan = require('morgan');
|
||||
const ejs = require('ejs');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const detectVersion = require('./middleware/detectVersion');
|
||||
const database = require('./database');
|
||||
const logger = require('./logger');
|
||||
const config = require('../config.json');
|
||||
@@ -32,8 +31,6 @@ app.use(express.urlencoded({
|
||||
}));
|
||||
|
||||
app.use(cookieParser());
|
||||
app.use(detectVersion);
|
||||
|
||||
|
||||
// import the servers into one
|
||||
app.use(juxt_web);
|
||||
|
||||
@@ -2,42 +2,67 @@ const express = require('express');
|
||||
const subdomain = require('express-subdomain');
|
||||
const logger = require('../../logger');
|
||||
const routes = require('./routes');
|
||||
const auth = require('../../middleware/auth');
|
||||
const webAuth = require('../../middleware/webAuth');
|
||||
const consoleAuth = require('../../middleware/consoleAuth');
|
||||
const checkBan = require('../../middleware/checkBan');
|
||||
const detectVersion = require('../../middleware/detectVersion');
|
||||
const checkDiscovery = require('../../middleware/discovery');
|
||||
|
||||
const router = express.Router();
|
||||
const console = express.Router();
|
||||
const consoleRouter = express.Router();
|
||||
const webRouter = express.Router();
|
||||
|
||||
// We want to check which domain we're running on before we fetch any files,
|
||||
// but we don't care about discovery until we're making it to the consoles themselves
|
||||
router.use(detectVersion);
|
||||
router.use('/', routes.WEB_FILES);
|
||||
router.use('/robots.txt', routes.ROBOTS);
|
||||
router.use('/web', routes.PWA);
|
||||
router.use(checkDiscovery);
|
||||
|
||||
// Create subdomains
|
||||
logger.info('[JUXT-WEB] Creating \'Web\' subdomain');
|
||||
router.use(subdomain('juxt', console));
|
||||
router.use(subdomain('juxt-beta', console));
|
||||
router.use(subdomain('juxt-dev', console));
|
||||
router.use(subdomain('juxt', webRouter));
|
||||
router.use(subdomain('juxt-beta', webRouter));
|
||||
router.use(subdomain('juxt-dev', webRouter));
|
||||
|
||||
logger.info('[JUXT-WEB] Creating \'Wii U\' subdomain');
|
||||
router.use(subdomain('portal.olv', console));
|
||||
router.use(subdomain('portal-beta.olv', console));
|
||||
router.use(subdomain('portal-dev.olv', console));
|
||||
router.use(subdomain('portal.olv', consoleRouter));
|
||||
router.use(subdomain('portal-beta.olv', consoleRouter));
|
||||
router.use(subdomain('portal-dev.olv', consoleRouter));
|
||||
|
||||
|
||||
logger.info('[JUXT-WEB] Creating \'3DS\' subdomain');
|
||||
router.use(subdomain('ctr.olv', console));
|
||||
router.use(subdomain('ctr-beta.olv', console));
|
||||
router.use(subdomain('ctr-dev.olv', console));
|
||||
router.use(subdomain('ctr.olv', consoleRouter));
|
||||
router.use(subdomain('ctr-beta.olv', consoleRouter));
|
||||
router.use(subdomain('ctr-dev.olv', consoleRouter));
|
||||
|
||||
// Setup routes
|
||||
console.use('/titles/show', auth, routes.PORTAL_SHOW);
|
||||
console.use('/titles', auth, routes.PORTAL_COMMUNITIES);
|
||||
console.use('/communities', auth, routes.PORTAL_COMMUNITIES);
|
||||
console.use('/topics', auth, routes.PORTAL_TOPICS);
|
||||
console.use('/users', auth, routes.PORTAL_USER);
|
||||
console.use('/posts', auth, routes.PORTAL_POST);
|
||||
console.use('/feed', auth, routes.PORTAL_FEED);
|
||||
console.use('/friend_messages', auth, routes.PORTAL_MESSAGES);
|
||||
console.use('/news', auth, routes.PORTAL_NEWS);
|
||||
console.use('/', routes.PORTAL_WEB);
|
||||
console.use('/login', auth, routes.WEB_LOGIN);
|
||||
console.use('/robots.txt', routes.ROBOTS);
|
||||
console.use('/web', routes.PWA);
|
||||
console.use('/admin', auth, routes.ADMIN);
|
||||
// Setup routes for console
|
||||
consoleRouter.use(consoleAuth);
|
||||
consoleRouter.use(checkBan);
|
||||
consoleRouter.use('/titles/show', routes.PORTAL_SHOW);
|
||||
consoleRouter.use('/titles', routes.PORTAL_COMMUNITIES);
|
||||
consoleRouter.use('/communities', routes.PORTAL_COMMUNITIES);
|
||||
consoleRouter.use('/topics', routes.PORTAL_TOPICS);
|
||||
consoleRouter.use('/users', routes.PORTAL_USER);
|
||||
consoleRouter.use('/posts', routes.PORTAL_POST);
|
||||
consoleRouter.use('/feed', routes.PORTAL_FEED);
|
||||
consoleRouter.use('/friend_messages', routes.PORTAL_MESSAGES);
|
||||
consoleRouter.use('/news', routes.PORTAL_NEWS);
|
||||
|
||||
// Setup routes for web
|
||||
webRouter.use(webAuth);
|
||||
webRouter.use(checkBan);
|
||||
webRouter.use('/titles/show', routes.PORTAL_SHOW);
|
||||
webRouter.use('/titles', routes.PORTAL_COMMUNITIES);
|
||||
webRouter.use('/communities', routes.PORTAL_COMMUNITIES);
|
||||
webRouter.use('/topics', routes.PORTAL_TOPICS);
|
||||
webRouter.use('/users', routes.PORTAL_USER);
|
||||
webRouter.use('/posts', routes.PORTAL_POST);
|
||||
webRouter.use('/feed', routes.PORTAL_FEED);
|
||||
webRouter.use('/friend_messages', routes.PORTAL_MESSAGES);
|
||||
webRouter.use('/news', routes.PORTAL_NEWS);
|
||||
webRouter.use('/login', routes.WEB_LOGIN);
|
||||
webRouter.use('/admin', routes.ADMIN);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -41,6 +41,15 @@ const yeahLimit = rateLimit({
|
||||
legacyHeaders: true,
|
||||
});
|
||||
|
||||
router.get('/:post_id/oembed.json', async function (req, res) {
|
||||
const post = await database.getPostByID(req.params.post_id.toString());
|
||||
const doc = {
|
||||
'author_name': post.screen_name,
|
||||
'author_url': 'https://juxt.pretendo.network/users/show?pid=' + post.pid,
|
||||
};
|
||||
res.send(doc);
|
||||
});
|
||||
|
||||
router.post('/empathy', yeahLimit, async function (req, res) {
|
||||
const post = await database.getPostByID(req.body.postID);
|
||||
if (!post) {
|
||||
|
||||
@@ -49,7 +49,7 @@ router.get('/first', async function (req, res) {
|
||||
});
|
||||
|
||||
router.post('/newUser', async function (req, res) {
|
||||
if (req.pid === null) {
|
||||
if (req.pid === null || !req.new_users || req.directory === 'web') {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,32 @@ router.get('/menu', async function (req, res) {
|
||||
});
|
||||
|
||||
router.get('/me', async function (req, res) {
|
||||
await userPage(req, res, req.pid);
|
||||
await userPage(req, res, req.pid);
|
||||
});
|
||||
|
||||
router.get('/notifications.json', async function (req, res) {
|
||||
const notifications = await database.getUnreadNotificationCount(req.pid);
|
||||
const messagesCount = await database.getUnreadConversationCount(req.pid);
|
||||
res.send(
|
||||
{
|
||||
message_count: messagesCount,
|
||||
notification_count: notifications,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
router.get('/downloadUserData.json', async function (req, res) {
|
||||
res.set('Content-Type', 'text/json');
|
||||
res.set('Content-Disposition', `attachment; filename="${req.pid}_user_data.json"`);
|
||||
const posts = await POST.find({ pid: req.pid });
|
||||
const userContent = await database.getUserSettings(req.pid);
|
||||
const userSettings = await database.getUserContent(req.pid);
|
||||
const doc = {
|
||||
'user_content': userContent,
|
||||
'user_settings': userSettings,
|
||||
'posts': posts,
|
||||
};
|
||||
res.send(doc);
|
||||
});
|
||||
|
||||
router.get('/me/settings', async function (req, res) {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const database = require('../../../../database');
|
||||
const { POST } = require('../../../../models/post');
|
||||
const path = require('path');
|
||||
const auth = require('../../../../middleware/auth');
|
||||
|
||||
router.get('/', function (req, res) {
|
||||
res.redirect('/titles/show');
|
||||
@@ -34,127 +31,4 @@ router.get('/favicon.ico', function (req, res) {
|
||||
res.sendFile('/images/favicon.ico', {root: path.join(__dirname, '../../../../webfiles/' + req.directory)});
|
||||
});
|
||||
|
||||
router.get('/icons/:image_id.png', async function (req, res) {
|
||||
res.set('Content-Type', 'image/png');
|
||||
const community = await database.getCommunityByID(req.params.image_id.toString());
|
||||
if (community !== null && community.browser_icon) {
|
||||
if (community.browser_icon.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(community.browser_icon.replace('data:image/png;base64,',''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(community.browser_icon, 'base64'));
|
||||
}
|
||||
} else {
|
||||
const user = await database.getUserSettings(req.params.image_id.toString());
|
||||
if (user !== null) {
|
||||
if (user.pfp_uri.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(user.pfp_uri.replace('data:image/png;base64,',''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(user.pfp_uri, 'base64'));
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/tip/:image_id.png', async function (req, res) {
|
||||
res.set('Content-Type', 'image/png');
|
||||
const community = await database.getCommunityByID(req.params.image_id.toString());
|
||||
if (community !== null) {
|
||||
if (community.browser_thumbnail.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(community.browser_thumbnail.replace('data:image/png;base64,',''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(community.browser_thumbnail, 'base64'));
|
||||
}
|
||||
} else {
|
||||
const user = await database.getUserByPID(req.params.image_id.toString());
|
||||
if (user !== null) {
|
||||
if (user.pfp_uri.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(user.pfp_uri.replace('data:image/png;base64,', ''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(user.pfp_uri, 'base64'));
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
router.get('/banner/:image_id.png', async function (req, res) {
|
||||
res.set('Content-Type', 'image/png');
|
||||
const community = await database.getCommunityByID(req.params.image_id.toString());
|
||||
if (community !== null && community.WiiU_browser_header !== undefined) {
|
||||
if (community.WiiU_browser_header.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(community.WiiU_browser_header.replace('data:image/png;base64,',''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(community.WiiU_browser_header, 'base64'));
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/screenshot/:image_id.png', async function (req, res) {
|
||||
res.set('Content-Type', 'image/png');
|
||||
const post = await database.getPostByID(req.params.image_id.toString());
|
||||
if (post !== null && post.screenshot !== '') {
|
||||
if (post.screenshot.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(post.screenshot.replace('data:image/png;base64,',''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(post.screenshot, 'base64'));
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/drawing/:image_id.png', async function (req, res) {
|
||||
res.set('Content-Type', 'image/png');
|
||||
const post = await database.getPostByID(req.params.image_id.toString());
|
||||
if (post !== null && post.painting_uri !== '') {
|
||||
if (post.painting_uri.indexOf('data:image/png;base64,') !== -1) {
|
||||
res.send(Buffer.from(post.painting_uri.replace('data:image/png;base64,',''), 'base64'));
|
||||
} else {
|
||||
res.send(Buffer.from(post.painting_uri, 'base64'));
|
||||
}
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/notifications.json', auth, async function (req, res) {
|
||||
const notifications = await database.getUnreadNotificationCount(req.pid);
|
||||
const messagesCount = await database.getUnreadConversationCount(req.pid);
|
||||
res.send(
|
||||
{
|
||||
message_count: messagesCount,
|
||||
notification_count: notifications,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
router.get('/:post_id/oembed.json', auth, async function (req, res) {
|
||||
const post = await database.getPostByID(req.params.post_id.toString());
|
||||
const doc = {
|
||||
'author_name': post.screen_name,
|
||||
'author_url': 'https://juxt.pretendo.network/users/show?pid=' + post.pid,
|
||||
};
|
||||
res.send(doc);
|
||||
});
|
||||
|
||||
router.get('/downloadUserData.json', auth, async function (req, res) {
|
||||
res.set('Content-Type', 'text/json');
|
||||
res.set('Content-Disposition', `attachment; filename="${req.pid}_user_data.json"`);
|
||||
const posts = await POST.find({ pid: req.pid });
|
||||
const userContent = await database.getUserSettings(req.pid);
|
||||
const userSettings = await database.getUserContent(req.pid);
|
||||
const doc = {
|
||||
'user_content': userContent,
|
||||
'user_settings': userSettings,
|
||||
'posts': posts,
|
||||
};
|
||||
res.send(doc);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
module.exports = {
|
||||
PORTAL_SHOW: require('./console/show'),
|
||||
PORTAL_WEB: require('./console/web'),
|
||||
PORTAL_COMMUNITIES: require('./console/communities'),
|
||||
PORTAL_USER: require('./console/userpage'),
|
||||
PORTAL_POST: require('./console/posts'),
|
||||
@@ -12,4 +11,5 @@ module.exports = {
|
||||
ROBOTS: require('./web/robots'),
|
||||
PWA: require('./web/pwa'),
|
||||
ADMIN: require('./admin/admin'),
|
||||
WEB_FILES: require('./console/web'),
|
||||
};
|
||||
@@ -38,7 +38,7 @@ router.post('/', async (req, res) => {
|
||||
|
||||
const pid = PNID.pid;
|
||||
|
||||
let discovery = await database.getEndPoint(PNID.serverAccessLevel);
|
||||
let discovery = await database.getEndPoint(config.server_environment);
|
||||
if (!discovery) {
|
||||
discovery = {
|
||||
status: 5
|
||||
|
||||
@@ -318,7 +318,7 @@ function testOffline() {
|
||||
}
|
||||
|
||||
function checkForUpdates() {
|
||||
GET('/notifications.json', function updates(data) {
|
||||
GET('/users/notifications.json', function updates(data) {
|
||||
var notificationObj = JSON.parse(data.responseText);
|
||||
var count =
|
||||
notificationObj.message_count + notificationObj.notification_count;
|
||||
|
||||
2
src/webfiles/ctr/js/juxt.min.js
vendored
2
src/webfiles/ctr/js/juxt.min.js
vendored
File diff suppressed because one or more lines are too long
2
src/webfiles/portal/css/juxt.min.css
vendored
2
src/webfiles/portal/css/juxt.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -348,7 +348,7 @@ function reportPost(post) {
|
||||
button.click();
|
||||
}
|
||||
function checkForUpdates() {
|
||||
GET('/notifications.json', function updates(data) {
|
||||
GET('/users/notifications.json', function updates(data) {
|
||||
var notificationObj = JSON.parse(data.responseText);
|
||||
var messages = document.getElementById("message-badge");
|
||||
var news = document.getElementById("news-badge");
|
||||
|
||||
2
src/webfiles/portal/js/juxt.min.js
vendored
2
src/webfiles/portal/js/juxt.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -10,14 +10,17 @@
|
||||
</script>
|
||||
<%} else {%>
|
||||
<script>
|
||||
<%if(user.account_status === 1) {%>
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980009, '<%=user.user_id%> has been limited from posting until: \n\n<%= moment(user.ban_lift_date) %>.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
location.href = '/communities'
|
||||
<% if(networkBan) {%>
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980010, '<%=PNID%> has been banned from the network.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
wiiuBrowser.closeApplication();
|
||||
<%} else if(user.account_status === 1) {%>
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980009, '<%=PNID%> has been limited from posting until: \n\n<%= moment(user.ban_lift_date) %>.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
location.href = '/communities';
|
||||
<%} else if(user.account_status === 2) {%>
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980010, '<%=user.user_id%> has been banned until: \n\n<%= moment(user.ban_lift_date) %>.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980010, '<%=PNID%> has been banned until: \n\n<%= moment(user.ban_lift_date) %>.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
wiiuBrowser.closeApplication();
|
||||
<%} else if(user.account_status === 3) {%>
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980011, '<%=user.user_id%> has been banned forever.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
wiiuErrorViewer.openByCodeAndMessage(5980011, '<%=PNID%> has been banned forever.\n\nReason: <%=user.ban_reason%>\n\nIf you have any questions contact the developers in the Discord server.');
|
||||
wiiuBrowser.closeApplication();
|
||||
<%}%>
|
||||
</script>
|
||||
|
||||
@@ -87,7 +87,8 @@
|
||||
</script>
|
||||
<div class="wrapper">
|
||||
<div class="account-form-wrapper">
|
||||
<a class="logotype" href="/">
|
||||
<h2>Account Creation is only available when you have a linked Wii U or 3DS.</h2>
|
||||
<!--<a class="logotype" href="/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="39.876">
|
||||
<g id="logo_type" data-name="logo type" transform="translate(-553 -467)">
|
||||
<g id="logo" transform="translate(553 467)">
|
||||
@@ -277,7 +278,7 @@
|
||||
<button class="about-button"
|
||||
onclick="window.location.replace('/titles')"><%= lang.setup.done_button %></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -279,7 +279,7 @@ function checkForUpdates() {
|
||||
}
|
||||
}
|
||||
};
|
||||
xhttp.open('GET', '/notifications.json', true);
|
||||
xhttp.open('GET', '/users/notifications.json', true);
|
||||
xhttp.send();
|
||||
}
|
||||
function POST(url, data, callback) {
|
||||
|
||||
2
src/webfiles/web/js/web.min.js
vendored
2
src/webfiles/web/js/web.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="/css/web.css">
|
||||
<script src="/js/pjax.min.js"></script>
|
||||
<script src="/js/web.js"></script>
|
||||
<script src="/js/web.min.js"></script>
|
||||
<link rel="manifest" href="https://juxt-web-cdn.b-cdn.net/web/manifest.json">
|
||||
<!-- Global site tag (gtag.js) - Google Analytics Testing-->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-195842548-1"></script>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<div class="community-page-post-box" id="post">
|
||||
<div id="wrapper">
|
||||
<%if(!post.removed) {%>
|
||||
<% if((
|
||||
<% if(pid !== 1000000000 && (
|
||||
(community.permissions.open && community.type < 2) || (community.admins && community.admins.indexOf(pid) !==-1) ||
|
||||
(pnid.accessLevel >= community.permissions.minimum_new_comment_access_level)
|
||||
) && userSettings.account_status === 0) {%>
|
||||
@@ -64,12 +64,6 @@
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
<% if((
|
||||
(community.permissions.open && community.type < 2) || (community.admins && community.admins.indexOf(pid) !==-1) ||
|
||||
(pnid.accessLevel >= community.permissions.minimum_new_comment_access_level)
|
||||
) && userSettings.account_status === 0) {%>
|
||||
<%- include('partials/new_post', { pid, lang, id: post.community_id, name: post.screen_name, url: `/posts/${post.id}/new`, show: 'post', message_pid: '' }); %>
|
||||
<%}%>
|
||||
<div id="report-post-page" class="add-post-page official-user-post" style="display: none">
|
||||
<form method="post" action="/posts/<%=post.id%>/report" id="report-form" name="report" data-is-own-title="1" data-is-identified="1">
|
||||
<input type="hidden" name="post_id" id="report-post-id" value="<%= post.id %>"/>
|
||||
@@ -104,8 +98,6 @@
|
||||
<input type="submit" class="post-button fixed-bottom-button" value="Submit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="painting-wrapper">
|
||||
<div id="painting-content">
|
||||
<div class="tools">
|
||||
<div>
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<%if(pnid.pid === pid) {%>
|
||||
<div>
|
||||
<h4>Download User Data</h4>
|
||||
<h4 id="user-page-download-tab"><a href="/downloadUserData.json">Download</a></h4>
|
||||
<h4 id="user-page-download-tab"><a href="/users/downloadUserData.json">Download</a></h4>
|
||||
</div>
|
||||
<%}%>
|
||||
<% if (moderator && pnid.pid !== pid) { %>
|
||||
|
||||
Reference in New Issue
Block a user