aboutsummaryrefslogtreecommitdiff
path: root/vnext/server
diff options
context:
space:
mode:
Diffstat (limited to 'vnext/server')
-rw-r--r--vnext/server/common/MessageUtils.js28
-rw-r--r--vnext/server/common/MessageUtils.spec.js32
-rw-r--r--vnext/server/durov.js54
-rw-r--r--vnext/server/hms.js44
-rw-r--r--vnext/server/http.js34
-rw-r--r--vnext/server/index.js64
-rw-r--r--vnext/server/middleware/event.js74
-rw-r--r--vnext/server/middleware/oembed.js20
-rw-r--r--vnext/server/middleware/renderer.js84
-rw-r--r--vnext/server/middleware/urlexpand.js8
-rw-r--r--vnext/server/sape.js34
-rw-r--r--vnext/server/sender.js138
-rw-r--r--vnext/server/webpack.config.js20
13 files changed, 315 insertions, 319 deletions
diff --git a/vnext/server/common/MessageUtils.js b/vnext/server/common/MessageUtils.js
index b7ed8ec0..bb3d791f 100644
--- a/vnext/server/common/MessageUtils.js
+++ b/vnext/server/common/MessageUtils.js
@@ -3,7 +3,7 @@
* @param {import('../../src/api').Message} msg message
*/
export function isPM(msg) {
- return !msg.mid;
+ return !msg.mid
}
/**
@@ -11,7 +11,7 @@
* @param {import('../../src/api').Message} msg message
*/
export function isReply(msg) {
- return msg.rid && msg.rid > 0;
+ return msg.rid && msg.rid > 0
}
/**
@@ -19,7 +19,7 @@ export function isReply(msg) {
* @param {import('../../src/api').Message} msg message
*/
export function isService(msg) {
- return msg.service && msg.service;
+ return msg.service && msg.service
}
/**
@@ -29,11 +29,11 @@ export function isService(msg) {
*/
export function formatTitle(msg) {
if (isReply(msg)) {
- return `Reply by ${msg.user.uname}:`;
+ return `Reply by ${msg.user.uname}:`
} else if (isPM(msg)) {
- return `Private message from ${msg.user.uname}:`;
+ return `Private message from ${msg.user.uname}:`
}
- return `${msg.user.uname}`;
+ return `${msg.user.uname}`
}
/**
@@ -43,11 +43,11 @@ export function formatTitle(msg) {
*/
export function formatQuote(msg) {
if (isReply(msg)) {
- return msg.replyQuote || '';
+ return msg.replyQuote || ''
} else if (isPM(msg)) {
- return '';
+ return ''
}
- return (msg.tags || []).map(t => `*${t}`).join(', ');
+ return (msg.tags || []).map(t => `*${t}`).join(', ')
}
/**
@@ -56,19 +56,19 @@ export function formatQuote(msg) {
* @returns {string} formatted body
*/
export function formatMessage(msg) {
- return msg.body || 'Sent an image';
+ return msg.body || 'Sent an image'
}
-const baseURL = 'https://juick.com';
+const baseURL = 'https://juick.com'
/**
* @param {import('../api').Message} msg message
*/
export function formatUrl(msg) {
if (isReply(msg)) {
- return `${baseURL}/m/${msg.mid}#${msg.rid}`;
+ return `${baseURL}/m/${msg.mid}#${msg.rid}`
} else if (isPM(msg)) {
- return `${baseURL}/pm/inbox`;
+ return `${baseURL}/pm/inbox`
}
- return `${baseURL}/m/${msg.mid}`;
+ return `${baseURL}/m/${msg.mid}`
}
diff --git a/vnext/server/common/MessageUtils.spec.js b/vnext/server/common/MessageUtils.spec.js
index 5e6f64c2..33336795 100644
--- a/vnext/server/common/MessageUtils.spec.js
+++ b/vnext/server/common/MessageUtils.spec.js
@@ -1,4 +1,4 @@
-import { formatTitle, formatMessage, formatQuote } from './MessageUtils';
+import { formatTitle, formatMessage, formatQuote } from './MessageUtils'
describe('Message formatting', () => {
it('Blog message', () => {
@@ -13,11 +13,11 @@ describe('Message formatting', () => {
'people'
],
'body': 'The message'
- };
- expect(formatTitle(msg)).toMatchSnapshot();
- expect(formatQuote(msg)).toMatchSnapshot();
- expect(formatMessage(msg)).toMatchSnapshot();
- });
+ }
+ expect(formatTitle(msg)).toMatchSnapshot()
+ expect(formatQuote(msg)).toMatchSnapshot()
+ expect(formatMessage(msg)).toMatchSnapshot()
+ })
it('Reply message', () => {
let msg = {
'mid': 1,
@@ -28,11 +28,11 @@ describe('Message formatting', () => {
},
'replyQuote': '> The message',
'body': 'The #reply #bla'
- };
- expect(formatTitle(msg)).toMatchSnapshot();
- expect(formatQuote(msg)).toMatchSnapshot();
- expect(formatMessage(msg)).toMatchSnapshot();
- });
+ }
+ expect(formatTitle(msg)).toMatchSnapshot()
+ expect(formatQuote(msg)).toMatchSnapshot()
+ expect(formatMessage(msg)).toMatchSnapshot()
+ })
it('PM', () => {
let msg = {
'user': {
@@ -40,8 +40,8 @@ describe('Message formatting', () => {
'uname': 'ugnich'
},
'body': 'The PM'
- };
- expect(formatTitle(msg)).toMatchSnapshot();
- expect(formatMessage(msg)).toMatchSnapshot();
- });
-});
+ }
+ expect(formatTitle(msg)).toMatchSnapshot()
+ expect(formatMessage(msg)).toMatchSnapshot()
+ })
+})
diff --git a/vnext/server/durov.js b/vnext/server/durov.js
index e9bbdb9a..6ab1831f 100644
--- a/vnext/server/durov.js
+++ b/vnext/server/durov.js
@@ -1,52 +1,52 @@
-import TelegramBot from 'node-telegram-bot-api';
-import debug from 'debug';
-var log = debug('durov');
-import config from 'config';
+import TelegramBot from 'node-telegram-bot-api'
+import debug from 'debug'
+var log = debug('durov')
+import config from 'config'
-import { formatQuote, formatTitle } from './common/MessageUtils';
-import { format } from '../src/utils/embed';
+import { formatQuote, formatTitle } from './common/MessageUtils'
+import { format } from '../src/utils/embed'
-let sender;
-let demouser;
-let bot_token;
-const durov_token_key = 'service.durov.token';
+let sender
+let demouser
+let bot_token
+const durov_token_key = 'service.durov.token'
if (config.has(durov_token_key)) {
- bot_token = config.get(durov_token_key);
- sender = new TelegramBot(bot_token);
- demouser = config.get('service.durov.demouser');
+ bot_token = config.get(durov_token_key)
+ sender = new TelegramBot(bot_token)
+ demouser = config.get('service.durov.demouser')
sender.setWebHook(`${config.get('service.baseURL')}/api/${bot_token}`).then(() => {
- log('Webhook is set');
- }).catch(console.log);
+ log('Webhook is set')
+ }).catch(console.log)
sender.on('message', msg => {
- log(`MESSAGE: ${JSON.stringify(msg)}`);
- });
+ log(`MESSAGE: ${JSON.stringify(msg)}`)
+ })
}
export const webhookPath = () => {
- return bot_token;
-};
+ return bot_token
+}
export const webhook = (req, res) => {
- sender.processUpdate(JSON.parse(req.body));
- res.sendStatus(200);
-};
+ sender.processUpdate(JSON.parse(req.body))
+ res.sendStatus(200)
+}
/**
* @param {import('../src/api').Message} msg
* @param {string[]} subscribers
*/
export const sendTelegramNotification = (msg, subscribers) => {
- log(`Telegram event: ${JSON.stringify(msg)}, ${subscribers} ${subscribers.length}`);
+ log(`Telegram event: ${JSON.stringify(msg)}, ${subscribers} ${subscribers.length}`)
if (!msg.service) {
if (subscribers && subscribers.includes(demouser)) {
- const message = `${formatTitle(msg)}\n${formatQuote(msg)}\n${format(msg.body, msg.uid, false)}`;
- log(message);
+ const message = `${formatTitle(msg)}\n${formatQuote(msg)}\n${format(msg.body, msg.uid, false)}`
+ log(message)
sender.sendMessage(demouser, message, {
parse_mode: 'HTML',
disable_web_page_preview: true
- }).then(log).catch(log);
+ }).then(log).catch(log)
}
}
-};
+}
diff --git a/vnext/server/hms.js b/vnext/server/hms.js
index 1f897cef..66bbad82 100644
--- a/vnext/server/hms.js
+++ b/vnext/server/hms.js
@@ -1,32 +1,32 @@
-import axios from 'axios';
-import config from 'config';
-import debug from 'debug';
-var log = debug('hms');
+import axios from 'axios'
+import config from 'config'
+import debug from 'debug'
+var log = debug('hms')
-const { client_id, client_secret } = config.has('service.hms') ? config.get('service.hms') : {};
+const { client_id, client_secret } = config.has('service.hms') ? config.get('service.hms') : {}
const refreshToken = async () => {
if (client_id) {
- const params = new URLSearchParams();
- params.append('grant_type', 'client_credentials');
- params.append('client_id', client_id);
- params.append('client_secret', client_secret);
- const res = await axios.post('https://oauth-login.cloud.huawei.com/oauth2/v3/token', params).catch(console.log);
+ const params = new URLSearchParams()
+ params.append('grant_type', 'client_credentials')
+ params.append('client_id', client_id)
+ params.append('client_secret', client_secret)
+ const res = await axios.post('https://oauth-login.cloud.huawei.com/oauth2/v3/token', params).catch(console.log)
try {
- log(`HMS response: ${JSON.stringify(res.data)}`);
- const access = res.data;
- log(`HMS access token: ${access.access_token}`);
- return access.access_token;
+ log(`HMS response: ${JSON.stringify(res.data)}`)
+ const access = res.data
+ log(`HMS access token: ${access.access_token}`)
+ return access.access_token
} catch (error) {
- log(error);
- return '';
+ log(error)
+ return ''
}
}
- return '';
-};
+ return ''
+}
export const send = async (msg, tokenList = []) => {
- const adminToken = await refreshToken();
+ const adminToken = await refreshToken()
if (adminToken) {
const response = await axios.post(`https://push-api.cloud.huawei.com/v1/${client_id}/messages:send`, {
headers: {
@@ -52,7 +52,7 @@ export const send = async (msg, tokenList = []) => {
'token': tokenList
}
}
- }).catch(log);
- log(`hcm: ${response.status}`);
+ }).catch(log)
+ log(`hcm: ${response.status}`)
}
-};
+}
diff --git a/vnext/server/http.js b/vnext/server/http.js
index 0ffa8bfe..a90afef3 100644
--- a/vnext/server/http.js
+++ b/vnext/server/http.js
@@ -1,7 +1,7 @@
-import axios from 'axios';
-import config from 'config';
-import debug from 'debug';
-var log = debug('http');
+import axios from 'axios'
+import config from 'config'
+import debug from 'debug'
+var log = debug('http')
/**
@@ -10,7 +10,6 @@ var log = debug('http');
*/
/**
* fetch message subscribers
- *
* @param {URLSearchParams} params - request params
* @returns {Promise<import('../client').SecureUser[]>} subscribers list
*/
@@ -18,26 +17,25 @@ export function subscribers(params) {
return new Promise((resolve, reject) => {
client.get(`/notifications?${params.toString()}`)
.then(response => {
- log(`CODE: ${response.status}`);
- resolve(response.data);
+ log(`CODE: ${response.status}`)
+ resolve(response.data)
})
- .catch(reason => { reject(reason); });
- });
+ .catch(reason => { reject(reason) })
+ })
}
/**
* delete invalid tokens
- *
* @param {import('../client').Token[]} tokens tokens
*/
export const deleteSubscribers = async (tokens) => {
- const response = await client.post('/notifications/delete', tokens);
- return response.data;
-};
+ const response = await client.post('/notifications/delete', tokens)
+ return response.data
+}
-const baseURL = config.get('service.baseURL') + '/api';
-const user = config.get('service.user') || process.env.JUICK_SERVICE_USER;
-const password = config.get('service.password') || process.env.JUICK_SERVICE_PASSWORD;
+const baseURL = config.get('service.baseURL') + '/api'
+const user = config.get('service.user') || process.env.JUICK_SERVICE_USER
+const password = config.get('service.password') || process.env.JUICK_SERVICE_PASSWORD
/** @type { import('axios').AxiosInstance } */
let client = axios.create({
@@ -45,5 +43,5 @@ let client = axios.create({
headers: user ? {
'Authorization': 'Basic ' + Buffer.from(user + ':' + password).toString('base64')
} : {}
-});
-log(`HTTP client initialized with base URL ${baseURL} ${ user? `and ${user} user` : ''}`);
+})
+log(`HTTP client initialized with base URL ${baseURL} ${ user? `and ${user} user` : ''}`)
diff --git a/vnext/server/index.js b/vnext/server/index.js
index 5bfa9070..8eb86981 100644
--- a/vnext/server/index.js
+++ b/vnext/server/index.js
@@ -1,53 +1,53 @@
-import express from 'express';
-import { raw } from 'body-parser';
-import cors from 'cors';
-import config from 'config';
-import debug from 'debug';
-const log = debug('http');
-
-import serverRenderer from './middleware/renderer';
-import event from './middleware/event';
-import oembed from './middleware/oembed';
-import urlExpand from './middleware/urlexpand';
-
-const PORT = 8081;
-import path from 'path';
-import { webhook, webhookPath } from './durov';
+import express from 'express'
+import { raw } from 'body-parser'
+import cors from 'cors'
+import config from 'config'
+import debug from 'debug'
+const log = debug('http')
+
+import serverRenderer from './middleware/renderer'
+import event from './middleware/event'
+import oembed from './middleware/oembed'
+import urlExpand from './middleware/urlexpand'
+
+const PORT = 8081
+import path from 'path'
+import { webhook, webhookPath } from './durov'
// initialize the application and create the routes
-const app = express();
-app.use(raw());
-app.use(cors());
-const router = express.Router();
+const app = express()
+app.use(raw())
+app.use(cors())
+const router = express.Router()
-router.post('/api/sender', event);
-router.get('/api/oembed', oembed);
-router.get('/api/urlexpand', urlExpand);
+router.post('/api/sender', event)
+router.get('/api/oembed', oembed)
+router.get('/api/urlexpand', urlExpand)
-const durov_webhook = webhookPath();
+const durov_webhook = webhookPath()
if (durov_webhook) {
- router.post(`/api/${durov_webhook}`, webhook);
+ router.post(`/api/${durov_webhook}`, webhook)
}
-router.use('^/$', serverRenderer);
+router.use('^/$', serverRenderer)
-const STATIC_ROOT = config.get('service.static_root') || path.resolve(__dirname, 'public');
+const STATIC_ROOT = config.get('service.static_root') || path.resolve(__dirname, 'public')
// other static resources should just be served as they are
router.use(express.static(
STATIC_ROOT,
{ maxAge: '30d' },
-));
+))
-router.use('*', serverRenderer);
+router.use('*', serverRenderer)
-app.use(router);
+app.use(router)
// start the app
app.listen(PORT, (error) => {
if (error) {
- return console.log('something bad happened', error);
+ return console.log('something bad happened', error)
}
- log('listening on ' + PORT + '...');
-});
+ log('listening on ' + PORT + '...')
+})
diff --git a/vnext/server/middleware/event.js b/vnext/server/middleware/event.js
index 5681eb59..59f36950 100644
--- a/vnext/server/middleware/event.js
+++ b/vnext/server/middleware/event.js
@@ -1,54 +1,54 @@
-import { simpleParser } from 'mailparser';
-import { isPM, isReply, isService } from '../common/MessageUtils';
-import { sendTelegramNotification } from '../durov';
-import { subscribers } from '../http';
-import { sendNotification, buildNotification } from '../sender';
-import debug from 'debug';
-import { send } from '../hms';
-var log = debug('event');
+import { simpleParser } from 'mailparser'
+import { isPM, isReply, isService } from '../common/MessageUtils'
+import { sendTelegramNotification } from '../durov'
+import { subscribers } from '../http'
+import { sendNotification, buildNotification } from '../sender'
+import debug from 'debug'
+import { send } from '../hms'
+var log = debug('event')
/** @type {number[]} */
-const allSandboxIds = [];
+const allSandboxIds = []
/**
* handle message event
* @param {import('../../client').Message} msg message
*/
function processMessageEvent(msg) {
- let params = {};
- params.uid = isPM(msg) ? msg.to.uid : msg.user.uid;
+ let params = {}
+ params.uid = isPM(msg) ? msg.to.uid : msg.user.uid
if (isReply(msg)) {
- params.mid = msg.mid;
- params.rid = msg.rid;
+ params.mid = msg.mid
+ params.rid = msg.rid
} else if (!isPM(msg) && !isService(msg)) {
- params.mid = msg.mid;
+ params.mid = msg.mid
}
subscribers(new URLSearchParams(JSON.parse(JSON.stringify(params)))).then(users => {
users.forEach(user => {
- log(`${user.uname}: ${user.unreadCount}`);
+ log(`${user.uname}: ${user.unreadCount}`)
let [sandboxTokens, productionTokens] = (user.tokens || [])
.filter(t => ['mpns', 'apns', 'fcm', 'web'].includes(t.type))
.map(t => t.type === 'web' ? JSON.parse(t.token) : t.token)
.reduce((result, element, i) => {
allSandboxIds.includes(user.uid)
? result[0].push(element)
- : result[1].push(element);
- return result;
- }, [[], []]);
- sendNotification(productionTokens, sandboxTokens, buildNotification(user, msg));
+ : result[1].push(element)
+ return result
+ }, [[], []])
+ sendNotification(productionTokens, sandboxTokens, buildNotification(user, msg))
let durovIds = (user.tokens || [])
.filter(t => ['durov'].includes(t.type))
- .map(t => t.token);
- sendTelegramNotification(msg, durovIds);
+ .map(t => t.token)
+ sendTelegramNotification(msg, durovIds)
let hmsIds = (user.tokens || [])
.filter(t => t.type === 'hcm')
- .map(t => t.token);
- log(`${user.uname}: ${hmsIds}`);
+ .map(t => t.token)
+ log(`${user.uname}: ${hmsIds}`)
send(msg, hmsIds).then(() => {
// TODO: handle results
- }).catch(log);
- });
- }).catch(log);
+ }).catch(log)
+ })
+ }).catch(log)
}
/**
@@ -58,30 +58,30 @@ function processMessageEvent(msg) {
export default function handleMessage(req, res) {
return simpleParser(req.body, {})
.then(parsed => {
- const new_version = parsed.headers.get('x-event-version') == '1.0';
- log(`New event: ${parsed.text}, new version: ${new_version}`);
+ const new_version = parsed.headers.get('x-event-version') == '1.0'
+ log(`New event: ${parsed.text}, new version: ${new_version}`)
if (new_version) {
/** @type {import('../../client').SystemEvent} */
- const event = JSON.parse(parsed.text || '');
+ const event = JSON.parse(parsed.text || '')
if (event.type === 'message' && event.message) {
if (event.message.service) {
// TODO: remove
- let msg = { ...event.message };
+ let msg = { ...event.message }
if (event.from) {
- msg.user = event.from;
+ msg.user = event.from
}
- processMessageEvent(msg);
+ processMessageEvent(msg)
} else {
- processMessageEvent(event.message);
+ processMessageEvent(event.message)
}
}
} else {
/** @type {import('../../client').Message} */
- const msg = JSON.parse(parsed.text || '');
- processMessageEvent(msg);
+ const msg = JSON.parse(parsed.text || '')
+ processMessageEvent(msg)
}
- res.end();
+ res.end()
})
- .catch(err => { log(err); res.status(400).send('Invalid request'); });
+ .catch(err => { log(err); res.status(400).send('Invalid request') })
}
diff --git a/vnext/server/middleware/oembed.js b/vnext/server/middleware/oembed.js
index 8b1ed61d..5d062228 100644
--- a/vnext/server/middleware/oembed.js
+++ b/vnext/server/middleware/oembed.js
@@ -1,19 +1,19 @@
-import { embeddedTweet } from '../../src/api';
+import { embeddedTweet } from '../../src/api'
/**
* Return content for embedding
* @type {import('express').RequestParamHandler}
*/
const oembed = async (req, res) => {
- let url = (req.query.url || '').toString();
+ let url = (req.query.url || '').toString()
return embeddedTweet(url).then(result => {
- res.send(result);
- res.end();
+ res.send(result)
+ res.end()
}).catch(err => {
- console.log(`HTTP ${err.response ? err.response.status : err.code}: ${url}`);
- res.sendStatus(err.response ? err.response.status : 500);
- res.end();
- });
-};
+ console.log(`HTTP ${err.response ? err.response.status : err.code}: ${url}`)
+ res.sendStatus(err.response ? err.response.status : 500)
+ res.end()
+ })
+}
-export default oembed;
+export default oembed
diff --git a/vnext/server/middleware/renderer.js b/vnext/server/middleware/renderer.js
index debba758..e7e0324e 100644
--- a/vnext/server/middleware/renderer.js
+++ b/vnext/server/middleware/renderer.js
@@ -1,54 +1,54 @@
-import * as ReactDOMServer from 'react-dom/server';
-import cookie from 'cookie';
-import config from 'config';
+import * as ReactDOMServer from 'react-dom/server'
+import cookie from 'cookie'
+import config from 'config'
// import our main App component
-import App from '../../src/App';
+import App from '../../src/App'
-import { getLinks } from '../sape';
-import { StaticRouter } from 'react-router-dom/server';
-import { VisitorProvider } from '../../src/ui/VisitorContext';
+import { getLinks } from '../sape'
+import { StaticRouter } from 'react-router-dom/server'
+import { VisitorProvider } from '../../src/ui/VisitorContext'
-import path from 'path';
-import fs from 'fs';
+import path from 'path'
+import fs from 'fs'
// convert a Unicode string to a string in which
// each 16-bit unit occupies only one byte
function toBinary(string) {
- const codeUnits = new Uint16Array(string.length);
+ const codeUnits = new Uint16Array(string.length)
for (let i = 0; i < codeUnits.length; i++) {
- codeUnits[i] = string.charCodeAt(i);
+ codeUnits[i] = string.charCodeAt(i)
}
- return Buffer.from(String.fromCharCode(...new Uint8Array(codeUnits.buffer))).toString('base64');
+ return Buffer.from(String.fromCharCode(...new Uint8Array(codeUnits.buffer))).toString('base64')
}
-const STATIC_ROOT = config.get('service.static_root') || path.resolve(__dirname, 'public');
+const STATIC_ROOT = config.get('service.static_root') || path.resolve(__dirname, 'public')
const serverRenderer = async (req, res) => {
// point to the html file created by CRA's build tool
- const filePath = path.resolve(STATIC_ROOT, 'index.html');
+ const filePath = path.resolve(STATIC_ROOT, 'index.html')
// links
- const cookies = cookie.parse(req.headers.cookie || '');
+ const cookies = cookie.parse(req.headers.cookie || '')
- const links = await getLinks(req.originalUrl, cookies['sape_cookie']);
+ const links = await getLinks(req.originalUrl, cookies['sape_cookie'])
fs.readFile(filePath, 'utf8', (err, htmlData) => {
if (err) {
- console.error('err', err);
- return res.status(404).end();
+ console.error('err', err)
+ return res.status(404).end()
}
- const routerContext = {};
+ const routerContext = {}
const props = {
footer: links.join(' ')
- };
+ }
- const marker = '<div id="app">';
- const data = htmlData.split(marker);
- const propsData = `<script>window.__PROPS__="${toBinary(JSON.stringify(props))}";</script>${marker}`;
- let didError = false;
+ const marker = '<div id="app">'
+ const data = htmlData.split(marker)
+ const propsData = `<script>window.__PROPS__="${toBinary(JSON.stringify(props))}";</script>${marker}`
+ let didError = false
const { pipe } = ReactDOMServer.renderToPipeableStream(
<VisitorProvider>
<StaticRouter location={req.baseUrl} context={routerContext}>
@@ -57,33 +57,33 @@ const serverRenderer = async (req, res) => {
</VisitorProvider>
, {
onShellReady() {
- res.statusCode = didError ? 500 : 200;
- res.setHeader('Content-type', 'text/html');
- res.write(data[0]);
- res.write(propsData);
- pipe(res, { end: false });
+ res.statusCode = didError ? 500 : 200
+ res.setHeader('Content-type', 'text/html')
+ res.write(data[0])
+ res.write(propsData)
+ pipe(res, { end: false })
},
onShellError() {
- didError = true;
- res.statusCode = 500;
- res.setHeader('Content-type', 'text/html');
+ didError = true
+ res.statusCode = 500
+ res.setHeader('Content-type', 'text/html')
res.send(
'<h1>Something went wrong :(</h1>'
- );
- res.end();
+ )
+ res.end()
},
onAllReady() {
if (!didError) {
- res.write(data[1]);
+ res.write(data[1])
}
- res.end();
+ res.end()
},
onError(err) {
- didError = true;
- console.log(err);
+ didError = true
+ console.log(err)
}
- });
- });
-};
+ })
+ })
+}
-export default serverRenderer;
+export default serverRenderer
diff --git a/vnext/server/middleware/urlexpand.js b/vnext/server/middleware/urlexpand.js
index f78d1cc0..a99f80a7 100644
--- a/vnext/server/middleware/urlexpand.js
+++ b/vnext/server/middleware/urlexpand.js
@@ -1,4 +1,4 @@
-import { expandShortenedLink } from '../../src/api';
+import { expandShortenedLink } from '../../src/api'
/**
* Expand URLs
@@ -6,8 +6,8 @@ import { expandShortenedLink } from '../../src/api';
* @param {import("next").NextApiResponse} res
*/
export default function urlExpand(req, res) {
- let url = (req.query.url || '').toString();
+ let url = (req.query.url || '').toString()
return expandShortenedLink(url).then(result => {
- res.json(result);
- });
+ res.json(result)
+ })
}
diff --git a/vnext/server/sape.js b/vnext/server/sape.js
index ad374f2b..cff9b48a 100644
--- a/vnext/server/sape.js
+++ b/vnext/server/sape.js
@@ -1,9 +1,9 @@
-import { parseStringPromise } from 'xml2js';
-import axios from 'axios';
-import { setupCache } from 'axios-cache-interceptor';
-import config from 'config';
+import { parseStringPromise } from 'xml2js'
+import axios from 'axios'
+import { setupCache } from 'axios-cache-interceptor'
+import config from 'config'
-const token = config.get('service.sape.token') || process.env.SAPE_TOKEN;
+const token = config.get('service.sape.token') || process.env.SAPE_TOKEN
/** @external Promise */
@@ -14,19 +14,19 @@ const token = config.get('service.sape.token') || process.env.SAPE_TOKEN;
*/
export const getLinks = async (uri, sapeCookie) => {
if (!token) {
- console.warn('Sape is not configured');
- return [];
+ console.warn('Sape is not configured')
+ return []
}
- const response = await sape.get(`http://dispencer-01.sape.ru/code.php?user=${token}&host=juick.com&charset=UTF-8&as_xml=true`);
- const data = await parseStringPromise(response.data);
- const showCode = token === sapeCookie;
- const requestURI = showCode ? '*' : uri;
+ const response = await sape.get(`http://dispencer-01.sape.ru/code.php?user=${token}&host=juick.com&charset=UTF-8&as_xml=true`)
+ const data = await parseStringPromise(response.data)
+ const showCode = token === sapeCookie
+ const requestURI = showCode ? '*' : uri
const page = data.sape.page.filter(page => {
- const uri = page['$']['uri'];
- return uri === requestURI;
- });
- return page.length > 0 ? showCode ? [page[0]._] : page[0].link : [];
-};
+ const uri = page['$']['uri']
+ return uri === requestURI
+ })
+ return page.length > 0 ? showCode ? [page[0]._] : page[0].link : []
+}
/** @type { import('axios-cache-interceptor').AxiosCacheInstance } */
let sape = setupCache(
@@ -36,4 +36,4 @@ let sape = setupCache(
}
}),
{ ttl: 3600 * 1000 }
-);
+)
diff --git a/vnext/server/sender.js b/vnext/server/sender.js
index 7c72cbf3..48b5fb78 100644
--- a/vnext/server/sender.js
+++ b/vnext/server/sender.js
@@ -1,11 +1,11 @@
-import PushNotifications from 'node-pushnotifications';
-import debug from 'debug';
-const log = debug('sender');
-import { deleteSubscribers } from './http';
-import { formatMessage, formatTitle, formatQuote } from './common/MessageUtils';
-import config from 'config';
+import PushNotifications from 'node-pushnotifications'
+import debug from 'debug'
+const log = debug('sender')
+import { deleteSubscribers } from './http'
+import { formatMessage, formatTitle, formatQuote } from './common/MessageUtils'
+import config from 'config'
-let cfg = /** @type { import('node-pushnotifications').Settings } */ (config);
+let cfg = /** @type { import('node-pushnotifications').Settings } */ (config)
const apnConfig = (production = true) => {
const apn = {
@@ -16,98 +16,96 @@ const apnConfig = (production = true) => {
teamId: cfg.apn?.token?.teamId || process.env.JUICK_APN_TEAM_ID
},
production: production
- };
- return apn;
-};
+ }
+ return apn
+}
const gcmConfig = {
...cfg.gcm,
id: cfg.gcm?.id || process.env.JUICK_GCM_ID
-};
+}
const push = new PushNotifications({
...config,
apn: apnConfig(true),
gcm: gcmConfig,
-});
+})
const sandbox = new PushNotifications({
...config,
apn: apnConfig(false),
gcm: gcmConfig
-});
+})
/** @type {string} */
-const application = config.get('service.application') || process.env.JUICK_APN_APPLICATION || '';
+const application = config.get('service.application') || process.env.JUICK_APN_APPLICATION || ''
/**
* send notification
- *
* @param {PushNotifications.RegistrationId[]} productionIds
* @param {PushNotifications.RegistrationId[]} sandboxIds
* @param {PushNotifications.Data} data
*/
export function sendNotification(productionIds, sandboxIds, data) {
[productionIds, sandboxIds].map((registrationIds, index) => {
- let sender = index == 0 ? push : sandbox;
+ let sender = index == 0 ? push : sandbox
if (registrationIds && registrationIds.length) {
sender.send(registrationIds, data)
.then((results) => {
results.forEach(result => {
- log(`${result.method}: ${result.success} success, ${result.failure} failure`);
+ log(`${result.method}: ${result.success} success, ${result.failure} failure`)
if (result.failure) {
- console.error(`${result.method} failure: ${JSON.stringify(result)}`);
- console.error(`Failed data: ${JSON.stringify(data)}`);
+ console.error(`${result.method} failure: ${JSON.stringify(result)}`)
+ console.error(`Failed data: ${JSON.stringify(data)}`)
}
- });
+ })
results.filter(r => r.method === 'apn')
.forEach(async r => {
- log(`Response message: ${JSON.stringify(r.message)}`);
+ log(`Response message: ${JSON.stringify(r.message)}`)
let badTokens = r.message.filter(m => m.errorMsg === 'BadDeviceToken').map(m => {
- return { 'type': 'apns', 'token': m.regId };
- });
+ return { 'type': 'apns', 'token': m.regId }
+ })
if (badTokens.length > 0) {
- await deleteSubscribers(badTokens);
- log(`${badTokens.length} APNS tokens deleted`);
+ await deleteSubscribers(badTokens)
+ log(`${badTokens.length} APNS tokens deleted`)
}
- });
+ })
results.filter(r => r.method === 'gcm')
.forEach(async r => {
let badTokens = r.message.filter(m => m.errorMsg === 'NotRegistered' || m.errorMsg === 'MismatchSenderId' || m.errorMsg === 'InvalidRegistration').map(m => {
- return { 'type': 'fcm', 'token': m.regId };
- });
+ return { 'type': 'fcm', 'token': m.regId }
+ })
if (badTokens.length > 0) {
- await deleteSubscribers(badTokens);
- log(`${badTokens.length} GCM tokens deleted`);
+ await deleteSubscribers(badTokens)
+ log(`${badTokens.length} GCM tokens deleted`)
}
- });
+ })
results.filter(r => r.method === 'mpns')
.forEach(async r => {
let badTokens = r.message.filter(m => m.errorMsg === 'The channel expired.').map(m => {
- return { 'type': 'mpns', 'token': m.regId };
- });
+ return { 'type': 'mpns', 'token': m.regId }
+ })
if (badTokens.length > 0) {
- await deleteSubscribers(badTokens);
- log(`${badTokens.length} MPNS tokens deleted`);
+ await deleteSubscribers(badTokens)
+ log(`${badTokens.length} MPNS tokens deleted`)
}
- });
+ })
results.filter(r => r.method === 'webPush')
.forEach(async r => {
let badTokens = r.message.filter(m => m.error && m.error['statusCode'] === 410).map(m => {
- return { 'type': 'web', 'token': JSON.stringify(m.regId) };
- });
+ return { 'type': 'web', 'token': JSON.stringify(m.regId) }
+ })
if (badTokens.length > 0) {
- await deleteSubscribers(badTokens);
- log(`${badTokens.length} WebPush tokens deleted`);
+ await deleteSubscribers(badTokens)
+ log(`${badTokens.length} WebPush tokens deleted`)
}
- });
+ })
})
- .catch((err) => { console.error(JSON.stringify(err)); });
+ .catch((err) => { console.error(JSON.stringify(err)) })
}
- });
+ })
}
/**
* builds notification object
- *
* @param {import('../client').SecureUser} user user
* @param {import('../client').Message} msg message
* @returns {PushNotifications.Data} notification template
@@ -119,33 +117,33 @@ export function buildNotification(user, msg) {
message: msg
},
timeToLive: 0
- };
- let { tokens, ...subscriber } = user;
+ }
+ let { tokens, ...subscriber } = user
if (msg.service) {
- template.contentAvailable = true;
- template.custom.service = true;
- template.custom.user = subscriber;
+ template.contentAvailable = true
+ template.custom.service = true
+ template.custom.user = subscriber
} else {
- const avatar = `https://i.juick.com/a/${msg.user.uid}.png`;
- const title = formatTitle(msg);
- const body = `${formatQuote(msg)}\n${formatMessage(msg)}`;
- template.custom.mid = msg.mid;
- template.custom.rid = msg.rid;
- template.custom.uname = msg.user.uname;
- template.custom.avatarUrl = avatar;
- template.image1src = avatar;
- template.text1 = title;
- template.text2 = body;
- template.title = title;
- template.body = body;
- template.badge = user.unreadCount || 0;
- template.mutableContent = 1;
- template.color = '#3c77aa';
- template.icon = 'ic_notification';
- template.clickAction = 'com.juick.NEW_EVENT_ACTION';
- const tag = msg.mid == 0 ? msg.user.uname : msg.mid;
- template.tag = `${tag}`;
- template.android_channel_id = 'default';
+ const avatar = `https://i.juick.com/a/${msg.user.uid}.png`
+ const title = formatTitle(msg)
+ const body = `${formatQuote(msg)}\n${formatMessage(msg)}`
+ template.custom.mid = msg.mid
+ template.custom.rid = msg.rid
+ template.custom.uname = msg.user.uname
+ template.custom.avatarUrl = avatar
+ template.image1src = avatar
+ template.text1 = title
+ template.text2 = body
+ template.title = title
+ template.body = body
+ template.badge = user.unreadCount || 0
+ template.mutableContent = 1
+ template.color = '#3c77aa'
+ template.icon = 'ic_notification'
+ template.clickAction = 'com.juick.NEW_EVENT_ACTION'
+ const tag = msg.mid == 0 ? msg.user.uname : msg.mid
+ template.tag = `${tag}`
+ template.android_channel_id = 'default'
}
- return template;
+ return template
}
diff --git a/vnext/server/webpack.config.js b/vnext/server/webpack.config.js
index 61f00d4d..77a86abd 100644
--- a/vnext/server/webpack.config.js
+++ b/vnext/server/webpack.config.js
@@ -1,11 +1,11 @@
/* eslint-disable @typescript-eslint/no-var-requires */
-const ESLintPlugin = require('eslint-webpack-plugin');
-const TerserPlugin = require('terser-webpack-plugin');
+const ESLintPlugin = require('eslint-webpack-plugin')
+const TerserPlugin = require('terser-webpack-plugin')
module.exports = () => {
- const node_env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development';
- const dev = node_env !== 'production';
+ const node_env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development'
+ const dev = node_env !== 'production'
const config = {
mode: node_env,
devtool: dev ? 'cheap-module-source-map' : false,
@@ -37,7 +37,7 @@ module.exports = () => {
symlinks: false,
extensions: ['.js']
}
- };
+ }
if (dev) {
config.plugins.push(
new ESLintPlugin({
@@ -46,7 +46,7 @@ module.exports = () => {
failOnWarning: false,
failOnError: true,
fix: false
- }));
+ }))
config.devServer = {
hot: true,
historyApiFallback: true,
@@ -55,7 +55,7 @@ module.exports = () => {
runtimeErrors: true
}
}
- };
+ }
}
config.optimization = {
minimize: !dev,
@@ -67,6 +67,6 @@ module.exports = () => {
terserOptions: {},
}),
]
- };
- return config;
-};
+ }
+ return config
+}