First Commit
commit
960e3d1f3c
@ -0,0 +1,193 @@
|
||||
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
|
||||
*.log
|
||||
|
||||
npm-debug.log*
|
||||
|
||||
yarn-debug.log*
|
||||
|
||||
yarn-error.log*
|
||||
|
||||
lerna-debug.log*
|
||||
|
||||
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
|
||||
*.pid
|
||||
|
||||
*.seed
|
||||
|
||||
*.pid.lock
|
||||
|
||||
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
|
||||
*.lcov
|
||||
|
||||
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
|
||||
jspm_packages/
|
||||
|
||||
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
|
||||
typings/
|
||||
|
||||
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
|
||||
|
||||
# dotenv environment variables file
|
||||
|
||||
.env
|
||||
|
||||
.env.test
|
||||
|
||||
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.cache
|
||||
|
||||
|
||||
|
||||
# next.js build output
|
||||
|
||||
.next
|
||||
|
||||
|
||||
|
||||
# nuxt.js build output
|
||||
|
||||
.nuxt
|
||||
|
||||
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
|
||||
|
||||
stickers/
|
||||
|
||||
$gifs/
|
||||
|
||||
searchgifs/
|
||||
|
||||
searchstickers/
|
||||
|
||||
exports/
|
||||
|
||||
dl/
|
||||
|
||||
dl2/
|
@ -0,0 +1,284 @@
|
||||
const config = require('../config')
|
||||
const every = require('every')
|
||||
|
||||
|
||||
// MongoDB
|
||||
const { mongoose, Models } = require('../database')
|
||||
|
||||
|
||||
// MCD API
|
||||
const UUID = require('uuid')
|
||||
const rqt = require('../node_modules/rqt')
|
||||
const MCDSession = new rqt.Session({
|
||||
host: config.mcdEndpointLegacy,
|
||||
headers: config.mcdHeadersLegacy,
|
||||
})
|
||||
|
||||
|
||||
const imapAuth = config.accountManager.imapAuth
|
||||
const MailListener = require('mail-listener2')
|
||||
const mailListener = new MailListener({
|
||||
...imapAuth,
|
||||
connTimeout: 10000,
|
||||
authTimeout: 10000,
|
||||
// debug: console.log,
|
||||
tlsOptions: { rejectUnauthorized: false },
|
||||
mailbox: config.accountManager.imapMailbox,
|
||||
searchFilter: ['UNSEEN'],
|
||||
markSeen: true,
|
||||
fetchUnreadOnStart: true,
|
||||
})
|
||||
|
||||
function generatePass(plength){
|
||||
var keylistalpha="abcdefghijklmnopqrstuvwxyz";
|
||||
var keylistint="123456789";
|
||||
var keylistspec="!@#_";
|
||||
var temp='';
|
||||
var len = plength/2;
|
||||
var len = len - 1;
|
||||
var lenspec = plength-len-len;
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
temp+=keylistalpha.charAt(Math.floor(Math.random()*keylistalpha.length));
|
||||
|
||||
for (i=0;i<lenspec;i++)
|
||||
temp+=keylistspec.charAt(Math.floor(Math.random()*keylistspec.length));
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
temp+=keylistint.charAt(Math.floor(Math.random()*keylistint.length));
|
||||
|
||||
temp=temp.split('').sort(function(){return 0.5-Math.random()}).join('');
|
||||
return temp;
|
||||
}
|
||||
|
||||
const makeAccount = async() => {
|
||||
const BOTID = mongoose.Types.ObjectId()
|
||||
const MAIL = BOTID + config.accountManager.mailSuffix
|
||||
const PW = generatePass(8) + 'aA.'
|
||||
const deviceId = UUID.v4()
|
||||
console.log('creating account', MAIL)
|
||||
const res = await MCDSession.aqt('/v2/customer/security/account?type=traditional', {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
"password": PW,
|
||||
"profile": {
|
||||
"base": {
|
||||
"address": [
|
||||
{ "activeInd": "Y", "allowPromotions": "Y", "details": [{ "addressLineDetails": { "zipCode": config.accountManager.mcdRegZipCode }, "addressLocale": "de-DE" }], "primaryInd": "Y", "addressType": "other" },
|
||||
],
|
||||
"email": [
|
||||
{ "activeInd": "Y", "emailAddress": MAIL, "primaryInd": "Y", "type": "personal" },
|
||||
],
|
||||
"firstName": config.accountManager.mcdRegFirstName,
|
||||
"lastName": config.accountManager.mcdRegLastName,
|
||||
"username": MAIL
|
||||
},
|
||||
"extended": {
|
||||
"devices": [
|
||||
{
|
||||
"brand": "privacymatters",
|
||||
"deviceId": deviceId,
|
||||
"deviceIdType": "AndroidId",
|
||||
"isActive": "Y",
|
||||
"language": "de-DE",
|
||||
"manufacturer": "privacymatters",
|
||||
"model": "privacymatters",
|
||||
"os": "android",
|
||||
"osVersion": "9",
|
||||
"personalName": "PersonalMobile",
|
||||
"sourceId": "MOT",
|
||||
"timezone": "Europe/Berlin",
|
||||
"token": "00000-0000:APA000000000000-00000000000000--0000000000000000000000000000000000000000000000000000000000000-000000000000000000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"policies": {
|
||||
"acceptancePolicies": [
|
||||
{ "acceptanceInd": "Y", "channelId": "M", "deviceId": deviceId, "isExpired": false, "name": "TermsOfUseAcceptanceType","sourceId": "MOT", "type": "1" }
|
||||
],
|
||||
"accessPolicy": [
|
||||
{ "acceptanceInd": "Y", "channelId": "M", "deviceId": deviceId, "isExpired": false, "name": "PrivacyPolicyAcceptanceType", "sourceId": "MOT", "type": "2" }
|
||||
]
|
||||
},
|
||||
"preferences": [
|
||||
{ "details": { "Email": "de-DE", "legacyId": "1", "MobileApp": "de-DE" }, "isActive": "Y", "preferenceDesc": "PreferredLanguage", "preferenceId": "1", "label": "PreferredLanguage", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "Email": "False", "legacyId": "2", "MobileApp": "False" }, "isActive": "N", "preferenceDesc": "DoesAcceptPromotion", "preferenceId": "2", "label": "DoesAcceptPromotion", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "Email": "ByEmail", "legacyId": "3", "MobileApp": "ByEmail" }, "isActive": "Y", "preferenceDesc": "PreferredNotification", "preferenceId": "3", "label": "PreferredNotification", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "Email": [], "legacyId": "18", "MobileApp": [] }, "isActive": "Y", "preferenceDesc": "PreferredOfferCategory", "preferenceId": "11", "label": "PreferredOfferCategory", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceFry", "preferenceId": "16", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "Email": "False", "legacyId": "6", "MobileApp": "True" }, "isActive": "Y", "preferenceDesc": "YourOffers", "preferenceId": "6", "label": "YourOffers", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "Email": "False", "legacyId": "7", "MobileApp": "True" }, "isActive": "Y", "preferenceDesc": "LimitedTimeOffers", "preferenceId": "7", "label": "LimitedTimeOffers", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceBreakfast", "preferenceId": "12", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceSandwich", "preferenceId": "13", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceHappymeal", "preferenceId": "17", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceDrink", "preferenceId": "15", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceSalad", "preferenceId": "19", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceChicken", "preferenceId": "14", "sourceId": "MOT", "type": "FoodPreference" },
|
||||
{ "details": { "Email": "False", "legacyId": "8", "MobileApp": "True" }, "isActive": "Y", "preferenceDesc": "PunchcardOffers", "preferenceId": "8", "label": "PunchcardOffers", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "Email": "False", "legacyId": "9", "MobileApp": "True" }, "isActive": "Y", "preferenceDesc": "EverydayOffers", "preferenceId": "9", "label": "EverydayOffers", "sourceId": "MOT", "type": "ecpLegacy" },
|
||||
{ "details": { "enabled": "Y" }, "isActive": "Y", "preferenceDesc": "FoodPreferenceWrap", "preferenceId": "21", "sourceId": "MOT", "type": "FoodPreference" }
|
||||
],
|
||||
"subscriptions": [
|
||||
{ "legacyId": "1", "legacyType": "optin", "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "CommunicationChannel", "subscriptionId": "1" },
|
||||
{ "legacyId": "2", "legacyType": "optin", "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "Surveys", "subscriptionId": "2" },
|
||||
{ "legacyId": "3", "legacyType": "optin", "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "ProgramChanges", "subscriptionId": "3" },
|
||||
{ "legacyId": "4", "legacyType": "optin", "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "Contests", "subscriptionId": "4" },
|
||||
{ "legacyId": "5", "legacyType": "optin", "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "OtherMarketingMessages", "subscriptionId": "5" },
|
||||
{ "legacyId": "2", "legacyType": "sub", "optInStatus": "Y", "sourceId": "MOT", "subscriptionDesc": "OfferProgram", "subscriptionId": "7" },
|
||||
{ "legacyId": "5", "legacyType": "pref", "optInStatus": "Y", "sourceId": "MOT", "subscriptionDesc": "MobileNotificationEnabled", "subscriptionId": "11" },
|
||||
{ "legacyId": "5", "legacyType": "pref", "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "EmailNotificationEnabled", "subscriptionId": "10" },
|
||||
{ "optInStatus": "Y", "sourceId": "MOT", "subscriptionDesc": "GeneralMarketing", "subscriptionId": "22" },
|
||||
{ "optInStatus": "N", "sourceId": "MOT", "subscriptionDesc": "PersonalMarketing", "subscriptionId": "23" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
//console.log(JSON.stringify(res.body, null, '\n'))
|
||||
await Models.Account.create({
|
||||
_id: BOTID,
|
||||
email: MAIL,
|
||||
deviceId: deviceId,
|
||||
password: PW,
|
||||
})
|
||||
return BOTID
|
||||
}
|
||||
const removeAccount = async(botId) => {
|
||||
let dbId = mongoose.Types.ObjectId(botId)
|
||||
console.log('removeAccount', dbId)
|
||||
let $user = await Models.Account.findById(dbId)
|
||||
const res = await MCDSession.jqt('/v2/customer/security/account', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ $user.token }`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
if (res.status == "ok") {
|
||||
await Models.Account.findByIdAndRemove(dbId)
|
||||
} else {
|
||||
console.log(res)
|
||||
return false
|
||||
}
|
||||
}
|
||||
const login = async (botId) => {
|
||||
let dbId = mongoose.Types.ObjectId(botId)
|
||||
let $user = await Models.Account.findById(dbId)
|
||||
console.log('logging in', $user._id)
|
||||
const res = await MCDSession.jqt('/v2/customer/security/authentication?type=traditional', {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
password: $user.password,
|
||||
type: "email",
|
||||
loginUsername: $user.email,
|
||||
}
|
||||
})
|
||||
if (res.status == "ok") {
|
||||
await Models.Account.findByIdAndUpdate(dbId, {
|
||||
token: res.details.token,
|
||||
lastLogin: new Date(),
|
||||
})
|
||||
return true
|
||||
} else
|
||||
console.error('logging in', $user._id, 'failed', res)
|
||||
return false
|
||||
}
|
||||
|
||||
async function handleMail(html, subject, toward, seqno) {
|
||||
try {
|
||||
let toMail = toward.replace('<', '').replace('>', '')
|
||||
if (subject == config.accountManager.mcdSubjectVerified) { // remove verified-mails
|
||||
mailListener.imap.seq.addFlags(seqno, '\\Seen', null)
|
||||
mailListener.imap.seq.addFlags(seqno, '\\Deleted', null)
|
||||
return
|
||||
}
|
||||
if (subject !== config.accountManager.mcdSubjectVerify) return console.error('not an register email')
|
||||
if (toMail.indexOf(config.accountManager.mailSuffix) == -1) return false
|
||||
let botId = toMail.substring(0, toMail.indexOf(config.accountManager.mailSuffix))
|
||||
console.log(botId)
|
||||
let dbId = mongoose.Types.ObjectId(botId)
|
||||
let activateAccountURL = html
|
||||
if (!activateAccountURL) return false
|
||||
if (activateAccountURL.indexOf(config.accountManager.mcdVerifyLink) == -1) return false
|
||||
// console.log(toMail, botId)
|
||||
if (await Models.Account.count({ _id: dbId }) !== 1) return console.error('not in db')
|
||||
let userEntryForMail = await Models.Account.findById(dbId)
|
||||
|
||||
// https://www.mcdonalds.com/de/de-de/gmaredirect.html?&ac=XXXXXXXXXX
|
||||
activateAccountURL = activateAccountURL.substring(activateAccountURL.indexOf(config.accountManager.mcdVerifyLink))
|
||||
activateAccountURL = activateAccountURL.substring(0, activateAccountURL.indexOf('"'))
|
||||
let verificationCode = activateAccountURL.substring(activateAccountURL.indexOf('ac=') + 'ac='.length)
|
||||
console.log(toMail, toMail == userEntryForMail.email, activateAccountURL, verificationCode)
|
||||
|
||||
let res = await MCDSession.jqt('/v2/customer/security/account/verification?type=email', {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
"username": userEntryForMail.email,
|
||||
"verificationCode": verificationCode
|
||||
}
|
||||
})
|
||||
// console.log(userEntryForMail , JSON.stringify(res, null,'\n'))
|
||||
console.log(res)
|
||||
if (res['status'] == "ok") {
|
||||
await Models.Account.findByIdAndUpdate(dbId, {
|
||||
active: true,
|
||||
link: activateAccountURL,
|
||||
})
|
||||
mailListener.imap.seq.addFlags(seqno, '\\Seen', null);
|
||||
mailListener.imap.seq.addFlags(seqno, '\\Deleted', null);
|
||||
} else {
|
||||
console.log(res)
|
||||
}
|
||||
} catch (ex) {
|
||||
console.error(ex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function Init() {
|
||||
// Schedule to fill up the Accounts
|
||||
every(5000)
|
||||
.on('data', async () => {
|
||||
let freeAccounts = await Models.Account.count({
|
||||
free: true,
|
||||
})
|
||||
if (freeAccounts < config.accountManager.freeAccountsReserve) {
|
||||
makeAccount()
|
||||
}
|
||||
|
||||
let oldAccounts = await Models.Account.find({
|
||||
active: true,
|
||||
free: false,
|
||||
lastLogin: { $lt: (new Date(new Date() - (1000 * 60 * 5))) }
|
||||
})
|
||||
for (let oldAccount of oldAccounts) {
|
||||
if (await login(oldAccount._id) === true) { // if login works
|
||||
await removeAccount(oldAccount._id)
|
||||
}
|
||||
}
|
||||
})
|
||||
// mail stuff
|
||||
mailListener.on('server:connected', () => {
|
||||
console.log("imapConnected")
|
||||
})
|
||||
mailListener.on('server:disconnected', () => {
|
||||
console.log("imapDisconnected")
|
||||
mailListener.stop()
|
||||
mailListener.start()
|
||||
})
|
||||
mailListener.on('error', (err) => {
|
||||
console.log(err)
|
||||
})
|
||||
mailListener.on('mail', async (mail, seqno, attributes) => {
|
||||
if (mail.headers.from.indexOf('mobile.mcdonalds.de') > -1) {
|
||||
// console.log("emailParsed", mail.headers.subject, mail.headers.to)
|
||||
if (mail.headers.to.indexOf('-') > -1) return // TODO: remove
|
||||
await handleMail(mail.html, mail.subject, mail.headers.to, seqno)
|
||||
}
|
||||
})
|
||||
mailListener.start()
|
||||
}
|
||||
|
||||
Init()
|
@ -0,0 +1,142 @@
|
||||
{
|
||||
"name": "accountmanager",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"addressparser": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
|
||||
"integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y="
|
||||
},
|
||||
"async": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
|
||||
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"encoding": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||
"requires": {
|
||||
"iconv-lite": "~0.4.13"
|
||||
}
|
||||
},
|
||||
"every": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/every/-/every-0.0.1.tgz",
|
||||
"integrity": "sha1-lUFd64XgRaVMgndYaSgSXVXpwY4="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"imap": {
|
||||
"version": "0.8.19",
|
||||
"resolved": "https://registry.npmjs.org/imap/-/imap-0.8.19.tgz",
|
||||
"integrity": "sha1-NniHOTSrCc6mukh0HyhNoq9Z2NU=",
|
||||
"requires": {
|
||||
"readable-stream": "1.1.x",
|
||||
"utf7": ">=1.0.2"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"mail-listener2": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mail-listener2/-/mail-listener2-0.3.1.tgz",
|
||||
"integrity": "sha1-GBRJfZYy/Y6vTjywg6qQEpZh+ok=",
|
||||
"requires": {
|
||||
"async": "^0.9.0",
|
||||
"imap": "~0.8.14",
|
||||
"mailparser": "~0.4.6"
|
||||
}
|
||||
},
|
||||
"mailparser": {
|
||||
"version": "0.4.9",
|
||||
"resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.4.9.tgz",
|
||||
"integrity": "sha1-HQpI1vqqovCawTmO0CPY746xnis=",
|
||||
"requires": {
|
||||
"encoding": ">=0.1.4",
|
||||
"mime": "*",
|
||||
"mimelib": ">=0.2.17",
|
||||
"uue": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
||||
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
|
||||
},
|
||||
"mimelib": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz",
|
||||
"integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=",
|
||||
"requires": {
|
||||
"addressparser": "~1.0.1",
|
||||
"encoding": "~0.1.12"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
|
||||
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"utf7": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utf7/-/utf7-1.0.2.tgz",
|
||||
"integrity": "sha1-lV9JCq5lO6IguUVqCod2wZk2CZE=",
|
||||
"requires": {
|
||||
"semver": "~5.3.0"
|
||||
}
|
||||
},
|
||||
"uue": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/uue/-/uue-1.0.0.tgz",
|
||||
"integrity": "sha1-ITuUSLmLmLnQPK9gGiI1ib2IZDA="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
||||
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "accountmanager",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"every": "0.0.1",
|
||||
"mail-listener2": "^0.3.1",
|
||||
"uuid": "^3.3.3"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
const config = require('./config')
|
||||
const mongoose = require('mongoose')
|
||||
mongoose.connect(config.mongodbURI, {
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
useFindAndModify: true,
|
||||
dbName: config.mongodbName
|
||||
})
|
||||
mongoose.Promise = global.Promise
|
||||
const Models = require('./models')
|
||||
module.exports = { mongoose, Models }
|
@ -0,0 +1,14 @@
|
||||
version: '3'
|
||||
services:
|
||||
redis:
|
||||
image: redis
|
||||
container_name: doofnalds_cache
|
||||
hostname: redis
|
||||
ports:
|
||||
- "127.0.0.1:6379:6379"
|
||||
mongo:
|
||||
image: "mongo:latest"
|
||||
container_name: doofnalds_db
|
||||
hostname: mongodb
|
||||
ports:
|
||||
- "127.0.0.1:27017:27017"
|
@ -0,0 +1,22 @@
|
||||
const mongoose = require('mongoose')
|
||||
const schema = new mongoose.Schema({
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
free: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
created: {
|
||||
type: Date,
|
||||
default: () => new Date(),
|
||||
},
|
||||
email: String,
|
||||
deviceId: String,
|
||||
password: String,
|
||||
link: String,
|
||||
token: String,
|
||||
lastLogin: Date,
|
||||
})
|
||||
module.exports = mongoose.model('Account', schema)
|
@ -0,0 +1,10 @@
|
||||
const mongoose = require('mongoose')
|
||||
const schema = new mongoose.Schema({
|
||||
place_id: String,
|
||||
query: String,
|
||||
name: String,
|
||||
latitude: Number,
|
||||
longitude: Number,
|
||||
lastRefresh: Date,
|
||||
})
|
||||
module.exports = mongoose.model('GoogleCacheResult', schema)
|
@ -0,0 +1,33 @@
|
||||
const mongoose = require('mongoose')
|
||||
const schema = new mongoose.Schema({
|
||||
userId: {
|
||||
type: Number,
|
||||
unique: true,
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: !!!false,
|
||||
},
|
||||
accounts: {
|
||||
type: Array({
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: 'Account'
|
||||
}),
|
||||
},
|
||||
store: {
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: 'Store'
|
||||
},
|
||||
offers: Object,
|
||||
|
||||
|
||||
created: {
|
||||
type: Date,
|
||||
default: () => new Date(),
|
||||
},
|
||||
lastInteraction: {
|
||||
type: Date,
|
||||
default: () => new Date(),
|
||||
},
|
||||
})
|
||||
module.exports = mongoose.model('Session', schema)
|
@ -0,0 +1,25 @@
|
||||
const mongoose = require('mongoose')
|
||||
const schema = new mongoose.Schema({
|
||||
id: Number,
|
||||
externalId: Number,
|
||||
|
||||
storeId: String,
|
||||
storeECPId: String,
|
||||
|
||||
latitude: Number,
|
||||
longitude: Number,
|
||||
city: String,
|
||||
postalCode: String,
|
||||
address: String,
|
||||
street: String,
|
||||
phone: String,
|
||||
seoURL: {
|
||||
type: String,
|
||||
unique: true,
|
||||
},
|
||||
name1: String,
|
||||
name2: String,
|
||||
|
||||
lastRefresh: Date,
|
||||
})
|
||||
module.exports = mongoose.model('Store', schema)
|
@ -0,0 +1,13 @@
|
||||
const mongoose = require('mongoose')
|
||||
const schema = new mongoose.Schema({
|
||||
place_id: String,
|
||||
query: String,
|
||||
latitude: Number,
|
||||
longitude: Number,
|
||||
store: {
|
||||
type: mongoose.Types.ObjectId,
|
||||
ref: 'Store'
|
||||
},
|
||||
lastRefresh: Date,
|
||||
})
|
||||
module.exports = mongoose.model('StoreFinderCorrelation', schema)
|
@ -0,0 +1,14 @@
|
||||
const mongoose = require('mongoose')
|
||||
const schema = new mongoose.Schema({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
ios: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
screenWidth: Number,
|
||||
screenHeight: Number,
|
||||
})
|
||||
module.exports = mongoose.model('User', schema)
|
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
Account: require('./Account'),
|
||||
Store: require('./Store'),
|
||||
Session: require('./Session'),
|
||||
StoreFinderCorrelation: require('./StoreFinderCorrelation'),
|
||||
GoogleCacheResult: require('./GoogleCacheResult'),
|
||||
User: require('./User'),
|
||||
}
|
@ -0,0 +1,623 @@
|
||||
{
|
||||
"name": "doofnalds-bot",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"amqp-connection-manager": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-3.0.0.tgz",
|
||||
"integrity": "sha512-a5MsUDsG+CqMjwk/WNFSTE0H4pAaWJXw7L24QFa3MeaB+KA05PXoBsppYlIzaIqc1XLWZwjO9J42AFHNrDsVFQ==",
|
||||
"requires": {
|
||||
"promise-breaker": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"amqplib": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.5.tgz",
|
||||
"integrity": "sha512-sWx1hbfHbyKMw6bXOK2k6+lHL8TESWxjAx5hG8fBtT7wcxoXNIsFxZMnFyBjxt3yL14vn7WqBDe5U6BGOadtLg==",
|
||||
"requires": {
|
||||
"bitsyntax": "~0.1.0",
|
||||
"bluebird": "^3.5.2",
|
||||
"buffer-more-ints": "~1.0.0",
|
||||
"readable-stream": "1.x >=1.1.9",
|
||||
"safe-buffer": "~5.1.2",
|
||||
"url-parse": "~1.4.3"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"bitsyntax": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz",
|
||||
"integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==",
|
||||
"requires": {
|
||||
"buffer-more-ints": "~1.0.0",
|
||||
"debug": "~2.6.9",
|
||||
"safe-buffer": "~5.1.2"
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz",
|
||||
"integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg=="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz",
|
||||
"integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg=="
|
||||
},
|
||||
"buffer-more-ints": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz",
|
||||
"integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg=="
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "~1.1.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.0",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
|
||||
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"kareem": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
|
||||
"integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"memory-pager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||
"optional": true
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.3.3.tgz",
|
||||
"integrity": "sha512-MdRnoOjstmnrKJsK8PY0PjP6fyF/SBS4R8coxmhsfEU7tQ46/J6j+aSHF2n4c2/H8B+Hc/Klbfp8vggZfI0mmA==",
|
||||
"requires": {
|
||||
"bson": "^1.1.1",
|
||||
"require_optional": "^1.0.1",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"saslprep": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"mongoose": {
|
||||
"version": "5.7.7",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.7.7.tgz",
|
||||
"integrity": "sha512-FU59waB4LKBa9KOnqBUcCcMIVRc09TFo1F8nMxrzSiIWATaJpjxxSSH5FBVUDxQfNdJLfg9uFHxaTxhhwjsZOQ==",
|
||||
"requires": {
|
||||
"bson": "~1.1.1",
|
||||
"kareem": "2.3.1",
|
||||
"mongodb": "3.3.3",
|
||||
"mongoose-legacy-pluralize": "1.0.2",
|
||||
"mpath": "0.6.0",
|
||||
"mquery": "3.2.2",
|
||||
"ms": "2.1.2",
|
||||
"regexp-clone": "1.0.0",
|
||||
"safe-buffer": "5.1.2",
|
||||
"sift": "7.0.1",
|
||||
"sliced": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"mongoose-legacy-pluralize": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
|
||||
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
|
||||
},
|
||||
"mpath": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.6.0.tgz",
|
||||
"integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw=="
|
||||
},
|
||||
"mquery": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
|
||||
"integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
|
||||
"requires": {
|
||||
"bluebird": "3.5.1",
|
||||
"debug": "3.1.0",
|
||||
"regexp-clone": "^1.0.0",
|
||||
"safe-buffer": "5.1.2",
|
||||
"sliced": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bluebird": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
||||
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"promise-breaker": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-5.0.0.tgz",
|
||||
"integrity": "sha512-mgsWQuG4kJ1dtO6e/QlNDLFtMkMzzecsC69aI5hlLEjGHFNpHrvGhFi4LiK5jg2SMQj74/diH+wZliL9LpGsyA=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
|
||||
"integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.0"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"querystring": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
||||
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
|
||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"regexp-clone": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
|
||||
"integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
|
||||
},
|
||||
"require_optional": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
|
||||
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
|
||||
"requires": {
|
||||
"resolve-from": "^2.0.0",
|
||||
"semver": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
|
||||
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
|
||||
},
|
||||
"rqt": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rqt/-/rqt-4.0.0.tgz",
|
||||
"integrity": "sha512-DUm6ZAt6ESeY46aFWhQwBvsOpXABRL5TTkpN/3KJjog7uk2ncYuU4UZ8FQV6qfWybihkMFCdoESNSxYQ5rSZiQ=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"saslprep": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
|
||||
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"destroy": "~1.0.4",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"sift": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
|
||||
"integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
|
||||
},
|
||||
"sliced": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
|
||||
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
|
||||
},
|
||||
"sparse-bitfield": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
|
||||
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
|
||||
"requires": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "doofnalds-bot",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "config.js",
|
||||
"dependencies": {
|
||||
"amqp-connection-manager": "^3.0.0",
|
||||
"amqplib": "^0.5.5",
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
"mongoose": "^5.7.7",
|
||||
"querystring": "^0.2.0",
|
||||
"rqt": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
@ -0,0 +1,119 @@
|
||||
const config = require('../config')
|
||||
|
||||
const express = require('../node_modules/express')
|
||||
const bodyParser = require('../node_modules/body-parser')
|
||||
const fs = require('fs')
|
||||
const Jimp = require('jimp')
|
||||
const sha1 = require('sha1')
|
||||
const microService = express()
|
||||
microService.use(bodyParser.json(true))
|
||||
|
||||
let AndroidAppImg
|
||||
Jimp.read('./app.png').then((img) => AndroidAppImg = img)
|
||||
let IOSAppImg
|
||||
Jimp.read('./app-ios.png').then((img) => IOSAppImg = img)
|
||||
let OverviewImg
|
||||
Jimp.read('./overview.png').then((img) => OverviewImg = img)
|
||||
microService
|
||||
/**
|
||||
* Putting the QR Code into a Screenshot
|
||||
*/
|
||||
.post('/qrcode', async (req, res) => {
|
||||
const returnImage = !!req.body.ios
|
||||
? IOSAppImg.clone()
|
||||
: AndroidAppImg.clone();
|
||||
|
||||
const qrCodeImage = await Jimp.read(Buffer.from(req.body.QrCode, 'base64'))
|
||||
await qrCodeImage.crop(37, 37, 165, 165)
|
||||
if (!!req.body.ios) {
|
||||
/*
|
||||
198, 635
|
||||
397, 835
|
||||
*/
|
||||
await qrCodeImage.resize(200, 200, Jimp.RESIZE_NEAREST_NEIGHBOR)
|
||||
await returnImage.composite(qrCodeImage, 198, 635)
|
||||
const font = await Jimp.loadFont(Jimp.FONT_SANS_64_BLACK)
|
||||
await returnImage.print(font, 0, 868,
|
||||
{
|
||||
text: req.body.RandomCode,
|
||||
alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER,
|
||||
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
|
||||
},
|
||||
591,
|
||||
915 - 868
|
||||
);
|
||||
} else {
|
||||
await qrCodeImage.resize(421, 421, Jimp.RESIZE_NEAREST_NEIGHBOR)
|
||||
await returnImage.composite(qrCodeImage, 329, 780)
|
||||
const font = await Jimp.loadFont(Jimp.FONT_SANS_128_BLACK)
|
||||
await returnImage.print(font, 0, 1212,
|
||||
{
|
||||
text: req.body.RandomCode,
|
||||
alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER,
|
||||
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
|
||||
},
|
||||
1080,
|
||||
146
|
||||
);
|
||||
}
|
||||
res.set('Content-Type', 'image/png')
|
||||
return res.send(await returnImage.getBufferAsync('image/png'))
|
||||
})
|
||||
/**
|
||||
* Putting the Offer Pics into a single Image
|
||||
*/
|
||||
.post('/overview', async (req, res) => {
|
||||
let i = 0
|
||||
const finalHash = req.body.reduce((complete, url) => sha1(complete + url), '')
|
||||
const finalHashPath = `./.cache/${ finalHash }.png`
|
||||
if (fs.existsSync('./.cache') === false)
|
||||
fs.mkdirSync('./.cache')
|
||||
console.log(req.body.length, finalHash)
|
||||
|
||||
if (fs.existsSync(finalHashPath) === false) {
|
||||
const returnImage = OverviewImg.clone();
|
||||
await returnImage.resize(
|
||||
Math.min(req.body.length, 3) * 500,
|
||||
Math.ceil(req.body.length / 3) * 500
|
||||
)
|
||||
for (let inUrl of req.body) {
|
||||
const cachePath = `./.cache/${ sha1(inUrl) }.png`
|
||||
const url = config.mcdEndpointOfferImage + inUrl
|
||||
console.log(cachePath, url)
|
||||
let image
|
||||
const x = i % 3, y = Math.floor(i / 3)
|
||||
console.log(`${ i } at x=${ x }, y=${ y }`)
|
||||
if (fs.existsSync(cachePath) === false) {
|
||||
let httpImage = await Jimp.read(url)
|
||||
console.log('downloading')
|
||||
await httpImage.writeAsync(cachePath)
|
||||
image = httpImage
|
||||
} else {
|
||||
let cacheImage = await Jimp.read(cachePath)
|
||||
console.log('cache')
|
||||
image = cacheImage
|
||||
}
|
||||
await image.resize(450, 450)
|
||||
await returnImage.composite(image, 25 + x * 500, 25 + y * 500)
|
||||
i++
|
||||
}
|
||||
await returnImage.writeAsync(finalHashPath)
|
||||
res.set('Cache-ID', finalHash)
|
||||
res.set('Content-Type', 'image/png')
|
||||
return res.send(await returnImage.getBufferAsync('image/png'))
|
||||
} else {
|
||||
const cacheImage = await Jimp.read(finalHashPath)
|
||||
console.log('loading overview from cache')
|
||||
res.set('Cache-ID', finalHash)
|
||||
res.set('Content-Type', 'image/png')
|
||||
return res.send(await cacheImage.getBufferAsync('image/png'))
|
||||
}
|
||||
})
|
||||
;
|
||||
/*
|
||||
|
||||
329, 780
|
||||
750, 1201
|
||||
*/
|
||||
|
||||
microService.listen(config.renderService.port, config.renderService.host)
|
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
@ -0,0 +1,700 @@
|
||||
{
|
||||
"name": "renderservice",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@jimp/bmp": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.8.5.tgz",
|
||||
"integrity": "sha512-o/23j1RODQGGjvb2xg+9ZQCHc9uXa5XIoJuXHN8kh8AJBGD7JZYiHMwNHaxJRJvadimCKUeA5udZUJAoaPwrYg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"bmp-js": "^0.1.0",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/core": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.8.5.tgz",
|
||||
"integrity": "sha512-Jto1IdL5HYg7uE15rpQjK6dfZJ6d6gRjUsVCPW50nIfXgWizaTibFEov90W9Bj+irwKrX2ntG3e3pZUyOC0COg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"any-base": "^1.1.0",
|
||||
"buffer": "^5.2.0",
|
||||
"core-js": "^2.5.7",
|
||||
"exif-parser": "^0.1.12",
|
||||
"file-type": "^9.0.0",
|
||||
"load-bmfont": "^1.3.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"phin": "^2.9.1",
|
||||
"pixelmatch": "^4.0.2",
|
||||
"tinycolor2": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"@jimp/custom": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.8.5.tgz",
|
||||
"integrity": "sha512-hS4qHOcOIL+N93IprsIhFgr8F4XnC2oYd+lRaOKEOg3ptS2vQnceSTtcXsC0//mhq8AV6lNjpbfs1iseEZuTqg==",
|
||||
"requires": {
|
||||
"@jimp/core": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/gif": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.8.5.tgz",
|
||||
"integrity": "sha512-Mj8jmv4AS76OY+Hx/Xoyihj02SUZ2ELk+O5x89pODz1+NeGtSWHHjZjnSam9HYAjycvVI/lGJdk/7w0nWIV/yQ==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"omggif": "^1.0.9"
|
||||
}
|
||||
},
|
||||
"@jimp/jpeg": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.8.5.tgz",
|
||||
"integrity": "sha512-7kjTY0BiCpwRywk+oPfpLto7cLI+9G0mf4N1bv1Hn+VLQwcXFy2fHyl4qjqLbbY6u4cyZgqN+R8Pg6GRRzv0kw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"jpeg-js": "^0.3.4"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-blit": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.8.5.tgz",
|
||||
"integrity": "sha512-r8Z1CwazaJwZCRbucQgrfprlGyH91tX7GubUsbWr+zy5/dRJAAgaPj/hcoHDwbh3zyiXp5BECKKzKW0x4reL4w==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-blur": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.8.5.tgz",
|
||||
"integrity": "sha512-UH5ywpV4YooUh9HXEsrNKDtojLCvIAAV0gywqn8EQeFyzwBJyXAvRNARJp7zr5OPLr9uGXkRLDCO9YyzdlXZng==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-color": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.8.5.tgz",
|
||||
"integrity": "sha512-7XHqcTQ8Y1zto1b9P1y8m1dzSjnOpBsD9OZG0beTpeJ5bgPX+hF5ZLmvcM6c5ljkINw5EUF1it07BYbkCxiGQA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"tinycolor2": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-contain": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.8.5.tgz",
|
||||
"integrity": "sha512-ZkiPFx9L0yITiKtYTYLWyBsSIdxo/NARhNPRZXyVF9HmTWSLDUw1c2c1uvETKxDZTAVK+souYT14DwFWWdhsYA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-cover": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.8.5.tgz",
|
||||
"integrity": "sha512-OdT4YAopLOhbhTUQV3R1v5ZZqIaUt3n3vJi/OfTbsak1t9UkPBVdmYPyhoont8zJdtdkF5dW16Ro1FTshytcww==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-crop": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.8.5.tgz",
|
||||
"integrity": "sha512-E1Hb+gfu2k74Gkqh96apAyVljsP5MjCH4TY6lECAAEcYKGH/XRhz6lY2dSEjCYE7KtiqjTZzWwYkgAvkwojj9Q==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-displace": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.8.5.tgz",
|
||||
"integrity": "sha512-fVgVYTS1HZzAXkg8Lg06PuirSUG5oXYaYYGL+3ZU4tmZn1pyZ+mZyfejpwtymETEYZnmymHoCT4xto19E/IRvA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-dither": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.8.5.tgz",
|
||||
"integrity": "sha512-KSj2y8E3yK7tldjT/8ejqAWw5HFBjtWW6QkcxfW7FdV4c/nsXZXDkMbhqMZ7FkDuSYoAPeWUFeddrH4yipC5iA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-flip": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.8.5.tgz",
|
||||
"integrity": "sha512-2QbGDkurPNAXZUeHLo/UA3tjh+AbAXWZKSdtoa1ArlASovRz8rqtA45YIRIkKrMH82TA3PZk8bgP2jaLKLrzww==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-gaussian": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.8.5.tgz",
|
||||
"integrity": "sha512-2zReC5GJcVAXtf3UgzFcHSYN277i02K9Yrhc1xJf3mti00s43uD++B5Ho7/mIo+HrntVvWhxqar7PARdq0lVIg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-invert": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.8.5.tgz",
|
||||
"integrity": "sha512-GyMXPGheHdS14xfDceuZ9hrGm6gE9UG3PfTEjQbJmHMWippLC6yf8kombSudJlUf8q72YYSSXsSFKGgkHa67vA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-mask": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.8.5.tgz",
|
||||
"integrity": "sha512-inD/++XO+MkmwXl9JGYQ8X2deyOZuq9i+dmugH/557p16B9Q6tvUQt5X1Yg5w7hhkLZ00BKOAJI9XoyCC1NFvQ==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-normalize": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.8.5.tgz",
|
||||
"integrity": "sha512-8YRWJWBT4NoSAbPhnjQJXGeaeWVrJAlGDv39A54oNH8Ry47fHcE0EN6zogQNpBuM34M6hRnZl4rOv1FIisaWdg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-print": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.8.5.tgz",
|
||||
"integrity": "sha512-BviNpCiA/fEieOqsrWr1FkqyFuiG2izdyyg7zUqyeUTHPwqrTLvXO9cfP/ThG4hZpu5wMQ5QClWSqhZu1fAwxA==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"load-bmfont": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-resize": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.8.5.tgz",
|
||||
"integrity": "sha512-gIdmISuNmZQ1QwprnRC5VXVWQfKIiWineVQGebpMAG/aoFOLDXrVl939Irg7Fb/uOlSFTzpAbt1zpJ8YG/Mi2w==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-rotate": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.8.5.tgz",
|
||||
"integrity": "sha512-8T9wnL3gb+Z0ogMZmtyI6h3y7TuqW2a5SpFbzFUVF+lTZoAabXjEfX3CAozizCLaT+Duc5H2FJVemAHiyr+Dbw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugin-scale": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.8.5.tgz",
|
||||
"integrity": "sha512-G+CDH9s7BsxJ4b+mKZ5SsiXwTAynBJ+7/9SwZFnICZJJvLd79Tws6VPXfSaKJZuWnGIX++L8jTGmFORCfLNkdg==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"@jimp/plugins": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.8.5.tgz",
|
||||
"integrity": "sha512-52na0wqfQ3uItIA+C9cJ1EXffhSmABgK7ETClDseUh9oGtynHzxZ97smnFf1ydLjXLrF89Gt+YBxWLyiBGgiZQ==",
|
||||
"requires": {
|
||||
"@jimp/plugin-blit": "^0.8.5",
|
||||
"@jimp/plugin-blur": "^0.8.5",
|
||||
"@jimp/plugin-color": "^0.8.5",
|
||||
"@jimp/plugin-contain": "^0.8.5",
|
||||
"@jimp/plugin-cover": "^0.8.5",
|
||||
"@jimp/plugin-crop": "^0.8.5",
|
||||
"@jimp/plugin-displace": "^0.8.5",
|
||||
"@jimp/plugin-dither": "^0.8.5",
|
||||
"@jimp/plugin-flip": "^0.8.5",
|
||||
"@jimp/plugin-gaussian": "^0.8.5",
|
||||
"@jimp/plugin-invert": "^0.8.5",
|
||||
"@jimp/plugin-mask": "^0.8.5",
|
||||
"@jimp/plugin-normalize": "^0.8.5",
|
||||
"@jimp/plugin-print": "^0.8.5",
|
||||
"@jimp/plugin-resize": "^0.8.5",
|
||||
"@jimp/plugin-rotate": "^0.8.5",
|
||||
"@jimp/plugin-scale": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"timm": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"@jimp/png": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.8.5.tgz",
|
||||
"integrity": "sha512-zT89ucu8I2rsD3FIMIPLgr1OyKn4neD+5umwD3MY8AOB8+6tX5bFtnmTm3FzGJaJuibkK0wFl87eiaxnb+Megw==",
|
||||
"requires": {
|
||||
"@jimp/utils": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"pngjs": "^3.3.3"
|
||||
}
|
||||
},
|
||||
"@jimp/tiff": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.8.5.tgz",
|
||||
"integrity": "sha512-Z7uzDcbHuwDg+hy2+UJQ2s5O6sqYXmv6H1fmSf/2dxBrlGMzl8yTc2/BxLrGREeoidDDMcKmXYGAOp4uCsdJjw==",
|
||||
"requires": {
|
||||
"core-js": "^2.5.7",
|
||||
"utif": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"@jimp/types": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.8.5.tgz",
|
||||
"integrity": "sha512-XUvpyebZGd1vyFiJyxUT4H9A3mKD7MV2MxjXnay3fNTrcow0UJJspmFw/w+G3TP/1dgrVC4K++gntjR6QWTzvg==",
|
||||
"requires": {
|
||||
"@jimp/bmp": "^0.8.5",
|
||||
"@jimp/gif": "^0.8.5",
|
||||
"@jimp/jpeg": "^0.8.5",
|
||||
"@jimp/png": "^0.8.5",
|
||||
"@jimp/tiff": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"timm": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"@jimp/utils": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.8.5.tgz",
|
||||
"integrity": "sha512-D3+H4BiopDkhUKvKkZTPPJ53voqOkfMuk3r7YZNcLtXGLkchjjukC4056lNo7B0DzjBgowTYsQM3JjKnYNIYeg==",
|
||||
"requires": {
|
||||
"core-js": "^2.5.7"
|
||||
}
|
||||
},
|
||||
"any-base": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
|
||||
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
},
|
||||
"bmp-js": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz",
|
||||
"integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM="
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
|
||||
"integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"buffer-equal": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
|
||||
"integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs="
|
||||
},
|
||||
"charenc": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
||||
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||
},
|
||||
"core-js": {
|
||||
"version": "2.6.10",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
|
||||
"integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA=="
|
||||
},
|
||||
"crypt": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
|
||||
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
|
||||
"requires": {
|
||||
"object-keys": "^1.0.12"
|
||||
}
|
||||
},
|
||||
"dom-walk": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
|
||||
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
|
||||
},
|
||||
"es-abstract": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz",
|
||||
"integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==",
|
||||
"requires": {
|
||||
"es-to-primitive": "^1.2.0",
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.0",
|
||||
"is-callable": "^1.1.4",
|
||||
"is-regex": "^1.0.4",
|
||||
"object-inspect": "^1.6.0",
|
||||
"object-keys": "^1.1.1",
|
||||
"string.prototype.trimleft": "^2.1.0",
|
||||
"string.prototype.trimright": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"es-to-primitive": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
|
||||
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
|
||||
"requires": {
|
||||
"is-callable": "^1.1.4",
|
||||
"is-date-object": "^1.0.1",
|
||||
"is-symbol": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"exif-parser": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
|
||||
"integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI="
|
||||
},
|
||||
"file-type": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz",
|
||||
"integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw=="
|
||||
},
|
||||
"for-each": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
|
||||
"requires": {
|
||||
"is-callable": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"global": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
|
||||
"integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
|
||||
"requires": {
|
||||
"min-document": "^2.19.0",
|
||||
"process": "~0.5.1"
|
||||
}
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
||||
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
|
||||
},
|
||||
"is-callable": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
|
||||
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
|
||||
},
|
||||
"is-date-object": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
|
||||
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
|
||||
},
|
||||
"is-function": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
|
||||
"integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
|
||||
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
|
||||
"requires": {
|
||||
"has": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"is-symbol": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
|
||||
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"jimp": {
|
||||
"version": "0.8.5",
|
||||
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.8.5.tgz",
|
||||
"integrity": "sha512-BW7t/+TCgKpqZw/wHFwqF/A/Tyk43RmzRHyMBdqfOepqunUrajt0RTqowdWyFo4CS2FmD8pFiYfefWjpXFWrCA==",
|
||||
"requires": {
|
||||
"@jimp/custom": "^0.8.5",
|
||||
"@jimp/plugins": "^0.8.5",
|
||||
"@jimp/types": "^0.8.5",
|
||||
"core-js": "^2.5.7",
|
||||
"regenerator-runtime": "^0.13.3"
|
||||
}
|
||||
},
|
||||
"jpeg-js": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.6.tgz",
|
||||
"integrity": "sha512-MUj2XlMB8kpe+8DJUGH/3UJm4XpI8XEgZQ+CiHDeyrGoKPdW/8FJv6ku+3UiYm5Fz3CWaL+iXmD8Q4Ap6aC1Jw=="
|
||||
},
|
||||
"load-bmfont": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz",
|
||||
"integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==",
|
||||
"requires": {
|
||||
"buffer-equal": "0.0.1",
|
||||
"mime": "^1.3.4",
|
||||
"parse-bmfont-ascii": "^1.0.3",
|
||||
"parse-bmfont-binary": "^1.0.5",
|
||||
"parse-bmfont-xml": "^1.1.4",
|
||||
"phin": "^2.9.1",
|
||||
"xhr": "^2.0.1",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"min-document": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
|
||||
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
|
||||
"requires": {
|
||||
"dom-walk": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz",
|
||||
"integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ=="
|
||||
},
|
||||
"object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
||||
},
|
||||
"object.getownpropertydescriptors": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
|
||||
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
|
||||
"requires": {
|
||||
"define-properties": "^1.1.2",
|
||||
"es-abstract": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"omggif": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
|
||||
"integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz",
|
||||
"integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw=="
|
||||
},
|
||||
"parse-bmfont-ascii": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
|
||||
"integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU="
|
||||
},
|
||||
"parse-bmfont-binary": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
|
||||
"integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY="
|
||||
},
|
||||
"parse-bmfont-xml": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz",
|
||||
"integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==",
|
||||
"requires": {
|
||||
"xml-parse-from-string": "^1.0.0",
|
||||
"xml2js": "^0.4.5"
|
||||
}
|
||||
},
|
||||
"parse-headers": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz",
|
||||
"integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==",
|
||||
"requires": {
|
||||
"for-each": "^0.3.3",
|
||||
"string.prototype.trim": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"phin": {
|
||||
"version": "2.9.3",
|
||||
"resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz",
|
||||
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="
|
||||
},
|
||||
"pixelmatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
|
||||
"integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
|
||||
"requires": {
|
||||
"pngjs": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"pngjs": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
|
||||
"integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="
|
||||
},
|
||||
"process": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
|
||||
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.3",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
|
||||
"integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw=="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"sha1": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz",
|
||||
"integrity": "sha1-rdqnqTFo85PxnrKxUJFhjicA+Eg=",
|
||||
"requires": {
|
||||
"charenc": ">= 0.0.1",
|
||||
"crypt": ">= 0.0.1"
|
||||
}
|
||||
},
|
||||
"string.prototype.trim": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz",
|
||||
"integrity": "sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg==",
|
||||
"requires": {
|
||||
"define-properties": "^1.1.3",
|
||||
"es-abstract": "^1.13.0",
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"string.prototype.trimleft": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
|
||||
"integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
|
||||
"requires": {
|
||||
"define-properties": "^1.1.3",
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"string.prototype.trimright": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
|
||||
"integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
|
||||
"requires": {
|
||||
"define-properties": "^1.1.3",
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"timm": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz",
|
||||
"integrity": "sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw=="
|
||||
},
|
||||
"tinycolor2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
|
||||
"integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
|
||||
},
|
||||
"utif": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz",
|
||||
"integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==",
|
||||
"requires": {
|
||||
"pako": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"util.promisify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
|
||||
"integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
|
||||
"requires": {
|
||||
"define-properties": "^1.1.2",
|
||||
"object.getownpropertydescriptors": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"xhr": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
|
||||
"integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
|
||||
"requires": {
|
||||
"global": "~4.3.0",
|
||||
"is-function": "^1.0.1",
|
||||
"parse-headers": "^2.0.0",
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"xml-parse-from-string": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
|
||||
"integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig="
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.22",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz",
|
||||
"integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==",
|
||||
"requires": {
|
||||
"sax": ">=0.6.0",
|
||||
"util.promisify": "~1.0.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "renderservice",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"jimp": "^0.8.5",
|
||||
"sha1": "^1.1.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,257 @@
|
||||
const config = require('../config')
|
||||
|
||||
const express = require('../node_modules/express')
|
||||
const bodyParser = require('../node_modules/body-parser')
|
||||
const querystring = require('../node_modules/querystring')
|
||||
|
||||
const microService = express()
|
||||
microService.use(bodyParser.json(true))
|
||||
|
||||
// MongoDB
|
||||
const { mongoose, Models } = require('../database')
|
||||
|
||||
// MCD API
|
||||
const rqt = require('../node_modules/rqt')
|
||||
const MCDSession = new rqt.Session({
|
||||
host: config.mcdEndpointLegacy,
|
||||
headers: config.mcdHeadersLegacy,
|
||||
})
|
||||
|
||||
const login = async (botId) => {
|
||||
let dbId = mongoose.Types.ObjectId(botId)
|
||||
let $user = await Models.Account.findById(dbId)
|
||||
console.log('logging in', $user._id)
|
||||
const res = await MCDSession.jqt('/v2/customer/security/authentication?type=traditional', {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
password: $user.password,
|
||||
type: "email",
|
||||
loginUsername: $user.email,
|
||||
}
|
||||
})
|
||||
if (res.status == "ok") {
|
||||
await Models.Account.findByIdAndUpdate(dbId, {
|
||||
token: res.details.token,
|
||||
lastLogin: new Date(),
|
||||
})
|
||||
return true
|
||||
} else
|
||||
console.error('logging in', $user._id, 'failed', res)
|
||||
return false
|
||||
}
|
||||
const redeemCode = async (userName, token, storeId, offerId, retryOnError) => {
|
||||
if (retryOnError == undefined) retryOnError = true
|
||||
console.log('redeemCode', userName, storeId, offerId, retryOnError)
|
||||
const res = await MCDSession.jqt('/v3/customer/offer/redemption', {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
"marketId": "DE",
|
||||
"application": "MOT",
|
||||
"languageName": "de-DE",
|
||||
"platform": "android",
|
||||
"offersIds": [`${ offerId }`],
|
||||
"storeId": storeId,
|
||||
"userName": userName,
|
||||
},
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ token }`
|
||||
}
|
||||
})
|
||||
if (!!res.Data && !!res.Data.QrCode) {
|
||||
console.log('SUCC', res)
|
||||
return res
|
||||
} else {
|
||||
if (retryOnError) {
|
||||
switch (parseInt(res.statusCode)) {
|
||||
case 10022:
|
||||
case 10018:
|
||||
console.log('not logged in')
|
||||
break;
|
||||
case -28006: //McDoofnald Exploded
|
||||
console.error('McDoofnald Exploded')
|
||||
break;
|
||||
}
|
||||
let retry = await redeemCode(userName, token, storeId, offerId, false)
|
||||
return retry
|
||||
}
|
||||
console.error('error', res)
|
||||
return false
|
||||
}
|
||||
}
|
||||
const removeMCDType = (obj) => {
|
||||
for(prop in obj) {
|
||||
if (prop === '$type')
|
||||
delete obj[prop]
|
||||
else if (typeof obj[prop] === 'object')
|
||||
removeMCDType(obj[prop])
|
||||
}
|
||||
}
|
||||
const compressOffers = (users) => {
|
||||
let output = {}
|
||||
let uniqueOffers = {}
|
||||
let $users = Object.keys(users)
|
||||
for (let i=0;i < $users.length;i++) {
|
||||
let $user = $users[i]
|
||||
let $offers = users[ $user ]
|
||||
for (let j=0;j< $offers.length; j++) {
|
||||
let $offer = $offers[ j ]
|
||||
if (!uniqueOffers[ $offer.Id ]) {
|
||||
uniqueOffers[ $offer.Id ] = {
|
||||
...$offer,
|
||||
tokens: []
|
||||
}
|
||||
}
|
||||
uniqueOffers[ $offer.Id ].tokens.push($user)
|
||||
}
|
||||
}
|
||||
return Object.values(uniqueOffers)
|
||||
}
|
||||
const customerOffer = async (userName, token, lat, lng, storeId, retryOnError) => {
|
||||
if (retryOnError == undefined) retryOnError = true
|
||||
const res = await MCDSession.jqt('/v3/customer/offer?' + querystring.stringify({
|
||||
marketId: 'DE',
|
||||
application: 'MOT',
|
||||
languageName:'de-DE',
|
||||
platform: 'ios',
|
||||
userName: userName,
|
||||
latitude: lat,
|
||||
longitude: lng,
|
||||
storeId: storeId || '[]'
|
||||
}), {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ token }`
|
||||
}
|
||||
})
|
||||
if (!!res.ResultCode && parseInt(res.ResultCode) == 1) {
|
||||
console.log(res)
|
||||
return res
|
||||
} else {
|
||||
console.error('ERROR', res)
|
||||
if (retryOnError) {
|
||||
switch (parseInt(res.statusCode)) {
|
||||
case 10022:
|
||||
case 10018:
|
||||
console.log('not logged in')
|
||||
break;
|
||||
case -28006: //McDoofnald Exploded
|
||||
console.error('McDoofnald Exploded')
|
||||
break;
|
||||
}
|
||||
let retry = await customerOffer(userName, token, lat, lng, storeId, false)
|
||||
return retry
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
microService
|
||||
/**
|
||||
* Creating a Session
|
||||
*/
|
||||
.post('/sitzung/:user', async (req, res) => {
|
||||
const userId = parseInt(req.params.user)
|
||||
let freeAccounts = await Models.Account
|
||||
.count({ free: true, active: true })
|
||||
.limit(config.sessionManager.accountsPerSession);
|
||||
|
||||
if (freeAccounts < config.sessionManager.accountsPerSession) {
|
||||
return res.status(500).json('Bitte versuchen sie es später erneut, es werden gerade neue Accounts erstellt.')
|
||||
}
|
||||
|
||||
let accountsForSession = await Models.Account
|
||||
.find({ free: true, active: true })
|
||||
.limit(config.sessionManager.accountsPerSession);
|
||||
|
||||
for (let account of accountsForSession) {
|
||||
await Models.Account.findByIdAndUpdate(account._id, {
|
||||
free: false,
|
||||
lastLogin: new Date(),
|
||||
})
|
||||
await login(account._id)
|
||||
}
|
||||
|
||||
if (await Models.Session.count({ userId: userId }) > 0) {
|
||||
await Models.Session.findOneAndDelete({ userId: userId })
|
||||
}
|
||||
let session = await Models.Session.create({
|
||||
userId: userId,
|
||||
accounts: accountsForSession.map(a => mongoose.Types.ObjectId(a._id)),
|
||||
})
|
||||
//console.log(session)
|
||||
res.json(session)
|
||||
})
|
||||
/**
|
||||
* Selecting a Restaurant and sending fetched Offers to rabbitmq
|
||||
*/
|
||||
.post('/sitzung/:user/restaurant/:restaurant', async (req, res) => {
|
||||
const userId = parseInt(req.params.user)
|
||||
const restaurantId = mongoose.Types.ObjectId(req.params.restaurant)
|
||||
if (await Models.Session.count({ userId: userId }) > 0) {
|
||||
if (await Models.Store.count({ _id: restaurantId }) === 0) {
|
||||
return res.json('Fehler: Kein Restaurant mit dieser ID')
|
||||
}
|
||||
await Models.Session
|
||||
.findOne({ userId })
|
||||
.update({ store: restaurantId });
|
||||
const sessionData = await Models.Session
|
||||
.findOne({ userId })
|
||||
.populate('store')
|
||||
.populate('accounts');
|
||||
// ES6 <3
|
||||
const { latitude: storeLat, longitude: storeLon, storeId } = sessionData.store
|
||||
const output = {}
|
||||
for (let sessionAccount of sessionData.accounts) {
|
||||
let offers = await customerOffer(sessionAccount.email, sessionAccount.token, storeLat, storeLon, storeId)
|
||||
if (!offers || !offers.Data || offers.Data.length === 0) continue; // skip empty responses, in case they somehow are
|
||||
//offers.Data.map((offer) => console.log(offer.Archived, offer.Expired, offer.Redeemed))
|
||||
offers.Data = offers.Data.filter((offer) => !offer.Archived && !offer.Expired && !offer.Redeemed)
|
||||
offers.Data = offers.Data.map((offer) => {
|
||||
removeMCDType(offer)
|
||||
return offer
|
||||
})
|
||||
output[ sessionAccount._id.toString() ] = offers.Data
|
||||
}
|
||||
const cOffers = compressOffers(output)
|
||||
//console.log(JSON.stringify(cOffers, null, "\t"))
|
||||
await Models.Session
|
||||
.findOne({ userId })
|
||||
.update({ offers: cOffers })
|
||||
return res.json(cOffers)
|
||||
}
|
||||
res.json(false)
|
||||
})
|
||||
/**
|
||||
* Redeems the Offer
|
||||
*/
|
||||
.get('/sitzung/:user/angebot/:offer', async (req, res) => {
|
||||
const userId = parseInt(req.params.user)
|
||||
const offerId = parseInt(req.params.offer)
|
||||
const sessionData = await Models.Session
|
||||
.findOne({ userId })
|
||||
.populate('store');
|
||||
let selectedOffer = sessionData.offers.filter((offer) => offer.Id === offerId)
|
||||
if (selectedOffer.length === 0) return res.json('Kein Angebot mit der ID gefunden')
|
||||
selectedOffer = selectedOffer[0]
|
||||
|
||||
let offerResult = false
|
||||
for (let i in selectedOffer.tokens) {
|
||||
let offerAccountID = selectedOffer.tokens[ i ]
|
||||
try {
|
||||
// console.log('trying code redemtion with account', offerAccountID)
|
||||
let account = await Models.Account.findById(mongoose.Types.ObjectId(offerAccountID))
|
||||
offerResult = await redeemCode(account.email, account.token, sessionData.store.storeId, offerId)
|
||||
} catch (ex) {
|
||||
console.error(ex)
|
||||
}
|
||||
}
|
||||
if (!!offerResult) {
|
||||
removeMCDType(offerResult)
|
||||
if (offerResult.ResultCode == 1)
|
||||
return res.json(offerResult.Data)
|
||||
}
|
||||
res.json(false)
|
||||
})
|
||||
microService.listen(config.sessionManager.port, config.sessionManager.host)
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "sessionmanager",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "sessionmanager",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {}
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
const config = require('../config')
|
||||
|
||||
const express = require('../node_modules/express')
|
||||
const bodyParser = require('../node_modules/body-parser')
|
||||
// MCD API
|
||||
const rqt = require('../node_modules/rqt')
|
||||
const MCDSession = new rqt.Session({
|
||||
host: config.mcdEndpointLegacy,
|
||||
headers: config.mcdHeadersLegacy,
|
||||
})
|
||||
const querystring = require('../node_modules/querystring')
|
||||
|
||||
const microService = express()
|
||||
microService.use(bodyParser.json(true))
|
||||
// MongoDB
|
||||
const { mongoose, Models } = require('../database')
|
||||
|
||||
const ortSuche = (query) => {
|
||||
return rqt('https://nominatim.openstreetmap.org/search?format=json&q=' + encodeURIComponent(query + ', Deutschland'))
|
||||
}
|
||||
const ortSucheGoogle = async (query) => {
|
||||
return rqt.jqt('https://maps.googleapis.com/maps/api/place/textsearch/json?' + querystring.stringify({
|
||||
key: config.storeFinder.googlePlacesKey,
|
||||
query: query,
|
||||
}))
|
||||
}
|
||||
|
||||
microService
|
||||
.post('/fillialsuche', async (req, res) => {
|
||||
let lon, lat, searchfield, place_id
|
||||
let correlationQuery = {}
|
||||
|
||||
if (!!req.body.query) {
|
||||
let query = req.body.query.toString()
|
||||
console.log('Searching with Query')
|
||||
if (await Models.GoogleCacheResult.count({ query }) === 0) {
|
||||
let orte = await ortSucheGoogle(query)
|
||||
orte = orte.results
|
||||
if (orte.length > 0) {
|
||||
/*orte = orte.sort((a,b) => {
|
||||
a = a.importance * (a.type === 'city' ? 2 : 1)
|
||||
b = b.importance * (b.type === 'city' ? 2 : 1)
|
||||
return a > b
|
||||
})*/
|
||||
const ort = orte[0]
|
||||
lon = parseFloat(ort.geometry.location.lng)
|
||||
lat = parseFloat(ort.geometry.location.lat)
|
||||
searchfield = ort.name
|
||||
place_id = ort.place_id
|
||||
correlationQuery = {
|
||||
place_id: ort.place_id,
|
||||
longitude: lon,
|
||||
latitude: lat,
|
||||
}
|
||||
await Models.GoogleCacheResult.create({
|
||||
query,
|
||||
name: searchfield,
|
||||
place_id: place_id,
|
||||
longitude: lon,
|
||||
latitude: lat,
|
||||
})
|
||||
console.log('Google Result', lon, lat, searchfield, place_id)
|
||||
} else {
|
||||
console.log('Keine Orte von #1 gefunden')
|
||||
return res.status(400).json('Keine Orte gefunden')
|
||||
}
|
||||
} else {
|
||||
let cachedResult = await Models.GoogleCacheResult.findOne({ query })
|
||||
lon = cachedResult.longitude
|
||||
lat = cachedResult.latitude
|
||||
searchfield = cachedResult.name
|
||||
place_id = cachedResult.place_id
|
||||
correlationQuery = {
|
||||
place_id: place_id,
|
||||
longitude: lon,
|
||||
latitude: lat,
|
||||
}
|
||||
console.log('Cache Result', lon, lat, searchfield, place_id)
|
||||
|
||||
}
|
||||
} else if (!!req.body.lat) {
|
||||
console.log('Searching with Location', req.body)
|
||||
lon = parseFloat(req.body.lon)
|
||||
lat = parseFloat(req.body.lat)
|
||||
correlationQuery = {
|
||||
longitude: parseInt(lon * 10000) / 10000,
|
||||
latitude: parseInt(lat * 10000) / 10000,
|
||||
}
|
||||
searchfield = ''
|
||||
place_id = false
|
||||
} else {
|
||||
console.log('Invalid Search')
|
||||
return res.status(400).json(false)
|
||||
}
|
||||
|
||||
let restaurants = []
|
||||
if (!!correlationQuery) {
|
||||
let correlationCount = await Models.StoreFinderCorrelation.count(correlationQuery)
|
||||
console.log('correlationCount', correlationCount)
|
||||
if (correlationCount === 0) {
|
||||
console.log('No Correlations found, asking API')
|
||||
console.time('MCD Search')
|
||||
const restaurants = await rqt.jqt('https://www.mcdonalds.de/search', {
|
||||
method: 'POST',
|
||||
type: 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
data: querystring.stringify({
|
||||
longitude: lon,
|
||||
latitude: lat,
|
||||
searchfield: searchfield,
|
||||
radius: 12, // 12km umkreis suche
|
||||
coupon: true,
|
||||
}),
|
||||
timeout: 6000,
|
||||
})
|
||||
.then(($res) => {
|
||||
if ($res.unfilteredCount === 0) throw 'Keine Restaurants gefunden'
|
||||
$res.restaurantList = $res.restaurantList.sort((a, b) => a.distance - b.distance)
|
||||
return $res.restaurantList.map((entry) => {
|
||||
return entry.restaurant
|
||||
})
|
||||
})
|
||||
.then(async ($res) => {
|
||||
console.log('retaurants', $res)
|
||||
let restaurants = []
|
||||
for (let restaurant of $res) {
|
||||
let seoCount = await Models.Store.count({ seoURL: restaurant.seoURL })
|
||||
if (seoCount == 0) {
|
||||
let ecpStore = await MCDSession.jqt('/v3/restaurant/location?' + querystring.stringify({
|
||||
filter: 'search',
|
||||
query: JSON.stringify({
|
||||
market: 'DE',
|
||||
pageSize: 1,
|
||||
local: 'de-DE',
|
||||
generalStoreStatusCode: 'OPEN,TEMPCLOSE,RENOVATION',
|
||||
locationCriteria: {
|
||||
longitude: lon,
|
||||
latitude: lat,
|
||||
distance: 22000
|
||||
}
|
||||
}),
|
||||
}), { method: 'GET', type: 'json', })
|
||||
if (ecpStore.length === 0) continue; // Skip Restaurants, we dont have the ECPId for
|
||||
console.log(ecpStore)
|
||||
ecpStore = ecpStore[0]
|
||||
if (ecpStore.identifiers.storeIdentifier.filter((a) => a.identifierType == 'ECPID').length == 0) continue
|
||||
|
||||
await Models.Store.create({
|
||||
id: restaurant.id,
|
||||
externalId: restaurant.externalId,
|
||||
|
||||
storeId: ecpStore.id,
|
||||
storeECPId: ecpStore.identifiers.storeIdentifier.filter((a) => a.identifierType == 'ECPID')[0].identifierValue,
|
||||
|
||||
latitude: restaurant.latitude,
|
||||
longitude: restaurant.longitude,
|
||||
|
||||
city: restaurant.city,
|
||||
postalCode: restaurant.postalCode,
|
||||
address: restaurant.address,
|
||||
street: restaurant.street,
|
||||
phone: restaurant.phone,
|
||||
seoURL: restaurant.seoURL,
|
||||
name1: restaurant.name1,
|
||||
name2: restaurant.name2,
|
||||
|
||||
lastRefresh: new Date(),
|
||||
})
|
||||
}
|
||||
let dbRestaurant = await Models.Store.findOne({ seoURL: restaurant.seoURL })
|
||||
restaurants.push(dbRestaurant)
|
||||
}
|
||||
console.timeEnd('MCD Search')
|
||||
return restaurants
|
||||
})
|
||||
.catch(($err) => {
|
||||
console.timeEnd('MCD Search')
|
||||
console.error($err)
|
||||
return false
|
||||
})
|
||||
if (!!restaurants) {
|
||||
for (let restaurant of restaurants) {
|
||||
if (await Models.StoreFinderCorrelation.count({
|
||||
...correlationQuery,
|
||||
store: restaurant._id,
|
||||
}) === 0) {
|
||||
await Models.StoreFinderCorrelation.create({
|
||||
...correlationQuery,
|
||||
store: restaurant._id,
|
||||
lastRefresh: new Date(),
|
||||
})
|
||||
}
|
||||
}
|
||||
return res.json(restaurants)
|
||||
} else {
|
||||
return res.json(false)
|
||||
}
|
||||
} else {
|
||||
console.time('Correlation Search')
|
||||
console.log('Correlations found, returning them...')
|
||||
let restaurantsDB = await Models.StoreFinderCorrelation
|
||||
.find(correlationQuery)
|
||||
.select('store')
|
||||
.populate('store');
|
||||
restaurants = restaurantsDB.map(corr => corr.store)
|
||||
console.timeEnd('Correlation Search')
|
||||
return res.json(restaurants)
|
||||
}
|
||||
}
|
||||
|
||||
return res.json(false)
|
||||
})
|
||||
|
||||
microService.listen(config.storeFinder.port, config.storeFinder.host)
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "storefinder",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "storefinder",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {}
|
||||
}
|
@ -0,0 +1,411 @@
|
||||
const config = require('../config')
|
||||
const rqt = require('../node_modules/rqt')
|
||||
const MCDSession = new rqt.Session({
|
||||
host: config.mcdEndpoint,
|
||||
headers: config.mcdHeaders,
|
||||
})
|
||||
|
||||
const Telegraf = require('telegraf')
|
||||
const Markup = require('telegraf/markup')
|
||||
const Extra = require('telegraf/extra')
|
||||
const Stage = require('telegraf/stage')
|
||||
const { leave } = Stage
|
||||
const Scene = require('telegraf/scenes/base')
|
||||
const rateLimit = require('telegraf-ratelimit')
|
||||
|
||||
// MongoDB
|
||||
const { mongoose, Models } = require('../database')
|
||||
|
||||
const bot = new Telegraf(config.telegramBot.token)
|
||||
|
||||
/* Redis Stuff */
|
||||
const Redis = require('redisng')
|
||||
const redis = new Redis()
|
||||
redis.connect(config.redisHost, config.redisPort)
|
||||
const memorysession = require('telegraf/session')
|
||||
const RedisSession = require('telegraf-session-redis')
|
||||
const session = new RedisSession({
|
||||
store: {
|
||||
host: config.redisHost,
|
||||
port: config.redisPort,
|
||||
},
|
||||
getSessionKey: (ctx) => {
|
||||
if (!ctx.from) return console.log('fail redis key', ctx);
|
||||
return ctx.from.id.toString();
|
||||
}
|
||||
})
|
||||
bot.use(memorysession())
|
||||
//bot.use(session)
|
||||
bot.use(rateLimit({
|
||||
window: 3000,
|
||||
limit: 10,
|
||||
onLimitExceeded: (ctx, next) => ctx.reply('Sie haben zuviele Anfragen geschickt, bitte warten Sie')
|
||||
}))
|
||||
bot.use(async (ctx, next) => {
|
||||
const start = new Date()
|
||||
//console.log(ctx)
|
||||
await next()
|
||||
const ms = new Date() - start
|
||||
console.log('Response time: %sms', ms)
|
||||
})
|
||||
// bot.use(Telegraf.log())
|
||||
|
||||
const cancelText = '\n\nZum abbrechen /cancel schicken!'
|
||||
const restartText = '\n\nZum neustarten /start schicken!'
|
||||
const errorTextSessionManager = 'Tut mir leid, der SessionManager ist gerade nicht erreichbar. Bitte kontaktiere den Entwickler'
|
||||
const errorTextRenderService = 'Tut mir leid, der RenderService ist gerade nicht erreichbar. Bitte kontaktiere den Entwickler'
|
||||
const errorTextStoreFinder = 'Tut mir leid, der StoreFinder ist gerade nicht erreichbar. Bitte kontaktiere den Entwickler'
|
||||
|
||||
|
||||
// Setup 1 Stage
|
||||
const setup0Stage = new Scene('setup')
|
||||
setup0Stage.enter(async (ctx) => {
|
||||
await ctx.reply('Willkommen! Bevor wir loslegen können, setze bitte einige Einstellungen.',
|
||||
Markup
|
||||
.keyboard([
|
||||
['Ich nutze Android', 'Ich nutze ein iPhone'],
|
||||
['❌ Überspringen'],
|
||||
])
|
||||
.resize()
|
||||
.extra()
|
||||
)
|
||||
})
|
||||
setup0Stage.hears('Ich nutze Android', async (ctx) => {
|
||||
console.log('android')
|
||||
await ctx.replyWithChatAction('typing')
|
||||
await ctx.reply('Du hast dich für ein Android entschieden', Markup.removeKeyboard())
|
||||
await Models.User.create({
|
||||
id: ctx.from.id,
|
||||
ios: false,
|
||||
screenWidth: 591,
|
||||
screenHeight: 1280,
|
||||
})
|
||||
let userExists = await Models.User.count({ id: ctx.from.id })
|
||||
if (userExists === 0) {
|
||||
await Models.User.create({
|
||||
id: ctx.from.id,
|
||||
ios: false,
|
||||
screenWidth: 1080,
|
||||
screenHeight: 1920,
|
||||
})
|
||||
} else {
|
||||
await Models.User.findOneAndUpdate({
|
||||
id: ctx.from.id
|
||||
}, {
|
||||
ios: false,
|
||||
screenWidth: 1080,
|
||||
screenHeight: 1920,
|
||||
})
|
||||
}
|
||||
await ctx.scene.enter('setup1')
|
||||
})
|
||||
setup0Stage.hears('Ich nutze ein iPhone', async (ctx) => {
|
||||
await ctx.replyWithChatAction('typing')
|
||||
await ctx.reply('Du hast dich für ein iPhone entschieden', Markup.removeKeyboard())
|
||||
let userExists = await Models.User.count({ id: ctx.from.id })
|
||||
if (userExists === 0) {
|
||||
await Models.User.create({
|
||||
id: ctx.from.id,
|
||||
ios: false,
|
||||
screenWidth: 591,
|
||||
screenHeight: 1280,
|
||||
})
|
||||
} else {
|
||||
await Models.User.findOneAndUpdate({
|
||||
id: ctx.from.id
|
||||
}, {
|
||||
ios: false,
|
||||
screenWidth: 591,
|
||||
screenHeight: 1280,
|
||||
})
|
||||
}
|
||||
await ctx.scene.enter('setup1')
|
||||
})
|
||||
setup0Stage.hears('❌ Überspringen', async (ctx) => {
|
||||
await ctx.replyWithChatAction('typing')
|
||||
await ctx.reply('Du hast dich für ein Android-Smartphone mit 1080x1920px entschieden', Markup.removeKeyboard())
|
||||
let userExists = await Models.User.count({ id: ctx.from.id })
|
||||
if (userExists === 0) {
|
||||
await Models.User.create({
|
||||
id: ctx.from.id,
|
||||
ios: false,
|
||||
screenWidth: 1080,
|
||||
screenHeight: 1920,
|
||||
})
|
||||
} else {
|
||||
await Models.User.findOneAndUpdate({
|
||||
id: ctx.from.id
|
||||
}, {
|
||||
id: ctx.from.id,
|
||||
ios: false,
|
||||
screenWidth: 1080,
|
||||
screenHeight: 1920,
|
||||
})
|
||||
}
|
||||
return ctx.scene.enter('main')
|
||||
})
|
||||
|
||||
// Setup 2 Stage
|
||||
const setup1Stage = new Scene('setup1')
|
||||
setup1Stage.enter(
|
||||
(ctx) => ctx.reply('Um ein perfekten Code-Screenshot zu erzeugen benötige ich deine Bildschirmgröße. Dafür musst du mir einfach nur einen Screenshot schicken.',
|
||||
Markup
|
||||
.keyboard([
|
||||
['❌ Überspringen'],
|
||||
])
|
||||
.forceReply()
|
||||
.resize()
|
||||
.oneTime()
|
||||
.extra()
|
||||
)
|
||||
)
|
||||
setup1Stage.hears('❌ Überspringen', async (ctx) => {
|
||||
return ctx.scene.enter('main')
|
||||
})
|
||||
setup1Stage.on('message', async (ctx) => {
|
||||
await ctx.replyWithChatAction('typing')
|
||||
if (!!ctx.message && !!ctx.message.photo) {
|
||||
let resPhoto = ctx.message.photo.reverse()[0]
|
||||
await Models.User.findOneAndUpdate({
|
||||
id: ctx.from.id
|
||||
}, {
|
||||
screenWidth: resPhoto.width,
|
||||
screenHeight: resPhoto.height,
|
||||
})
|
||||
ctx.reply('Deine Bildschirmauflösung wurde gesetzt.')
|
||||
} else {
|
||||
return ctx.reply('Bitte schick mir einen Screenshot als Bild oder wähle "Überspringen"!')
|
||||
}
|
||||
return ctx.scene.enter('main')
|
||||
})
|
||||
|
||||
|
||||
// Main Stage
|
||||
const mainStage = new Scene('main')
|
||||
mainStage.enter(
|
||||
(ctx) => ctx.reply('Willkommen! Schicke mir einen Standort über 📎 oder einen Ort(z.B. Berlin)' + cancelText, Extra.markup((markup) => {
|
||||
return markup.resize()
|
||||
.keyboard([
|
||||
markup.locationRequestButton('Aktuellen Standort senden')
|
||||
])
|
||||
}))
|
||||
)
|
||||
mainStage.on('message', async (ctx) => {
|
||||
await ctx.replyWithChatAction('typing')
|
||||
let results = []
|
||||
let url = `http://${ config.storeFinder.host }:${ config.storeFinder.port }/fillialsuche`
|
||||
try {
|
||||
if (!!ctx.message.location) {
|
||||
results = await rqt.jqt(url, {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
lon: ctx.message.location.longitude,
|
||||
lat: ctx.message.location.latitude,
|
||||
},
|
||||
timeout: 15000,
|
||||
})
|
||||
} else if (!!ctx.message.text) {
|
||||
results = await rqt.jqt(url, {
|
||||
method: 'POST',
|
||||
type: 'json',
|
||||
data: {
|
||||
query: ctx.message.text,
|
||||
},
|
||||
timeout: 15000,
|
||||
})
|
||||
} else {
|
||||
return ctx.reply('Schicke mir einen Standort über 📎 oder einen Ort(z.B. Berlin)' + cancelText)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return ctx.reply(errorTextStoreFinder + cancelText)
|
||||
}
|
||||
|
||||
if (typeof(results) == 'object' && (!!results || results.length > 0)) {
|
||||
await ctx.reply('Bitte wähle eine Filliale aus' + cancelText,
|
||||
Markup.inlineKeyboard(
|
||||
results.map(restaurant => {
|
||||
return [Markup.callbackButton(`${ restaurant.street } ${ restaurant.address }`, restaurant._id)]
|
||||
})
|
||||
).oneTime().extra()
|
||||
)
|
||||
} else {
|
||||
return ctx.reply('Ort nicht gefunden')
|
||||
}
|
||||
})
|
||||
mainStage.action(/([0-9a-z]{12,24})/, async (ctx) => {
|
||||
await ctx.replyWithChatAction('typing')
|
||||
let dbId = mongoose.Types.ObjectId(ctx.match[1])
|
||||
ctx.deleteMessage()
|
||||
ctx.session.fillialSelection = dbId
|
||||
try {
|
||||
ctx.answerCbQuery('Lade Angebote...')
|
||||
let url = `http://${ config.sessionManager.host }:${ config.sessionManager.port }/sitzung/${ ctx.from.id }`
|
||||
let session = await rqt.jqt(url, { method: 'POST', timeout: 15000 })
|
||||
ctx.session.id = session._id
|
||||
ctx.scene.enter('angebotSelect')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return ctx.reply(errorTextSessionManager + cancelText)
|
||||
}
|
||||
})
|
||||
// Offer Selection
|
||||
const angebotSelectStage = new Scene('angebotSelect')
|
||||
angebotSelectStage.enter(async (ctx) => {
|
||||
let loadMsg = await ctx.reply('Lade Angebote...', Markup.removeKeyboard().extra())
|
||||
let offers = []
|
||||
await ctx.replyWithChatAction('upload_photo')
|
||||
try {
|
||||
let url = `http://${ config.sessionManager.host }:${ config.sessionManager.port }/sitzung/${ ctx.from.id }/restaurant/${ ctx.session.fillialSelection }`
|
||||
offers = await rqt.jqt(url, { method: 'POST', timeout: 15000 })
|
||||
offers = offers.filter((offer) => offer.OfferType !== 9)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return ctx.reply(errorTextSessionManager + restartText)
|
||||
}
|
||||
await ctx.deleteMessage(loadMsg.message_id)
|
||||
let overviewImage, cacheId
|
||||
try {
|
||||
let url = `http://${ config.renderService.host }:${ config.renderService.port }/overview`
|
||||
let response = await rqt.aqt(url, {
|
||||
data: offers.map(offer => offer.ImageBaseName),
|
||||
type: 'json', method: 'POST', timeout: 15000, binary: true
|
||||
})
|
||||
cacheId = response.headers['cache-id']
|
||||
overviewImage = response.body
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return ctx.reply(errorTextRenderService + restartText)
|
||||
}
|
||||
let fileId = await redis.get('render-' + cacheId)
|
||||
let selectMsg
|
||||
let selectMsgKeyboard = Markup.inlineKeyboard(
|
||||
offers.map(offer => {
|
||||
return [Markup.callbackButton(`[${ offer.Id }] ${ offer.Name }`, offer.Id)]
|
||||
})
|
||||
.concat([
|
||||
[ Markup.callbackButton('Abbrechen', 'abort') ]
|
||||
])
|
||||
).extra()
|
||||
if (!fileId) {
|
||||
selectMsg = await ctx.replyWithPhoto({ source: overviewImage }, selectMsgKeyboard)
|
||||
await redis.set('render-' + cacheId, selectMsg.photo.reverse()[0].file_id)
|
||||
} else {
|
||||
console.log('using cached file id')
|
||||
selectMsg = await ctx.replyWithPhoto(fileId, selectMsgKeyboard)
|
||||
}
|
||||
await redis.set('msg-' + ctx.from.id, selectMsg.message_id)
|
||||
// ctx.scene.state.selectMsg = selectMsg.message_id // doesnt work because of #reason
|
||||
})
|
||||
angebotSelectStage.leave(async (ctx) => {
|
||||
let msgToDelete = await redis.get('msg-' + ctx.from.id)
|
||||
if (!!msgToDelete)
|
||||
try {
|
||||
await ctx.deleteMessage(msgToDelete)
|
||||
} catch (e) {}
|
||||
})
|
||||
angebotSelectStage.action('abort', (ctx) => ctx.scene.enter('main'))
|
||||
angebotSelectStage.action('back', (ctx) => ctx.scene.leave())
|
||||
angebotSelectStage.action(/(.*)/, async (ctx) => {
|
||||
const offerId = parseInt(ctx.match[1])
|
||||
try {
|
||||
ctx.answerCbQuery('Lade Angebot...')
|
||||
let url = `http://${ config.sessionManager.host }:${ config.sessionManager.port }/sitzung/${ ctx.from.id }/angebot/${ offerId }`
|
||||
let code = await rqt.jqt(url, { method: 'GET', timeout: 15000, type: 'json' })
|
||||
if (!code) throw 'Kein Code vorhanden'
|
||||
ctx.session.code = code
|
||||
console.log('entering code stage', !!code)
|
||||
ctx.scene.enter('angebotCode')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return ctx.reply(errorTextSessionManager + cancelText)
|
||||
}
|
||||
})
|
||||
// Offer Code
|
||||
const angebotCodeStage = new Scene('angebotCode')
|
||||
angebotCodeStage.enter(async (ctx) => {
|
||||
await ctx.replyWithChatAction('upload_photo')
|
||||
//let loadMsg = await ctx.reply('Lade Code...' + cancelText)
|
||||
let codeImage
|
||||
try {
|
||||
let code = ctx.session.code
|
||||
let user = await Models.User.findOne({ id: ctx.from.id })
|
||||
code.ios = !!user.ios
|
||||
code.screenWidth = user.screenWidth
|
||||
code.screenHeight = user.screenHeight
|
||||
let url = `http://${ config.renderService.host }:${ config.renderService.port }/qrcode`
|
||||
codeImage = await rqt.bqt(url, { data: code, type: 'json', method: 'POST', timeout: 6000 })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return ctx.reply(errorTextRenderService + cancelText)
|
||||
}
|
||||
//await ctx.deleteMessage(loadMsg.message_id)
|
||||
let codeMsg = await ctx.replyWithPhoto({ source: codeImage }, Markup.inlineKeyboard([
|
||||
[
|
||||
Markup.callbackButton('Zurück', 'back'),
|
||||
Markup.callbackButton('Nächster Code', 'next')
|
||||
],
|
||||
[
|
||||
Markup.callbackButton('Sitzung beenden', 'abort')
|
||||
]
|
||||
]).extra())
|
||||
ctx.session.codeMsg = codeMsg.message_id
|
||||
})
|
||||
angebotCodeStage.leave(async (ctx) => {
|
||||
if (!!ctx.session.codeMsg)
|
||||
await ctx.deleteMessage(ctx.session.codeMsg)
|
||||
})
|
||||
angebotCodeStage.action('abort', async (ctx) => {
|
||||
await ctx.replyWithChatAction('typing')
|
||||
try {
|
||||
//TODO: call SessionManager to delete the session
|
||||
} catch(e) {
|
||||
}
|
||||
leaveFunc(ctx)
|
||||
ctx.scene.enter('main')
|
||||
})
|
||||
angebotCodeStage.action('back', (ctx) => {
|
||||
ctx.answerCbQuery('')
|
||||
ctx.scene.enter('angebotSelect')
|
||||
})
|
||||
angebotCodeStage.action('next', async (ctx) => {
|
||||
ctx.answerCbQuery('')
|
||||
ctx.scene.enter('angebotCode')
|
||||
})
|
||||
angebotCodeStage.action(/(.*)/, async (ctx) => {
|
||||
ctx.answerCbQuery('')
|
||||
console.log(ctx.match[1])
|
||||
})
|
||||
|
||||
const startFunc = async (ctx) => {
|
||||
let userExists = await Models.User.count({ id: ctx.from.id })
|
||||
if (userExists === 0) {
|
||||
ctx.scene.enter('setup')
|
||||
} else {
|
||||
ctx.scene.enter('main')
|
||||
}
|
||||
}
|
||||
// Create scene manager
|
||||
const stage = new Stage()
|
||||
const leaveFunc = leave()
|
||||
stage.command('cancel', (ctx) => {
|
||||
leaveFunc(ctx)
|
||||
ctx.reply('Aktion erfolgreich abgebrochen, nutze /start um nochmal neu anzufangen')
|
||||
})
|
||||
stage.command('start', (ctx) => {
|
||||
leaveFunc(ctx)
|
||||
startFunc(ctx)
|
||||
})
|
||||
|
||||
// Scene registration
|
||||
stage.register(setup0Stage)
|
||||
stage.register(setup1Stage)
|
||||
stage.register(mainStage)
|
||||
stage.register(angebotSelectStage)
|
||||
stage.register(angebotCodeStage)
|
||||
|
||||
bot.use(stage.middleware())
|
||||
bot.command('start', startFunc)
|
||||
bot.command('settings', (ctx) => ctx.scene.enter('setup'))
|
||||
bot.launch()
|
@ -0,0 +1,142 @@
|
||||
{
|
||||
"name": "tgbot",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "12.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz",
|
||||
"integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A=="
|
||||
},
|
||||
"@types/redis": {
|
||||
"version": "2.8.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.14.tgz",
|
||||
"integrity": "sha512-255dzsOLJdXFHBio9/aMHGozNkoiBUgc+g2nlNjbTSp5qcAlmpm4Z6Xs3pKOBLNIKdZbA2BkUxWvYSIwKra0Yw==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"double-ended-queue": {
|
||||
"version": "2.1.0-0",
|
||||
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
|
||||
"integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"redis": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
|
||||
"integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==",
|
||||
"requires": {
|
||||
"double-ended-queue": "^2.1.0-0",
|
||||
"redis-commands": "^1.2.0",
|
||||
"redis-parser": "^2.6.0"
|
||||
}
|
||||
},
|
||||
"redis-commands": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.5.0.tgz",
|
||||
"integrity": "sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg=="
|
||||
},
|
||||
"redis-parser": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz",
|
||||
"integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs="
|
||||
},
|
||||
"redis-proto": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-proto/-/redis-proto-2.1.0.tgz",
|
||||
"integrity": "sha1-hPt/aOpJdAqxQBZwjJr95ioqRIo="
|
||||
},
|
||||
"redisng": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/redisng/-/redisng-2.0.0.tgz",
|
||||
"integrity": "sha1-Kv3Nxw8UYiVePZizgqLbZwjrmWw=",
|
||||
"requires": {
|
||||
"redis-proto": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"sandwich-stream": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz",
|
||||
"integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ=="
|
||||
},
|
||||
"telegraf": {
|
||||
"version": "3.33.3",
|
||||
"resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.33.3.tgz",
|
||||
"integrity": "sha512-ItSAeE9OjFH+X0rS8DeErccoUZRy2hBl+mDjFWDqyZWyRElxA5L178UpJV7tM6hCVN/leFY+9orfra2JtX4AyQ==",
|
||||
"requires": {
|
||||
"@types/node": "^12.0.4",
|
||||
"debug": "^4.0.1",
|
||||
"node-fetch": "^2.2.0",
|
||||
"sandwich-stream": "^2.0.1",
|
||||
"telegram-typings": "^3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"telegraf-ratelimit": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/telegraf-ratelimit/-/telegraf-ratelimit-2.0.0.tgz",
|
||||
"integrity": "sha512-OUVJRz+pVDpkOfwvFuv4x5YxcPIl6puPN3HRdicN3NDnT+jQeMzKDwVAkvloUtyH1Ruo1wH4nfB5tZbtJAJ4pQ==",
|
||||
"requires": {
|
||||
"debug": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"telegraf-session-redis": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/telegraf-session-redis/-/telegraf-session-redis-5.1.0.tgz",
|
||||
"integrity": "sha512-Ohl9GxorTz3kcgFL38KSYl7U4OqEr6TLNXa841pFC7wwB9Z/zhOt9nkExAFOWu5wHE8wBwApCHt5X63XGvhy3Q==",
|
||||
"requires": {
|
||||
"@types/redis": "^2.8.6",
|
||||
"debug": "^4.1.1",
|
||||
"redis": "^2.6.0-1"
|
||||
}
|
||||
},
|
||||
"telegram-typings": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/telegram-typings/-/telegram-typings-3.6.1.tgz",
|
||||
"integrity": "sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw=="
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "tgbot",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"redisng": "^2.0.0",
|
||||
"telegraf": "^3.33.3",
|
||||
"telegraf-ratelimit": "^2.0.0",
|
||||
"telegraf-session-redis": "^5.1.0"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue