diff --git a/package.json b/package.json
index 4e7830d..3503435 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"lerna": "^3.14.1"
},
"scripts": {
- "db:setup": "lerna run db:setup --scope '*/*-server' --stream",
+ "db:setup": "lerna run db:setup --scope '*/*-shared' --stream",
"build": "lerna run --stream build",
"build:shared": "yarn run --scope '*/*-shared' build",
"start:app": "lerna run --scope '*/*-app' --stream start",
diff --git a/packages/server/package.json b/packages/server/package.json
index e218e25..09ff487 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -14,7 +14,7 @@
"start:dev": "yarn db:setup && nodemon --ignore ./build --exec babel-node ./src/index.js",
"knex": "npx babel-node ./node_modules/.bin/knex",
"test": "npx mocha test --recursive --exit --require @babel/register",
- "db:setup": "./scripts/db-setup.sh"
+ "db:setup": "lerna run db:setup --scope '*/*-shared' --stream"
},
"dependencies": {
"@aragon/protocol-backend-shared": "^0.2.21",
@@ -31,12 +31,7 @@
"express-session": "^1.17.0",
"helmet": "^3.21.2",
"http-status-codes": "^1.4.0",
- "jsonwebtoken": "^8.5.1",
- "knex": "^0.21.0",
"morgan": "^1.9.1",
- "objection": "^2.1.3",
- "pg": "^7.18.2",
- "pg-hstore": "^2.3.3",
"postmark": "^2.5.3",
"prom-client": "^11.5.3",
"regenerator-runtime": "^0.13.3",
diff --git a/packages/server/scripts/db-setup.sh b/packages/server/scripts/db-setup.sh
deleted file mode 100755
index 8623538..0000000
--- a/packages/server/scripts/db-setup.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-# Wait for connection before Knex migrations
-db_result=0
-while [ "${db_result}" -ne "1" ]; do
- npm run knex -- migrate:currentVersion 2>&1 | grep 'connect ECONNREFUSED' > /dev/null
- db_result=$?
- if [ "${db_result}" -eq "0" ]; then
- echo "Waiting for DB..."
- sleep 5
- fi
-done
-
-echo "Running knex database migrations..."
-npm run knex -- migrate:latest
-if [ "$?" -ne "0" ]; then
- exit 1
-fi
-
-echo "Running knex seeds..."
-npm run knex -- seed:run
-if [ "$?" -ne "0" ]; then
- exit 1
-fi
-
-echo "Database is ready!"
diff --git a/packages/server/scripts/notify-appeals-confirm.js b/packages/server/scripts/notify-appeals-confirm.js
deleted file mode 100755
index 67e175d..0000000
--- a/packages/server/scripts/notify-appeals-confirm.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Usage: npx babel-node scripts/notify-appeals-confirm
- * requires .env file / env vars with
- * DB_NAME=
- * DB_USER=
- * DB_PASS=
- * DB_PORT=
- * DB_HOST=
- * POSTMARK_SERVER_API_TOKEN=
- */
-import { User } from '../src/models/objection'
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
-import dotenv from 'dotenv'
-import { accountData } from '../../../emails/helpers'
-dotenv.config()
-
-async function main() {
- const users = await User.findWithoutDisabledNotifications()
- const emails = new Set()
- for (const user of users) {
- const { email: { email }, address } = user
- if (emails.has(email.toLowerCase())) continue
- emails.add(email.toLowerCase())
- try {
- await emailClient.sendEmailWithTemplate({
- To: email,
- From: 'notifications@protocol.aragon.org',
- TemplateAlias: 'appeals-confirm',
- TemplateModel: {
- subject: 'Aragon Court Dispute #20 and Dispute #21 have been APPEALED.',
- ...accountData(address),
- date: 'Tuesday, 8 Sep. 2020'
- },
- })
- } catch (err) {
- console.log(err.message)
- }
- console.log(`sent email to ${email} for address ${address}`)
- }
- console.log(`Total emails: ${emails.size}`)
- process.exit(0)
-}
-
-main().catch((error) => {
- console.error(error)
- process.exit(1)
-})
diff --git a/packages/server/scripts/notify-fee-mechanism-upgrade.js b/packages/server/scripts/notify-fee-mechanism-upgrade.js
deleted file mode 100755
index 13ead1e..0000000
--- a/packages/server/scripts/notify-fee-mechanism-upgrade.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Usage: npx babel-node scripts/notify-fee-mechanism-upgrade
- * requires .env file / env vars with
- * DB_NAME=
- * DB_USER=
- * DB_PASS=
- * DB_PORT=
- * DB_HOST=
- * POSTMARK_SERVER_API_TOKEN=
- */
-import { User } from '../src/models/objection'
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
-import dotenv from 'dotenv'
-import { trimMultiline } from '../../../emails/template-utils'
-dotenv.config()
-
-async function main() {
- const users = await User.findWithoutDisabledNotifications()
- const emails = new Set()
- for (const user of users) {
- const { email: { email }, address } = user
- if (emails.has(email.toLowerCase())) continue
- emails.add(email.toLowerCase())
- try {
- await emailClient.sendEmailWithTemplate({
- To: email,
- From: 'notifications@protocol.aragon.org',
- TemplateAlias: 'generic',
- TemplateModel: {
- actionLabel: 'Go to the Aragon Forum Post',
- actionUrl: 'https://forum.aragon.org/t/request-for-comment-proposal-to-adjust-the-court-subscription-fee-mechanism/2163',
- title: 'Proposal to adjust the Court Subscription Fee Mechanism',
- bannerHtml: '',
- contentHtml: `
-
- A proposal has been made to adjust the Court Subscription Fee Mechanism.
- The author is requesting comments for their proposal from Aragon community.
- You can read the proposal and leave comments on the forum post here:
-
- `,
- content: trimMultiline(`
- A proposal has been made to adjust the Court Subscription Fee Mechanism.
- The author is requesting comments for their proposal from Aragon community.
- You can read the proposal and leave comments on the forum post here:
- `),
- },
- })
- } catch (err) {
- console.log(err.message)
- }
- console.log(`sent email to ${email} for address ${address}`)
- }
- console.log(`Total emails: ${emails.size}`)
- process.exit(0)
-}
-
-main().catch((error) => {
- console.error(error)
- process.exit(1)
-})
diff --git a/packages/server/scripts/notify-unverified-anj-registrations.js b/packages/server/scripts/notify-unverified-anj-registrations.js
deleted file mode 100755
index d643b8b..0000000
--- a/packages/server/scripts/notify-unverified-anj-registrations.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Usage: npx babel-node scripts/notify-unverified-anj-registrations
- * requires .env file / env vars with
- * DB_NAME=
- * DB_USER=
- * DB_PASS=
- * DB_PORT=
- * DB_HOST=
- * POSTMARK_SERVER_API_TOKEN=
- */
-import { User } from '../src/models/objection'
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
-import dotenv from 'dotenv'
-dotenv.config()
-
-async function main() {
- const users = await User.findUnverifiedAnjRegistrations()
- const emails = new Set()
- for (const user of users) {
- const { email: { email }, address } = user
- if (emails.has(email.toLowerCase())) continue
- emails.add(email.toLowerCase())
- try {
- await emailClient.sendEmailWithTemplate({
- To: email,
- From: 'notifications@protocol.aragon.org',
- TemplateAlias: 'notification-settings-announcement',
- TemplateModel: {
- dashboardUrl: 'https://protocol.aragon.org/dashboard',
- },
- })
- } catch (err) {
- console.log(err.message)
- }
- console.log(`sent email to ${email} for address ${address}`)
- }
- console.log(`Total emails: ${emails.size}`)
- process.exit(0)
-}
-
-main().catch((error) => {
- console.error(error)
- process.exit(1)
-})
diff --git a/packages/server/src/controllers/AdminsController.js b/packages/server/src/controllers/AdminsController.js
index a0bd547..7ab5010 100644
--- a/packages/server/src/controllers/AdminsController.js
+++ b/packages/server/src/controllers/AdminsController.js
@@ -1,4 +1,4 @@
-import { Admin } from '../models/objection'
+import { Admin } from '@aragon/protocol-backend-shared/build/models/objection'
import HttpError from '../errors/http-error'
import AdminValidator from '../validators/AdminValidator'
diff --git a/packages/server/src/controllers/EmailsController.js b/packages/server/src/controllers/EmailsController.js
index 0bd4811..cef2525 100644
--- a/packages/server/src/controllers/EmailsController.js
+++ b/packages/server/src/controllers/EmailsController.js
@@ -1,6 +1,6 @@
-import { User } from '../models/objection'
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
-import sleep from '@aragon/protocol-backend-shared/helpers/sleep'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
+import emailClient from '@aragon/protocol-backend-shared/build/helpers/email-client'
+import sleep from '@aragon/protocol-backend-shared/build/helpers/sleep'
export default {
async send(req, res) {
@@ -40,7 +40,7 @@ async function sendEmails(users, TemplateModel, res) {
}
}
console.log(`Total emails: ${emails.size}`)
- await sleep(0.1) // sleep to make sure Total emails is in the next chunk
+ await sleep(100) // sleep to make sure Total emails is in the next chunk
res.write(`Total emails: ${emails.size}`)
res.end()
}
diff --git a/packages/server/src/controllers/RevealsController.js b/packages/server/src/controllers/RevealsController.js
index abec252..4c439d7 100644
--- a/packages/server/src/controllers/RevealsController.js
+++ b/packages/server/src/controllers/RevealsController.js
@@ -1,4 +1,4 @@
-import { Reveal } from '../models/objection'
+import { Reveal } from '@aragon/protocol-backend-shared/build/models/objection'
import HttpError from '../errors/http-error'
import RevealsValidator from '../validators/RevealsValidator'
import { decodeVoteId } from '@aragon/protocol-backend-shared/helpers/voting'
diff --git a/packages/server/src/controllers/UserEmailController.js b/packages/server/src/controllers/UserEmailController.js
index fe66975..5e7682b 100644
--- a/packages/server/src/controllers/UserEmailController.js
+++ b/packages/server/src/controllers/UserEmailController.js
@@ -1,7 +1,7 @@
import HttpError from '../errors/http-error'
import UsersValidator from '../validators/UsersValidator'
import UserEmailVerificationTokenValidator from '../validators/UserEmailVerificationTokenValidator'
-import { User } from '../models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
export default {
async get(req, res) {
diff --git a/packages/server/src/controllers/UserNotificationsController.js b/packages/server/src/controllers/UserNotificationsController.js
index 10c1c9d..c012b2e 100644
--- a/packages/server/src/controllers/UserNotificationsController.js
+++ b/packages/server/src/controllers/UserNotificationsController.js
@@ -1,5 +1,5 @@
import HttpError from '../errors/http-error'
-import { User } from '../models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
export default {
async set(req, res) {
diff --git a/packages/server/src/controllers/UserSessionsController.js b/packages/server/src/controllers/UserSessionsController.js
index ff8a59b..94c7be8 100644
--- a/packages/server/src/controllers/UserSessionsController.js
+++ b/packages/server/src/controllers/UserSessionsController.js
@@ -1,6 +1,6 @@
import HttpError from '../errors/http-error'
import UserSessionsValidator from '../validators/UserSessionsValidator'
-import { User } from '../models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
export default {
async create(req, res) {
diff --git a/packages/server/src/controllers/UsersController.js b/packages/server/src/controllers/UsersController.js
index 59a1c3d..7a6df0d 100644
--- a/packages/server/src/controllers/UsersController.js
+++ b/packages/server/src/controllers/UsersController.js
@@ -1,6 +1,6 @@
import HttpError from '../errors/http-error'
import UsersValidator from '../validators/UsersValidator'
-import { User, UserEmail } from '../models/objection'
+import { User, UserEmail } from '@aragon/protocol-backend-shared/build/models/objection'
export default {
async details(req, res) {
diff --git a/packages/server/src/database/migrations/20200425004131_create-emails.js b/packages/server/src/database/migrations/20200425004131_create-emails.js
deleted file mode 100644
index 5161a85..0000000
--- a/packages/server/src/database/migrations/20200425004131_create-emails.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export function up(knex) {
- return knex.schema.hasTable('Users').then(function(sequelizeExists) {
- if (sequelizeExists) {
- return knex.schema.renameTable('Users', 'UserEmails').alterTable('UserEmails', function (table) {
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable().alter()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable().alter()
- })
- } else {
- return knex.schema.createTable('UserEmails', function (table) {
- table.increments('id')
- table.string('email').unique().notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
- })
- }
- })
-}
-
-export function down(knex) {
- return knex.schema.dropTable('UserEmails')
-}
diff --git a/packages/server/src/database/migrations/20200425004137_create-users.js b/packages/server/src/database/migrations/20200425004137_create-users.js
deleted file mode 100644
index 11f3b9b..0000000
--- a/packages/server/src/database/migrations/20200425004137_create-users.js
+++ /dev/null
@@ -1,31 +0,0 @@
-export function up(knex) {
- return knex.schema.hasTable('UserAddresses').then(function(sequelizeExists) {
- if (sequelizeExists) {
- return knex.schema.renameTable('UserAddresses', 'Users').alterTable('Users', function (table) {
- table.boolean('addressVerified').defaultTo(false).notNullable()
- table.renameColumn('userId', 'userEmailId')
- table.index('userEmailId')
- table.dropForeign('userEmailId', 'UserAddresses_userId_fkey') // need to recreate constraint with set null on delete
- table.foreign('userEmailId').references('UserEmails.id').onDelete('SET NULL')
- table.boolean('emailVerified').defaultTo(false).notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable().alter()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable().alter()
- })
- } else {
- return knex.schema.createTable('Users', function (table) {
- table.increments('id')
- table.string('address').unique().notNullable()
- table.boolean('addressVerified').defaultTo(false).notNullable()
- table.integer('userEmailId').index()
- table.foreign('userEmailId').references('UserEmails.id').onDelete('SET NULL')
- table.boolean('emailVerified').defaultTo(false).notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
- })
- }
- })
-}
-
-export function down(knex) {
- return knex.schema.dropTable('Users')
-}
diff --git a/packages/server/src/database/migrations/20200425004140_create-admins.js b/packages/server/src/database/migrations/20200425004140_create-admins.js
deleted file mode 100644
index 295dc08..0000000
--- a/packages/server/src/database/migrations/20200425004140_create-admins.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export function up(knex) {
- return knex.schema.hasTable('Admins').then(function(sequelizeExists) {
- if (sequelizeExists) {
- return knex.schema.alterTable('Admins', function (table) {
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable().alter()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable().alter()
- })
- } else {
- return knex.schema.createTable('Admins', function (table) {
- table.increments('id')
- table.string('email').unique().notNullable()
- table.string('password').notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
- })
- }
- })
-}
-
-export function down(knex) {
- return knex.schema.dropTable('Admins')
-}
diff --git a/packages/server/src/database/migrations/20200428185153_create-reveals.js b/packages/server/src/database/migrations/20200428185153_create-reveals.js
deleted file mode 100644
index 8f6a800..0000000
--- a/packages/server/src/database/migrations/20200428185153_create-reveals.js
+++ /dev/null
@@ -1,29 +0,0 @@
-export function up(knex) {
- return knex.schema.hasTable('Reveals').then(function(sequelizeExists) {
- if (sequelizeExists) {
- return knex.schema.alterTable('Reveals', function (table) {
- table.boolean('revealed').defaultTo(false).notNullable().alter()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable().alter()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable().alter()
- })
- } else {
- return knex.schema.createTable('Reveals', function (table) {
- table.increments('id')
- table.string('voteId').notNullable()
- table.string('guardian').notNullable()
- table.unique(['guardian', 'voteId'])
- table.string('disputeId').notNullable()
- table.integer('roundNumber').notNullable()
- table.integer('outcome').notNullable()
- table.string('salt').notNullable()
- table.boolean('revealed').defaultTo(false).notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
- })
- }
- })
-}
-
-export function down(knex) {
- return knex.schema.dropTable('Reveals')
-}
diff --git a/packages/server/src/database/migrations/20200504162940_create-keeper-suspicious-transactions.js b/packages/server/src/database/migrations/20200504162940_create-keeper-suspicious-transactions.js
deleted file mode 100644
index 77e1e2b..0000000
--- a/packages/server/src/database/migrations/20200504162940_create-keeper-suspicious-transactions.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export function up(knex) {
- return knex.schema.hasTable('KeeperSuspiciousTransactions').then(function(sequelizeExists) {
- if (sequelizeExists) {
- return knex.schema.alterTable('KeeperSuspiciousTransactions', function (table) {
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable().alter()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable().alter()
- })
- } else {
- return knex.schema.createTable('KeeperSuspiciousTransactions', function (table) {
- table.increments('id')
- table.string('blockNumber').unique().notNullable()
- table.string('txHash').unique().nullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
- })
- }
- })
-}
-
-export function down(knex) {
- return knex.schema.dropTable('KeeperSuspiciousTransactions')
-}
diff --git a/packages/server/src/database/migrations/20200509004243_create-notification-types.js b/packages/server/src/database/migrations/20200509004243_create-notification-types.js
deleted file mode 100644
index de82292..0000000
--- a/packages/server/src/database/migrations/20200509004243_create-notification-types.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export function up(knex) {
- return knex.schema.createTable('UserNotificationTypes', function (table) {
- table.increments('id')
- table.string('model').unique().notNullable()
- table.datetime('scannedAt').index()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
- })
-}
-
-export function down(knex) {
- return knex.schema.dropTable('UserNotificationTypes')
-}
diff --git a/packages/server/src/database/migrations/20200605140156_add-reveals-tries.js b/packages/server/src/database/migrations/20200605140156_add-reveals-tries.js
deleted file mode 100644
index 8cf9cb9..0000000
--- a/packages/server/src/database/migrations/20200605140156_add-reveals-tries.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export function up(knex) {
- return knex.schema.alterTable('Reveals', function (table) {
- table.integer('failedAttempts').notNullable().defaultTo(0)
- })
-}
-
-export function down(knex) {
- return knex.schema.alterTable('Reveals', function (table) {
- table.dropColumn('failedAttempts')
- })
-}
diff --git a/packages/server/src/database/migrations/20200903114032_add-reveals-expired.js b/packages/server/src/database/migrations/20200903114032_add-reveals-expired.js
deleted file mode 100644
index 16d4c0e..0000000
--- a/packages/server/src/database/migrations/20200903114032_add-reveals-expired.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export function up(knex) {
- return knex.schema.alterTable('Reveals', function (table) {
- table.boolean('expired').notNullable().defaultTo(false)
- })
-}
-
-export function down(knex) {
- return knex.schema.alterTable('Reveals', function (table) {
- table.dropColumn('expired')
- })
-}
diff --git a/packages/server/src/helpers/session-middleware.js b/packages/server/src/helpers/session-middleware.js
index 294e578..150d2a1 100644
--- a/packages/server/src/helpers/session-middleware.js
+++ b/packages/server/src/helpers/session-middleware.js
@@ -1,5 +1,5 @@
import expressSession from 'express-session'
-import { Session } from '../models/objection'
+import { Session } from '@aragon/protocol-backend-shared/build/models/objection'
import { HOURS, DAYS } from '@aragon/protocol-backend-shared/build/helpers/times'
const SESSION_MAXAGE = 30 * DAYS
diff --git a/packages/server/src/helpers/token-manager.js b/packages/server/src/helpers/token-manager.js
deleted file mode 100644
index 7f6319b..0000000
--- a/packages/server/src/helpers/token-manager.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import jwt from 'jsonwebtoken'
-
-const { env: {
- EMAIL_JWT_PRIVATE_KEY,
-}} = process
-
-function generateToken(expiresIn = '24h') {
- const payload = { timestamp: Date.now() }
- return jwt.sign(payload, EMAIL_JWT_PRIVATE_KEY, { expiresIn })
-}
-
-function isTokenValid(token) {
- try {
- jwt.verify(token, EMAIL_JWT_PRIVATE_KEY)
- return true
- } catch {
- return false
- }
-}
-
-export { generateToken, isTokenValid }
diff --git a/packages/server/src/models/objection/Admin.js b/packages/server/src/models/objection/Admin.js
deleted file mode 100644
index e5551a7..0000000
--- a/packages/server/src/models/objection/Admin.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import bcrypt from 'bcryptjs'
-import BaseModel from './BaseModel'
-
-export default class Admin extends BaseModel {
- static get tableName() {
- return 'Admins'
- }
-
- static get relationMappings() {
- return {
- sessions: {
- relation: BaseModel.HasManyRelation,
- modelClass: 'Session',
- join: {
- from: 'Admins.id',
- to: 'Sessions.adminId'
- }
- }
- }
- }
-
- static async countByEmail(email) {
- return this.query().where({ email }).count()
- }
-
- static async findByEmail(email) {
- return this.findOne({ email })
- }
-
- static async findAllEmails() {
- const admins = await this.query().select('email')
- return admins.map(admin => admin.email)
- }
-
- hasPassword(password) {
- return bcrypt.compareSync(password, this.password)
- }
-
- hashPassword() {
- this.password = bcrypt.hashSync(this.password)
- }
-
- async $beforeInsert(queryContext) {
- await super.$beforeInsert(queryContext)
- this.hashPassword()
- }
-
- async $beforeUpdate(opt, queryContext) {
- await super.$beforeUpdate(opt, queryContext)
- this.hashPassword()
- }
-}
diff --git a/packages/server/src/models/objection/BaseModel.js b/packages/server/src/models/objection/BaseModel.js
deleted file mode 100644
index 06ea81d..0000000
--- a/packages/server/src/models/objection/BaseModel.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { Model } from 'objection'
-import Knex from 'knex'
-
-import config from '../../database/config'
-Model.knex(Knex(config))
-
-export default class BaseModel extends Model {
- // modelPaths is used to allow modelClass relations be defined as a string to avoid require loops
- // https://vincit.github.io/objection.js/guide/relations.html#require-loops
- static get modelPaths() {
- return [__dirname];
- }
- // every child model should have updatedAt datetime field
- $beforeUpdate() {
- this.updatedAt = new Date().toISOString()
- }
-
-
- // static query methods (table level)
-
- static async exists(args) {
- return !!(await this.findOne(args))
- }
-
- static count(args) {
- return this.query().where(args).resultSize()
- }
-
- static findById(id) {
- return this.query().findById(id)
- }
-
- static findOne(args) {
- return this.query().findOne(args)
- }
-
- static async findOrInsert(args) {
- let row = await this.findOne(args)
- if (!row) row = await this.create(args)
- return row
- }
-
- static create(args = {}) {
- return this.query().insert(args)
- }
-
-
- // instance query methods (row level)
-
- async relatedUpdateOrInsert(relation, args) {
- const row = await this.$relatedQuery(relation)
- if (row) {
- await this.$relatedQuery(relation).update(args)
- } else {
- await this.$relatedQuery(relation).insert(args)
- }
- }
-
- get createdAtDateString() {
- return this.createdAt.toLocaleDateString('en-US', {dateStyle: 'full'}) // format: Tuesday, May 19, 2020
- }
-}
diff --git a/packages/server/src/models/objection/Reveal.js b/packages/server/src/models/objection/Reveal.js
deleted file mode 100644
index e10426e..0000000
--- a/packages/server/src/models/objection/Reveal.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import BaseModel from './BaseModel'
-
-export default class Reveal extends BaseModel {
- static get tableName() {
- return 'Reveals'
- }
-
- static async create(params = {}) {
- return this.query().insert(params)
- }
-}
diff --git a/packages/server/src/models/objection/index.js b/packages/server/src/models/objection/index.js
deleted file mode 100644
index 902f22a..0000000
--- a/packages/server/src/models/objection/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import Admin from './Admin'
-import KeeperSuspiciousTransaction from './KeeperSuspiciousTransaction'
-import Reveal from './Reveal'
-import Session from './Session'
-import UserEmail from './UserEmail'
-import UserEmailVerificationToken from './UserEmailVerificationToken'
-import UserNotificationSetting from './UserNotificationSetting'
-import UserNotification from './UserNotification'
-import UserNotificationType from './UserNotificationType'
-import User from './User'
-
-export {
- Admin,
- KeeperSuspiciousTransaction,
- Reveal,
- Session,
- UserEmail,
- UserEmailVerificationToken,
- UserNotificationSetting,
- UserNotification,
- UserNotificationType,
- User,
-}
diff --git a/packages/server/src/routes/authenticate-admin.js b/packages/server/src/routes/authenticate-admin.js
index de9e7a7..a668f58 100644
--- a/packages/server/src/routes/authenticate-admin.js
+++ b/packages/server/src/routes/authenticate-admin.js
@@ -1,4 +1,4 @@
-import { Admin } from '../models/objection'
+import { Admin } from '@aragon/protocol-backend-shared/build/models/objection'
import HttpError from '../errors/http-error'
import asyncMiddleware from '../helpers/async-middleware'
diff --git a/packages/server/src/routes/authenticate-user.js b/packages/server/src/routes/authenticate-user.js
index f5a7139..3187037 100644
--- a/packages/server/src/routes/authenticate-user.js
+++ b/packages/server/src/routes/authenticate-user.js
@@ -1,6 +1,6 @@
import HttpError from '../errors/http-error'
import asyncMiddleware from '../helpers/async-middleware'
-import { User } from '../models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
const authenticate = (route) => async (req, res, next) => {
const { session: { userId }, params: { address } } = req
diff --git a/packages/server/src/validators/AdminValidator.js b/packages/server/src/validators/AdminValidator.js
index 6f35a0c..3905030 100644
--- a/packages/server/src/validators/AdminValidator.js
+++ b/packages/server/src/validators/AdminValidator.js
@@ -1,4 +1,4 @@
-import { Admin } from '../models/objection'
+import { Admin } from '@aragon/protocol-backend-shared/build/models/objection'
import BaseValidator from './BaseValidator'
class AdminValidator extends BaseValidator {
diff --git a/packages/server/src/validators/RevealsValidator.js b/packages/server/src/validators/RevealsValidator.js
index fa169c7..837739a 100644
--- a/packages/server/src/validators/RevealsValidator.js
+++ b/packages/server/src/validators/RevealsValidator.js
@@ -1,4 +1,4 @@
-import { Reveal } from '../models/objection'
+import { Reveal } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '../web3/Network'
import BaseValidator from './BaseValidator'
const { hashVote } = require('@aragon/protocol-backend-shared/helpers/voting')
diff --git a/packages/server/src/validators/UserEmailVerificationTokenValidator.js b/packages/server/src/validators/UserEmailVerificationTokenValidator.js
index 4ca1e6e..61a9352 100644
--- a/packages/server/src/validators/UserEmailVerificationTokenValidator.js
+++ b/packages/server/src/validators/UserEmailVerificationTokenValidator.js
@@ -1,6 +1,6 @@
import BaseValidator from './BaseValidator'
-import { User } from '../models/objection'
-import { isTokenValid } from '../helpers/token-manager'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
+import { isTokenValid } from '@aragon/protocol-backend-shared/build/helpers/jwt-manager'
class UserEmailVerificationTokenValidator extends BaseValidator {
async validateForVerify({ address, token }) {
diff --git a/packages/server/src/validators/UsersValidator.js b/packages/server/src/validators/UsersValidator.js
index 0f16f52..90f0826 100644
--- a/packages/server/src/validators/UsersValidator.js
+++ b/packages/server/src/validators/UsersValidator.js
@@ -1,7 +1,7 @@
import validator from 'validator'
import BaseValidator from './BaseValidator'
-import { User } from '../models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
class UsersValidator extends BaseValidator {
async validateForCreate({ address, email }) {
diff --git a/packages/server/test/helpers/dbCleanup.js b/packages/server/test/helpers/dbCleanup.js
index eabe8d2..f40dd76 100644
--- a/packages/server/test/helpers/dbCleanup.js
+++ b/packages/server/test/helpers/dbCleanup.js
@@ -1,4 +1,4 @@
-import { User } from '../../src/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
export default async function dbCleanup(address) {
const user = await User.findOne({address})
diff --git a/packages/server/test/integration/user-client-interaction.js b/packages/server/test/integration/user-client-interaction.js
index 714864d..f0fef92 100644
--- a/packages/server/test/integration/user-client-interaction.js
+++ b/packages/server/test/integration/user-client-interaction.js
@@ -4,7 +4,7 @@ import HttpStatus from 'http-status-codes'
import { ethers } from 'ethers'
import app from '../../src/app'
-import { User } from '../../src/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import dbCleanup from '../helpers/dbCleanup'
const serverPort = process.env.SERVER_PORT || 8000
const { expect } = chai
diff --git a/packages/services/bin/worker.js b/packages/services/bin/worker.js
index c3c2f10..fbe5481 100644
--- a/packages/services/bin/worker.js
+++ b/packages/services/bin/worker.js
@@ -4,7 +4,7 @@ import path from 'path'
import Logger from '../src/helpers/worker-logger'
import MetricsReporter from '../src/helpers/metrics-reporter'
import errorHandler from '../src/helpers/error-handler'
-import sleep from '@aragon/protocol-backend-shared/helpers/sleep'
+import sleep from '@aragon/protocol-backend-shared/build/helpers/sleep'
let [workerPath, name, times, repeat, color, metricsPort] = process.argv.slice(2)
if (!workerPath) throw Error('Cannot start worker with missing path')
@@ -36,7 +36,7 @@ async function run() {
metrics.workerError()
logger.error(`Job #${job} exited with an error`, error)
}
- await sleep(repeat)
+ await sleep(repeat * 1000)
}
logger.success(`Worker finished`)
}
diff --git a/packages/services/package.json b/packages/services/package.json
index acf78b8..d699296 100644
--- a/packages/services/package.json
+++ b/packages/services/package.json
@@ -10,7 +10,8 @@
"build:server": "yarn workspace @aragon/protocol-backend-server build",
"start": "npm run build:server && babel-node ./bin/main.js",
"start:dev": "npm run build:server && nodemon --ignore ./build --exec babel-node ./bin/main.js",
- "test": "npx mocha test --recursive --exit --require @babel/register"
+ "test": "npx mocha test --recursive --exit --require @babel/register",
+ "db:setup": "lerna run db:setup --scope '*/*-shared' --stream"
},
"dependencies": {
"@aragon/protocol-backend-server": "^0.2.21",
diff --git a/packages/services/src/models/notification-scanners/SubscriptionReminder.js b/packages/services/src/models/notification-scanners/SubscriptionReminder.js
index dd25122..5489f2e 100644
--- a/packages/services/src/models/notification-scanners/SubscriptionReminder.js
+++ b/packages/services/src/models/notification-scanners/SubscriptionReminder.js
@@ -1,5 +1,5 @@
import NotificationScannerBaseModel from './NotificationScannerBaseModel'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
class SubscriptionReminder extends NotificationScannerBaseModel {
async scan() {
diff --git a/packages/services/src/workers/heartbeat.js b/packages/services/src/workers/heartbeat.js
index 87c8f0e..383927a 100644
--- a/packages/services/src/workers/heartbeat.js
+++ b/packages/services/src/workers/heartbeat.js
@@ -1,4 +1,4 @@
-import sleep from '@aragon/protocol-backend-shared/helpers/sleep'
+import sleep from '@aragon/protocol-backend-shared/build/helpers/sleep'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
const HEARTBEAT_TRIES_PER_JOB = 3
@@ -19,7 +19,7 @@ async function heartbeat(logger, protocol, attempt = 1) {
} catch (error) {
logger.error('Failed to transition terms with error', error)
if (attempt >= HEARTBEAT_TRIES_PER_JOB) return
- await sleep(SECONDS_BETWEEN_INTENTS)
+ await sleep(SECONDS_BETWEEN_INTENTS * 1000)
await heartbeat(logger, protocol, attempt + 1)
}
}
diff --git a/packages/services/src/workers/monitor-keeper.js b/packages/services/src/workers/monitor-keeper.js
index a7bd7fb..ecb5364 100644
--- a/packages/services/src/workers/monitor-keeper.js
+++ b/packages/services/src/workers/monitor-keeper.js
@@ -1,7 +1,7 @@
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
+import emailClient from '@aragon/protocol-backend-shared/build/helpers/email-client'
import Etherscan from '../models/Etherscan'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
-import { Admin, KeeperSuspiciousTransaction } from '@aragon/protocol-backend-server/build/models/objection'
+import { Admin, KeeperSuspiciousTransaction } from '@aragon/protocol-backend-shared/build/models/objection'
import { fromWei } from 'web3-utils'
import { bigExp } from '@aragon/protocol-backend-shared/helpers/numbers'
diff --git a/packages/services/src/workers/notification-scanner.js b/packages/services/src/workers/notification-scanner.js
index 68d5ba9..6bd441c 100644
--- a/packages/services/src/workers/notification-scanner.js
+++ b/packages/services/src/workers/notification-scanner.js
@@ -1,4 +1,4 @@
-import { User, UserNotification, UserNotificationType } from '@aragon/protocol-backend-server/build/models/objection'
+import { User, UserNotification, UserNotificationType } from '@aragon/protocol-backend-shared/build/models/objection'
import * as notificationScanners from '../models/notification-scanners'
/**
diff --git a/packages/services/src/workers/notification-sender.js b/packages/services/src/workers/notification-sender.js
index 7d87637..f39789c 100644
--- a/packages/services/src/workers/notification-sender.js
+++ b/packages/services/src/workers/notification-sender.js
@@ -1,5 +1,5 @@
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
-import { UserNotification } from '@aragon/protocol-backend-server/build/models/objection'
+import emailClient from '@aragon/protocol-backend-shared/build/helpers/email-client'
+import { UserNotification } from '@aragon/protocol-backend-shared/build/models/objection'
import * as notificationScanners from '../models/notification-scanners'
import { accountData } from '../../../../emails/helpers'
diff --git a/packages/services/src/workers/reveal.js b/packages/services/src/workers/reveal.js
index 6564c36..5ad7921 100644
--- a/packages/services/src/workers/reveal.js
+++ b/packages/services/src/workers/reveal.js
@@ -1,4 +1,4 @@
-import { Reveal } from '@aragon/protocol-backend-server/build/models/objection'
+import { Reveal } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
const REVEAL_TRIES = 3
diff --git a/packages/services/test/helpers/dbCleanup.js b/packages/services/test/helpers/dbCleanup.js
index 9ce9976..3745395 100644
--- a/packages/services/test/helpers/dbCleanup.js
+++ b/packages/services/test/helpers/dbCleanup.js
@@ -1,4 +1,4 @@
-import { User, UserEmail, UserNotificationType } from '@aragon/protocol-backend-server/build/models/objection'
+import { User, UserEmail, UserNotificationType } from '@aragon/protocol-backend-shared/build/models/objection'
export async function userDbCleanup(address, email) {
await UserEmail.findOne({email}).del()
diff --git a/packages/services/test/helpers/userNotificationTypeByModel.js b/packages/services/test/helpers/userNotificationTypeByModel.js
index 34aac37..b83d0e6 100644
--- a/packages/services/test/helpers/userNotificationTypeByModel.js
+++ b/packages/services/test/helpers/userNotificationTypeByModel.js
@@ -1,4 +1,4 @@
-import { UserNotificationType } from '@aragon/protocol-backend-server/build/models/objection'
+import { UserNotificationType } from '@aragon/protocol-backend-shared/build/models/objection'
export default function userNotificationTypeByModel(model) {
return UserNotificationType.findOne({model}).withGraphFetched('notifications')
diff --git a/packages/services/test/integration/notification-scanners/AppealsOpened.js b/packages/services/test/integration/notification-scanners/AppealsOpened.js
index a0e0407..03c2398 100644
--- a/packages/services/test/integration/notification-scanners/AppealsOpened.js
+++ b/packages/services/test/integration/notification-scanners/AppealsOpened.js
@@ -7,7 +7,7 @@ chai.use(sinonChai)
import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCleanup'
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
import * as termIdGetter from '../../../src/helpers/term-id-getter'
diff --git a/packages/services/test/integration/notification-scanners/DisputeRuled.js b/packages/services/test/integration/notification-scanners/DisputeRuled.js
index 73ecb4e..dda8cae 100644
--- a/packages/services/test/integration/notification-scanners/DisputeRuled.js
+++ b/packages/services/test/integration/notification-scanners/DisputeRuled.js
@@ -7,7 +7,7 @@ chai.use(sinonChai)
import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCleanup'
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
const { env: { CLIENT_URL } } = process
diff --git a/packages/services/test/integration/notification-scanners/DueTasks.js b/packages/services/test/integration/notification-scanners/DueTasks.js
index d58cf8a..bd656fd 100644
--- a/packages/services/test/integration/notification-scanners/DueTasks.js
+++ b/packages/services/test/integration/notification-scanners/DueTasks.js
@@ -7,7 +7,7 @@ chai.use(sinonChai)
import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCleanup'
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
import * as termIdGetter from '../../../src/helpers/term-id-getter'
diff --git a/packages/services/test/integration/notification-scanners/JurorDrafted.js b/packages/services/test/integration/notification-scanners/JurorDrafted.js
index fcf9b1c..492e9fb 100644
--- a/packages/services/test/integration/notification-scanners/JurorDrafted.js
+++ b/packages/services/test/integration/notification-scanners/JurorDrafted.js
@@ -7,7 +7,7 @@ chai.use(sinonChai)
import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCleanup'
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
const { env: { CLIENT_URL } } = process
diff --git a/packages/services/test/integration/notification-scanners/MissedReveal.js b/packages/services/test/integration/notification-scanners/MissedReveal.js
index 20700f5..c233692 100644
--- a/packages/services/test/integration/notification-scanners/MissedReveal.js
+++ b/packages/services/test/integration/notification-scanners/MissedReveal.js
@@ -7,7 +7,7 @@ chai.use(sinonChai)
import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCleanup'
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
import * as termIdGetter from '../../../src/helpers/term-id-getter'
diff --git a/packages/services/test/integration/notification-scanners/MissedVote.js b/packages/services/test/integration/notification-scanners/MissedVote.js
index 3b7f7b5..29b847e 100644
--- a/packages/services/test/integration/notification-scanners/MissedVote.js
+++ b/packages/services/test/integration/notification-scanners/MissedVote.js
@@ -7,7 +7,7 @@ chai.use(sinonChai)
import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCleanup'
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
-import { User } from '@aragon/protocol-backend-server/build/models/objection'
+import { User } from '@aragon/protocol-backend-shared/build/models/objection'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
import * as termIdGetter from '../../../src/helpers/term-id-getter'
diff --git a/packages/services/test/integration/notification-scanners/SubscriptionReminder.js b/packages/services/test/integration/notification-scanners/SubscriptionReminder.js
index 4836aae..338dbc9 100644
--- a/packages/services/test/integration/notification-scanners/SubscriptionReminder.js
+++ b/packages/services/test/integration/notification-scanners/SubscriptionReminder.js
@@ -8,7 +8,7 @@ import { userDbCleanup, userNotificationTypeDbCleanup } from '../../helpers/dbCl
import userNotificationTypeByModel from '../../helpers/userNotificationTypeByModel'
import { tryRunScanner } from '../../../src/workers/notification-scanner'
import { trySendNotification } from '../../../src/workers/notification-sender'
-import { User, UserEmail, UserNotification } from '@aragon/protocol-backend-server/build/models/objection'
+import { User, UserEmail, UserNotification } from '@aragon/protocol-backend-shared/build/models/objection'
const { env: { CLIENT_URL } } = process
const notificationTypeModel = 'SubscriptionReminder'
@@ -117,7 +117,7 @@ describe('SubscriptionReminder notifications', () => {
await type.$query().update({scannedAt: null})
await tryRunScanner(ctx, notificationTypeModel)
const newType = await userNotificationTypeByModel(notificationTypeModel)
- expect(type.notifications).to.deep.equal(newType.notifications)
+ expect(type.notifications[0].updatedAt).to.deep.equal(newType.notifications[0].updatedAt)
})
it('should send single notification', async () => {
diff --git a/packages/services/test/src/workers/reveal.js b/packages/services/test/src/workers/reveal.js
index d4651cc..3061a97 100644
--- a/packages/services/test/src/workers/reveal.js
+++ b/packages/services/test/src/workers/reveal.js
@@ -3,7 +3,7 @@ import sinon from 'sinon'
import sinonChai from 'sinon-chai'
import revealWorker from '../../../src/workers/reveal'
import Network from '@aragon/protocol-backend-server/build/web3/Network'
-import { Reveal } from '@aragon/protocol-backend-server/build/models/objection'
+import { Reveal } from '@aragon/protocol-backend-shared/build/models/objection'
const { expect } = chai
chai.use(sinonChai)
diff --git a/packages/shared/README.md b/packages/shared/README.md
index 19a07a8..89f8566 100644
--- a/packages/shared/README.md
+++ b/packages/shared/README.md
@@ -26,12 +26,13 @@ The first one is only used by the back-office frontend app where all the compone
### Helpers
It provides the following helper functions:
-- [`email-client`](./helpers/email-client.js): Handles sending emails through Postmark
+- [`email-client`](./src/helpers/email-client.ts): Handles sending emails through Postmark
+- [`jwt-manager`](./src/helpers/jwt-manager.ts): For creating and validating JWTs in email verification
- [`gas-price-oracle`](./helpers/gas-price-oracle.js): Get gas price oracle object used to know the current gas prices being paid on each network
- [`get-wallet-from-pk`](./helpers/get-wallet-from-pk.js): Decode Ethereum address based on a private key
- [`logger`](./helpers/logger.js): Logger object that provides a friendly interface for fancy logging
- [`numbers`](./helpers/numbers.js): BigNumber-related helper functions
-- [`sleep`](./helpers/sleep.js): Sleep function to wait a number of seconds
+- [`sleep`](./src/helpers/sleep.ts): Sleep function to wait a number of seconds
- [`times`](./helpers/times.ts): Time constants for using with `Date()`
- [`voting`](./helpers/voting.js): Utils related to the CR Voting module of Aragon Protocol
@@ -45,3 +46,8 @@ yarn build
# from another package:
yarn build:shared
```
+
+Shared Typescript packages need to be imported from the `build` directory, e.g.:
+```js
+import sleep from '@aragon/protocol-backend-shared/build/helpers/sleep'
+```
diff --git a/packages/shared/helpers/email-client.js b/packages/shared/helpers/email-client.js
deleted file mode 100644
index 8709362..0000000
--- a/packages/shared/helpers/email-client.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const { ServerClient } = require('postmark')
-
-const { env: {
- CLIENT_URL,
- EMAIL_FROM_DEFAULT,
- POSTMARK_SERVER_API_TOKEN,
- POSTMARK_TEMPLATE_ALIAS_VERIFY,
-}} = process
-const postmarkClient = new ServerClient(POSTMARK_SERVER_API_TOKEN)
-
-class EmailClient {
- async sendMagicLink({ email, address, token }) {
- const verifyEmailUrl = `${CLIENT_URL}?preferences=notifications&address=${address}&token=${token}`
- const message = {
- To: email,
- TemplateAlias: POSTMARK_TEMPLATE_ALIAS_VERIFY,
- TemplateModel: { verifyEmailUrl },
- }
- await this.sendEmailWithTemplate(message)
- }
-
- async sendEmail(message) {
- message = this._sanitizeMessage(message)
- await postmarkClient.sendEmail(message)
- }
-
- async sendEmailWithTemplate(message) {
- message = this._sanitizeMessage(message)
- // simply check postmark endpoint when testing.
- // there is no way to run template test as of 2020-05-04:
- // https://github.com/wildbit/postmark.js/issues/56
- if (POSTMARK_SERVER_API_TOKEN == 'POSTMARK_API_TEST') {
- message.TextBody = 'test'
- delete message.TemplateAlias
- delete message.TemplateModel
- return await this.sendEmail(message)
- }
- await postmarkClient.sendEmailWithTemplate(message)
- }
-
- _sanitizeMessage(message) {
- message.From = this._sanitizeFrom(message.From)
- message.To = this._sanitizeTo(message.To)
- return message
- }
-
- _sanitizeFrom(From) {
- return From || EMAIL_FROM_DEFAULT
- }
-
- _sanitizeTo(To) {
- return Array.isArray(To) ? To.join(', ') : To
- }
-}
-
-module.exports = new EmailClient()
diff --git a/packages/shared/helpers/sleep.js b/packages/shared/helpers/sleep.js
deleted file mode 100644
index d2c2443..0000000
--- a/packages/shared/helpers/sleep.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = async function (seconds) {
- return new Promise(resolve => setTimeout(resolve, seconds * 1000))
-}
diff --git a/packages/server/knexfile.js b/packages/shared/knexfile.ts
similarity index 100%
rename from packages/server/knexfile.js
rename to packages/shared/knexfile.ts
diff --git a/packages/shared/models/environments/BrowserEnvironment.js b/packages/shared/models/environments/BrowserEnvironment.js
index 2da84ad..8f2e55c 100644
--- a/packages/shared/models/environments/BrowserEnvironment.js
+++ b/packages/shared/models/environments/BrowserEnvironment.js
@@ -1,5 +1,5 @@
const { ethers } = require('ethers')
-const sleep = require('../../helpers/sleep')
+const sleep = require('../../build/helpers/sleep')
const Environment = require('./Environment')
const JsonRpcSigner = require('../providers/JsonRpcSigner')
const StaticArtifacts = require('../artifacts/StaticArtifacts')
@@ -10,7 +10,7 @@ class BrowserEnvironment extends Environment {
}
async isEnabled() {
- await sleep(2)
+ await sleep(2000)
const { web3 } = window
return !!(web3 && web3.currentProvider && web3.currentProvider.selectedAddress)
}
diff --git a/packages/shared/package.json b/packages/shared/package.json
index 58a9f28..b2a696a 100644
--- a/packages/shared/package.json
+++ b/packages/shared/package.json
@@ -10,7 +10,8 @@
"build:types": "tsc",
"build:js": "babel ./src --out-dir ./build --extensions .ts",
"build:clean": "yarn clean && yarn build",
- "clean": "rm -rf ./build"
+ "clean": "rm -rf ./build",
+ "db:setup": "babel-node --extensions .ts src/scripts/db-setup"
},
"dependencies": {
"@aragon/contract-helpers-test": "^0.1.0",
@@ -23,6 +24,10 @@
"dotenv": "^8.2.0",
"ethers": "^4.0.46",
"graphql-request": "^1.8.2",
+ "jsonwebtoken": "^8.5.1",
+ "knex": "^0.21.12",
+ "objection": "^2.2.3",
+ "pg": "^8.4.2",
"postmark": "^2.5.3",
"web3-utils": "^1.2.4"
},
@@ -31,6 +36,8 @@
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"@babel/preset-typescript": "^7.12.1",
+ "@types/bcryptjs": "^2.4.2",
+ "@types/jsonwebtoken": "^8.5.0",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"eslint": "^7.12.1",
diff --git a/packages/server/src/database/config.js b/packages/shared/src/database/config.ts
similarity index 83%
rename from packages/server/src/database/config.js
rename to packages/shared/src/database/config.ts
index 499eae6..9ac62c3 100644
--- a/packages/server/src/database/config.js
+++ b/packages/shared/src/database/config.ts
@@ -1,13 +1,14 @@
import path from 'path'
import dotenv from 'dotenv'
+import { Config } from 'knex'
dotenv.config()
-const config = {
+const config: Config = {
client: 'pg',
connection: {
host: process.env.DB_HOST,
- port: process.env.DB_PORT,
+ port: Number(process.env.DB_PORT),
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
diff --git a/packages/shared/src/database/migrations/20200425004131_create-emails.ts b/packages/shared/src/database/migrations/20200425004131_create-emails.ts
new file mode 100644
index 0000000..8391a41
--- /dev/null
+++ b/packages/shared/src/database/migrations/20200425004131_create-emails.ts
@@ -0,0 +1,14 @@
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('UserEmails', function (table) {
+ table.increments('id')
+ table.string('email').unique().notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ })
+}
+
+export function down(knex: Knex): Promise {
+ return knex.schema.dropTable('UserEmails')
+}
diff --git a/packages/shared/src/database/migrations/20200425004137_create-users.ts b/packages/shared/src/database/migrations/20200425004137_create-users.ts
new file mode 100644
index 0000000..1628536
--- /dev/null
+++ b/packages/shared/src/database/migrations/20200425004137_create-users.ts
@@ -0,0 +1,18 @@
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('Users', function (table) {
+ table.increments('id')
+ table.string('address').unique().notNullable()
+ table.boolean('addressVerified').defaultTo(false).notNullable()
+ table.integer('userEmailId').index()
+ table.foreign('userEmailId').references('UserEmails.id').onDelete('SET NULL')
+ table.boolean('emailVerified').defaultTo(false).notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ })
+}
+
+export function down(knex: Knex): Promise {
+ return knex.schema.dropTable('Users')
+}
diff --git a/packages/shared/src/database/migrations/20200425004140_create-admins.ts b/packages/shared/src/database/migrations/20200425004140_create-admins.ts
new file mode 100644
index 0000000..cb050cf
--- /dev/null
+++ b/packages/shared/src/database/migrations/20200425004140_create-admins.ts
@@ -0,0 +1,15 @@
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('Admins', function (table) {
+ table.increments('id')
+ table.string('email').unique().notNullable()
+ table.string('password').notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ })
+}
+
+export function down(knex: Knex): Promise {
+ return knex.schema.dropTable('Admins')
+}
diff --git a/packages/server/src/database/migrations/20200425004150_create-sessions.js b/packages/shared/src/database/migrations/20200425004150_create-sessions.ts
similarity index 59%
rename from packages/server/src/database/migrations/20200425004150_create-sessions.js
rename to packages/shared/src/database/migrations/20200425004150_create-sessions.ts
index e11c858..f89241f 100644
--- a/packages/server/src/database/migrations/20200425004150_create-sessions.js
+++ b/packages/shared/src/database/migrations/20200425004150_create-sessions.ts
@@ -1,5 +1,7 @@
-export function up(knex) {
- return knex.schema.dropTableIfExists('Sessions').createTable('Sessions', function (table) {
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('Sessions', function (table) {
table.increments('id')
table.string('sid').unique().notNullable()
table.jsonb('data').notNullable()
@@ -7,12 +9,12 @@ export function up(knex) {
table.foreign('adminId').references('Admins.id').onDelete('CASCADE')
table.integer('userId').index()
table.foreign('userId').references('Users.id').onDelete('CASCADE')
- table.datetime('expiresAt').index().notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('expiresAt').index().notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
}).raw('ALTER TABLE "Sessions" ADD CONSTRAINT "admin_or_user" CHECK (("adminId" IS NOT NULL AND "userId" IS NULL) OR ("userId" IS NOT NULL AND "adminId" IS NULL));')
}
-export function down(knex) {
+export function down(knex: Knex): Promise {
return knex.schema.dropTable('Sessions')
}
diff --git a/packages/server/src/database/migrations/20200425004217_create-settings.js b/packages/shared/src/database/migrations/20200425004217_create-settings.ts
similarity index 60%
rename from packages/server/src/database/migrations/20200425004217_create-settings.js
rename to packages/shared/src/database/migrations/20200425004217_create-settings.ts
index 7868feb..b585226 100644
--- a/packages/server/src/database/migrations/20200425004217_create-settings.js
+++ b/packages/shared/src/database/migrations/20200425004217_create-settings.ts
@@ -1,14 +1,16 @@
-export function up(knex) {
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
return knex.schema.createTable('UserNotificationSettings', function (table) {
table.increments('id')
table.boolean('notificationsDisabled').defaultTo(false).notNullable()
table.integer('userId').index().notNullable()
table.foreign('userId').references('Users.id').onDelete('CASCADE')
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
})
}
-export function down(knex) {
+export function down(knex: Knex): Promise {
return knex.schema.dropTable('UserNotificationSettings')
}
diff --git a/packages/server/src/database/migrations/20200425005745_create-tokens.js b/packages/shared/src/database/migrations/20200425005745_create-tokens.ts
similarity index 56%
rename from packages/server/src/database/migrations/20200425005745_create-tokens.js
rename to packages/shared/src/database/migrations/20200425005745_create-tokens.ts
index 42354a1..755017c 100644
--- a/packages/server/src/database/migrations/20200425005745_create-tokens.js
+++ b/packages/shared/src/database/migrations/20200425005745_create-tokens.ts
@@ -1,16 +1,18 @@
-export function up(knex) {
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
return knex.schema.createTable('UserEmailVerificationTokens', function (table) {
table.increments('id')
table.string('email').notNullable()
table.string('token').notNullable()
table.integer('userId').index().notNullable()
table.foreign('userId').references('Users.id').onDelete('CASCADE')
- table.datetime('expiresAt').index().notNullable()
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('expiresAt').index().notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
})
}
-export function down(knex) {
+export function down(knex: Knex): Promise {
return knex.schema.dropTable('UserEmailVerificationTokens')
}
diff --git a/packages/shared/src/database/migrations/20200428185153_create-reveals.ts b/packages/shared/src/database/migrations/20200428185153_create-reveals.ts
new file mode 100644
index 0000000..32fba45
--- /dev/null
+++ b/packages/shared/src/database/migrations/20200428185153_create-reveals.ts
@@ -0,0 +1,23 @@
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('Reveals', function (table) {
+ table.increments('id')
+ table.string('voteId').notNullable()
+ table.string('guardian').notNullable()
+ table.unique(['guardian', 'voteId'])
+ table.string('disputeId').notNullable()
+ table.integer('roundNumber').notNullable()
+ table.integer('outcome').notNullable()
+ table.string('salt').notNullable()
+ table.boolean('revealed').defaultTo(false).notNullable()
+ table.integer('failedAttempts').notNullable().defaultTo(0)
+ table.boolean('expired').notNullable().defaultTo(false)
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ })
+}
+
+export function down(knex: Knex): Promise {
+ return knex.schema.dropTable('Reveals')
+}
diff --git a/packages/shared/src/database/migrations/20200504162940_create-keeper-suspicious-transactions.ts b/packages/shared/src/database/migrations/20200504162940_create-keeper-suspicious-transactions.ts
new file mode 100644
index 0000000..aaaa4c5
--- /dev/null
+++ b/packages/shared/src/database/migrations/20200504162940_create-keeper-suspicious-transactions.ts
@@ -0,0 +1,15 @@
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('KeeperSuspiciousTransactions', function (table) {
+ table.increments('id')
+ table.string('blockNumber').unique().notNullable()
+ table.string('txHash').unique().nullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ })
+}
+
+export function down(knex: Knex): Promise {
+ return knex.schema.dropTable('KeeperSuspiciousTransactions')
+}
diff --git a/packages/shared/src/database/migrations/20200509004243_create-notification-types.ts b/packages/shared/src/database/migrations/20200509004243_create-notification-types.ts
new file mode 100644
index 0000000..393ba1f
--- /dev/null
+++ b/packages/shared/src/database/migrations/20200509004243_create-notification-types.ts
@@ -0,0 +1,15 @@
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
+ return knex.schema.createTable('UserNotificationTypes', function (table) {
+ table.increments('id')
+ table.string('model').unique().notNullable()
+ table.dateTime('scannedAt').index()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ })
+}
+
+export function down(knex: Knex): Promise {
+ return knex.schema.dropTable('UserNotificationTypes')
+}
diff --git a/packages/server/src/database/migrations/20200509004247_create-notifications.js b/packages/shared/src/database/migrations/20200509004247_create-notifications.ts
similarity index 63%
rename from packages/server/src/database/migrations/20200509004247_create-notifications.js
rename to packages/shared/src/database/migrations/20200509004247_create-notifications.ts
index 64b74c6..91be437 100644
--- a/packages/server/src/database/migrations/20200509004247_create-notifications.js
+++ b/packages/shared/src/database/migrations/20200509004247_create-notifications.ts
@@ -1,17 +1,19 @@
-export function up(knex) {
+import * as Knex from 'knex'
+
+export function up(knex: Knex): Promise {
return knex.schema.createTable('UserNotifications', function (table) {
table.increments('id')
table.jsonb('details').index()
- table.datetime('sentAt').index()
+ table.dateTime('sentAt').index()
table.integer('userNotificationTypeId').index().notNullable()
table.foreign('userNotificationTypeId').references('UserNotificationTypes.id').onDelete('CASCADE')
table.integer('userId').index().notNullable()
table.foreign('userId').references('Users.id').onDelete('CASCADE')
- table.datetime('createdAt').defaultTo(knex.fn.now()).notNullable()
- table.datetime('updatedAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('createdAt').defaultTo(knex.fn.now()).notNullable()
+ table.dateTime('updatedAt').defaultTo(knex.fn.now()).notNullable()
})
}
-export function down(knex) {
+export function down(knex: Knex): Promise {
return knex.schema.dropTable('UserNotifications')
}
diff --git a/packages/server/src/database/seeds/insert-admin.js b/packages/shared/src/database/seeds/insert-admin.ts
similarity index 83%
rename from packages/server/src/database/seeds/insert-admin.js
rename to packages/shared/src/database/seeds/insert-admin.ts
index e861cab..3040518 100644
--- a/packages/server/src/database/seeds/insert-admin.js
+++ b/packages/shared/src/database/seeds/insert-admin.ts
@@ -5,6 +5,6 @@ dotenv.config()
const { env: { ADMIN_EMAIL, ADMIN_PASSWORD } } = process
export async function seed() {
- const admin = await Admin.findByEmail(ADMIN_EMAIL)
+ const admin = await Admin.findByEmail(ADMIN_EMAIL!)
if (!admin) await Admin.create({ email: ADMIN_EMAIL, password: ADMIN_PASSWORD })
}
diff --git a/packages/shared/src/helpers/email-client.ts b/packages/shared/src/helpers/email-client.ts
new file mode 100644
index 0000000..7b350ef
--- /dev/null
+++ b/packages/shared/src/helpers/email-client.ts
@@ -0,0 +1,63 @@
+import { ServerClient, Message, TemplatedMessage } from 'postmark'
+
+const { env: {
+ CLIENT_URL,
+ EMAIL_FROM_DEFAULT,
+ POSTMARK_SERVER_API_TOKEN,
+ POSTMARK_TEMPLATE_ALIAS_VERIFY,
+}} = process
+const postmarkClient = new ServerClient(POSTMARK_SERVER_API_TOKEN!)
+
+type MagicLinkPayload = { email: string, address: string, token: string }
+type ToMaybeArray = { To?: string | string[] }
+type EmailMessage = Message & ToMaybeArray
+type EmailTemplatedMessage = Partial & ToMaybeArray
+type SanitizedMessage = M extends EmailMessage ? Message : TemplatedMessage
+
+class EmailClient {
+ async sendMagicLink({ email, address, token }: MagicLinkPayload): Promise {
+ const verifyEmailUrl = `${CLIENT_URL}?preferences=notifications&address=${address}&token=${token}`
+ const message = {
+ To: email,
+ TemplateAlias: POSTMARK_TEMPLATE_ALIAS_VERIFY,
+ TemplateModel: { verifyEmailUrl },
+ }
+ await this.sendEmailWithTemplate(message)
+ }
+
+ async sendEmail(message: EmailMessage): Promise {
+ const sanitizedMessage = this._sanitizeMessage(message)
+ await postmarkClient.sendEmail(sanitizedMessage)
+ }
+
+ async sendEmailWithTemplate(message: EmailTemplatedMessage): Promise {
+ const sanitizedMessage = this._sanitizeMessage(message)
+ // simply check postmark endpoint when testing.
+ // there is no way to run template test as of 2020-05-04:
+ // https://github.com/wildbit/postmark.js/issues/56
+ if (POSTMARK_SERVER_API_TOKEN == 'POSTMARK_API_TEST') {
+ delete sanitizedMessage.TemplateAlias
+ delete sanitizedMessage.TemplateModel
+ const nonTemplateMessage = message as Message
+ nonTemplateMessage.TextBody = 'test'
+ return await this.sendEmail(nonTemplateMessage)
+ }
+ await postmarkClient.sendEmailWithTemplate(sanitizedMessage)
+ }
+
+ private _sanitizeMessage(message: M): SanitizedMessage {
+ message.From = this._sanitizeFrom(message?.From)
+ if (message.To) message.To = this._sanitizeTo(message.To)
+ return message as any as SanitizedMessage
+ }
+
+ private _sanitizeFrom(From: string | undefined): string {
+ return From || EMAIL_FROM_DEFAULT!
+ }
+
+ private _sanitizeTo(To: string | string[]): string {
+ return Array.isArray(To) ? To.join(', ') : To
+ }
+}
+
+export default new EmailClient()
diff --git a/packages/shared/src/helpers/jwt-manager.ts b/packages/shared/src/helpers/jwt-manager.ts
new file mode 100644
index 0000000..5ad13ab
--- /dev/null
+++ b/packages/shared/src/helpers/jwt-manager.ts
@@ -0,0 +1,23 @@
+import jwt from 'jsonwebtoken'
+
+const { env: {
+ EMAIL_JWT_PRIVATE_KEY,
+}} = process
+
+function generateToken(expiresIn: string | number = '24h'): string {
+ if (!EMAIL_JWT_PRIVATE_KEY) throw new Error('EMAIL_JWT_PRIVATE_KEY env variable missing.')
+ const payload = { timestamp: Date.now() }
+ return jwt.sign(payload, EMAIL_JWT_PRIVATE_KEY, { expiresIn })
+}
+
+function isTokenValid(token: string): boolean {
+ if (!EMAIL_JWT_PRIVATE_KEY) throw new Error('EMAIL_JWT_PRIVATE_KEY env variable missing.')
+ try {
+ jwt.verify(token, EMAIL_JWT_PRIVATE_KEY)
+ return true
+ } catch {
+ return false
+ }
+}
+
+export { generateToken, isTokenValid }
diff --git a/packages/shared/src/helpers/sleep.ts b/packages/shared/src/helpers/sleep.ts
new file mode 100644
index 0000000..a49de62
--- /dev/null
+++ b/packages/shared/src/helpers/sleep.ts
@@ -0,0 +1,3 @@
+export default async function (ms: number) {
+ return new Promise(resolve => setTimeout(resolve, ms))
+}
diff --git a/packages/shared/src/models/objection/Admin.ts b/packages/shared/src/models/objection/Admin.ts
new file mode 100644
index 0000000..19900a2
--- /dev/null
+++ b/packages/shared/src/models/objection/Admin.ts
@@ -0,0 +1,57 @@
+import BaseModel from './BaseModel'
+import { Session } from './'
+import bcrypt from 'bcryptjs'
+
+export default class Admin extends BaseModel {
+ static get tableName() {
+ return 'Admins'
+ }
+
+ email?: string
+ password?: string
+ sessions?: Session[]
+
+ static get relationMappings() {
+ return {
+ sessions: {
+ relation: BaseModel.HasManyRelation,
+ modelClass: 'Session',
+ join: {
+ from: 'Admins.id',
+ to: 'Sessions.adminId'
+ }
+ }
+ }
+ }
+
+ static async countByEmail(email: string): Promise {
+ return this.query().where({ email }).resultSize()
+ }
+
+ static async findByEmail(email: string): Promise {
+ return this.findOne({ email })
+ }
+
+ static async findAllEmails(): Promise {
+ const admins = await this.query().select('email')
+ return admins.map(admin => admin.email!)
+ }
+
+ hasPassword(password: string): boolean {
+ return bcrypt.compareSync(password, this.password!)
+ }
+
+ hashPassword(): void {
+ if (this.password) this.password = bcrypt.hashSync(this.password)
+ }
+
+ $beforeInsert: BaseModel['$beforeInsert'] = async (queryContext) => {
+ await super.$beforeInsert(queryContext)
+ this.hashPassword()
+ }
+
+ $beforeUpdate: BaseModel['$beforeUpdate'] = async (opt, queryContext) => {
+ await super.$beforeUpdate(opt, queryContext)
+ this.hashPassword()
+ }
+}
diff --git a/packages/shared/src/models/objection/BaseModel.ts b/packages/shared/src/models/objection/BaseModel.ts
new file mode 100644
index 0000000..1881f79
--- /dev/null
+++ b/packages/shared/src/models/objection/BaseModel.ts
@@ -0,0 +1,87 @@
+import Knex from 'knex'
+import { Model, MaybeCompositeId, QueryBuilder } from 'objection'
+
+import config from '../../database/config'
+Model.knex(Knex(config))
+
+// "this" is not polymorphic for static methods, need to cast return values
+// Ongoing issue as of Nov 7, 2020: https://github.com/microsoft/TypeScript/issues/5863
+type SingleResult = QueryBuilder, InstanceType>
+export { SingleResult }
+
+export default class BaseModel extends Model {
+ // modelPaths is used to allow modelClass relations be defined as a string to avoid require loops
+ // https://vincit.github.io/objection.js/guide/relations.html#require-loops
+ static get modelPaths(): [string] {
+ return [__dirname];
+ }
+
+ id!: MaybeCompositeId
+ updatedAt?: Date
+ createdAt?: Date
+
+ $beforeUpdate: Model['$beforeUpdate'] = async (opt, queryContext) => {
+ await super.$beforeUpdate(opt, queryContext)
+ this.updatedAt = new Date()
+ }
+
+
+ // static query methods (table level)
+
+ static async exists(args: any): Promise {
+ return !!(await this.findOne(args))
+ }
+
+ static count(args: any): Promise {
+ return this.query().where(args).resultSize()
+ }
+
+ static findById(
+ this: T,
+ id: BaseModel['id']
+ ): SingleResult {
+ return this.query().findById(id) as SingleResult
+ }
+
+ static findOne(
+ this: T,
+ args: any
+ ): SingleResult {
+ return this.query().findOne(args) as SingleResult
+ }
+
+ static async findOrInsert(
+ this: T,
+ args: any
+ ): Promise> {
+ let row = await this.findOne(args)
+ if (!row) row = await this.create(args)
+ return row as SingleResult
+ }
+
+ static create(
+ this: T,
+ args: any = {}
+ ): SingleResult {
+ return this.query().insert(args) as SingleResult
+ }
+
+
+ // instance query methods (row level)
+
+ async relatedUpdateOrInsert(relation: string, args: any): Promise {
+ const row = await this.$relatedQuery(relation)
+ if (row) {
+ await this.$relatedQuery(relation).update(args)
+ } else {
+ await this.$relatedQuery(relation).insert(args)
+ }
+ }
+
+ get createdAtDateString(): string {
+ if (!this.createdAt) {
+ throw Error('createdAt field missing')
+ }
+ return this.createdAt.toLocaleDateString('en-US', ({dateStyle: 'full'} as Intl.DateTimeFormatOptions)) // format: Tuesday, May 19, 2020
+ }
+}
diff --git a/packages/server/src/models/objection/KeeperSuspiciousTransaction.js b/packages/shared/src/models/objection/KeeperSuspiciousTransaction.ts
similarity index 60%
rename from packages/server/src/models/objection/KeeperSuspiciousTransaction.js
rename to packages/shared/src/models/objection/KeeperSuspiciousTransaction.ts
index 398510c..70ee8a6 100644
--- a/packages/server/src/models/objection/KeeperSuspiciousTransaction.js
+++ b/packages/shared/src/models/objection/KeeperSuspiciousTransaction.ts
@@ -5,17 +5,16 @@ export default class KeeperSuspiciousTransactions extends BaseModel {
return 'KeeperSuspiciousTransactions'
}
- static async last() {
+ blockNumber?: string
+ txHash?: string
+
+ static async last(): Promise {
const txs = await this.query().limit(1).orderBy('createdAt', 'DESC')
return txs[0]
}
- static async lastInspectedBlockNumber() {
+ static async lastInspectedBlockNumber(): Promise {
const tx = await this.last()
- return tx ? tx.blockNumber : 0
- }
-
- static async create(params = {}) {
- return this.query().insert(params)
+ return tx ? Number(tx.blockNumber!) : 0
}
}
diff --git a/packages/shared/src/models/objection/Reveal.ts b/packages/shared/src/models/objection/Reveal.ts
new file mode 100644
index 0000000..d378282
--- /dev/null
+++ b/packages/shared/src/models/objection/Reveal.ts
@@ -0,0 +1,18 @@
+import BaseModel from './BaseModel'
+
+export default class Reveal extends BaseModel {
+ static get tableName() {
+ return 'Reveals'
+ }
+
+ voteId?: string
+ guardian?: string
+ blockNumber?: string
+ disputeId?: string
+ roundNumber?: number
+ outcome?: number
+ salt?: string
+ revealed?: boolean
+ failedAttempts?: number
+ expired?: boolean
+}
diff --git a/packages/server/src/models/objection/Session.js b/packages/shared/src/models/objection/Session.ts
similarity index 70%
rename from packages/server/src/models/objection/Session.js
rename to packages/shared/src/models/objection/Session.ts
index 5243e99..1b1cd4f 100644
--- a/packages/server/src/models/objection/Session.js
+++ b/packages/shared/src/models/objection/Session.ts
@@ -1,10 +1,18 @@
-import BaseModel from './BaseModel'
+import { BaseModel, User, Admin } from './'
export default class Session extends BaseModel {
static get tableName() {
return 'Sessions'
}
+ sid?: string
+ data?: any
+ adminId?: number
+ userId?: number
+ expiresAt?: Date
+ user?: User
+ admin?: Admin
+
static get relationMappings() {
return {
user: {
@@ -26,14 +34,14 @@ export default class Session extends BaseModel {
}
}
- static async getData(sid) {
+ static async getData(sid: Session['sid']) {
const session = await this.findOne({sid})
return session?.data
}
- static async setData(sid, newData) {
- for (let prop of ['userId', 'adminId']) {
- if (newData.hasOwnProperty(prop)) {
+ static async setData(sid: Session['sid'], newData: Session['data']): Promise {
+ for (const prop of ['userId', 'adminId']) {
+ if (Object.prototype.hasOwnProperty.call(newData, prop)) {
const row = {
sid,
data: newData,
diff --git a/packages/server/src/models/objection/User.js b/packages/shared/src/models/objection/User.ts
similarity index 65%
rename from packages/server/src/models/objection/User.js
rename to packages/shared/src/models/objection/User.ts
index d4b8048..af595b9 100644
--- a/packages/server/src/models/objection/User.js
+++ b/packages/shared/src/models/objection/User.ts
@@ -1,17 +1,28 @@
-import BaseModel from './BaseModel'
-import UserEmail from './UserEmail'
-import emailClient from '@aragon/protocol-backend-shared/helpers/email-client'
-import { generateToken } from '../../helpers/token-manager'
+import { BaseModel, Session, UserNotificationSetting, UserNotification, UserEmailVerificationToken, UserEmail } from './'
+import { SingleResult } from './BaseModel'
+import emailClient from '../../helpers/email-client'
+import { generateToken } from '../../helpers/jwt-manager'
-import { DAYS } from '@aragon/protocol-backend-shared/build/helpers/times'
+import { DAYS } from '../../helpers/times'
const EMAIL_TOKEN_EXPIRES = DAYS
const EMAIL_TOKEN_OLD = DAYS
export default class User extends BaseModel {
+
static get tableName() {
return 'Users'
}
+ address?: string
+ addressVerified?: boolean
+ userEmailId?: number
+ emailVerified?: boolean
+ sessions?: Session[]
+ notificationSetting?: UserNotificationSetting
+ notifications?: UserNotification[]
+ emailVerificationToken?: UserEmailVerificationToken
+ email?: UserEmail
+
static get relationMappings() {
return {
sessions: {
@@ -57,42 +68,45 @@ export default class User extends BaseModel {
}
}
- static findOne(args) {
+ static findOne(
+ this: T,
+ args: any
+ ): SingleResult {
if (args.address) args.address = args.address.toLowerCase()
- return super.findOne(args)
+ return super.findOne(args) as SingleResult
}
- async $beforeInsert(queryContext) {
+ $beforeInsert: BaseModel['$beforeInsert'] = async (queryContext) => {
await super.$beforeInsert(queryContext)
if (this.address) this.address = this.address.toLowerCase()
}
- async $beforeUpdate(opt, queryContext) {
+ $beforeUpdate: BaseModel['$beforeUpdate'] = async (opt, queryContext) => {
await super.$beforeUpdate(opt, queryContext)
if (this.address) this.address = this.address.toLowerCase()
}
- static async findWithUnverifiedEmail() {
+ static async findWithUnverifiedEmail(): Promise {
const users = await this.query().where({emailVerified: false}).withGraphFetched('[email, emailVerificationToken]')
return users.filter(user => !!user.email)
}
- static async findWithoutDisabledNotifications() {
+ static async findWithoutDisabledNotifications(): Promise {
const users = await this.query().withGraphFetched('[email, notificationSetting]')
return users.filter(user => !!user.email && !user.notificationSetting?.notificationsDisabled)
}
- static async findWithOldVerificationToken() {
+ static async findWithOldVerificationToken(): Promise {
const users = await this.findWithUnverifiedEmail()
- return users.filter(user => user.emailVerificationToken && user.emailVerificationToken.expiresAt <= new Date(Date.now()-EMAIL_TOKEN_OLD))
+ return users.filter(user => user.emailVerificationToken && user.emailVerificationToken.expiresAt! <= new Date(Date.now()-EMAIL_TOKEN_OLD))
}
- static async findUnverifiedAnjRegistrations() {
+ static async findUnverifiedAnjRegistrations(): Promise {
const users = await this.findWithUnverifiedEmail()
return users.filter(user => !user.addressVerified)
}
- async relateEmail(email) {
+ async relateEmail(email: string): Promise {
await this.unrelateEmail()
const emailInstance = await UserEmail.findOne({email})
if (emailInstance) {
@@ -102,32 +116,34 @@ export default class User extends BaseModel {
}
}
- async unrelateEmail() {
+ async unrelateEmail(): Promise {
const user = await this.$fetchGraph('email')
let emailInstance = user.email
await user.$relatedQuery('email').unrelate()
// clean emails with no users
if (emailInstance) {
emailInstance = await emailInstance.$fetchGraph('users')
- if (emailInstance.users.length == 0) {
+ if (emailInstance.users?.length == 0) {
await emailInstance.$query().del()
}
}
}
- async sendVerificationEmail() {
+ async sendVerificationEmail(): Promise {
const user = await this.$fetchGraph('email')
- const { email: { email }, address } = user
+ const { email: userEmail, address } = user
+ if (!userEmail) throw new Error(`No associated email found for user ${user.address}`)
+ const { email } = userEmail
const tokenExpiresSeconds = EMAIL_TOKEN_EXPIRES/1000
const token = generateToken(tokenExpiresSeconds)
await user.relatedUpdateOrInsert('emailVerificationToken', {
- email,
+ email: email!,
token,
expiresAt: new Date(Date.now()+EMAIL_TOKEN_EXPIRES)
})
await emailClient.sendMagicLink({
- email,
- address,
+ email: email!,
+ address: address!,
token
})
}
diff --git a/packages/server/src/models/objection/UserEmail.js b/packages/shared/src/models/objection/UserEmail.ts
similarity index 83%
rename from packages/server/src/models/objection/UserEmail.js
rename to packages/shared/src/models/objection/UserEmail.ts
index cbf9fc2..9e046cb 100644
--- a/packages/server/src/models/objection/UserEmail.js
+++ b/packages/shared/src/models/objection/UserEmail.ts
@@ -1,10 +1,13 @@
-import BaseModel from './BaseModel'
+import { BaseModel, User } from './'
export default class UserEmail extends BaseModel {
static get tableName() {
return 'UserEmails'
}
+ email?: string
+ users?: User[]
+
static get relationMappings() {
return {
users: {
diff --git a/packages/server/src/models/objection/UserEmailVerificationToken.js b/packages/shared/src/models/objection/UserEmailVerificationToken.ts
similarity index 76%
rename from packages/server/src/models/objection/UserEmailVerificationToken.js
rename to packages/shared/src/models/objection/UserEmailVerificationToken.ts
index b68792f..5852963 100644
--- a/packages/server/src/models/objection/UserEmailVerificationToken.js
+++ b/packages/shared/src/models/objection/UserEmailVerificationToken.ts
@@ -1,10 +1,16 @@
-import BaseModel from './BaseModel'
+import { BaseModel, User } from './'
export default class UserEmailVerificationToken extends BaseModel {
static get tableName() {
return 'UserEmailVerificationTokens'
}
+ email?: string
+ token?: string
+ userId?: number
+ expiresAt?: Date
+ user?: User
+
static get relationMappings() {
return {
user: {
diff --git a/packages/server/src/models/objection/UserNotification.js b/packages/shared/src/models/objection/UserNotification.ts
similarity index 76%
rename from packages/server/src/models/objection/UserNotification.js
rename to packages/shared/src/models/objection/UserNotification.ts
index dfdc708..2f5bf1d 100644
--- a/packages/server/src/models/objection/UserNotification.js
+++ b/packages/shared/src/models/objection/UserNotification.ts
@@ -1,11 +1,18 @@
-import BaseModel from './BaseModel'
-import { HOURS } from '@aragon/protocol-backend-shared/build/helpers/times'
+import { BaseModel, User, UserNotificationType } from './'
+import { HOURS } from '../../helpers/times'
export default class UserNotification extends BaseModel {
static get tableName() {
return 'UserNotifications'
}
+ details?: any
+ sentAt?: Date
+ userNotificationTypeId?: number
+ userId?: number
+ user?: User
+ type?: UserNotificationType
+
static get relationMappings() {
return {
user: {
diff --git a/packages/server/src/models/objection/UserNotificationSetting.js b/packages/shared/src/models/objection/UserNotificationSetting.ts
similarity index 79%
rename from packages/server/src/models/objection/UserNotificationSetting.js
rename to packages/shared/src/models/objection/UserNotificationSetting.ts
index c1136cd..052fa65 100644
--- a/packages/server/src/models/objection/UserNotificationSetting.js
+++ b/packages/shared/src/models/objection/UserNotificationSetting.ts
@@ -1,10 +1,14 @@
-import BaseModel from './BaseModel'
+import { BaseModel, User } from './'
export default class UserNotificationSetting extends BaseModel {
static get tableName() {
return 'UserNotificationSettings'
}
+ notificationsDisabled?: boolean
+ userId?: number
+ user?: User
+
static get relationMappings() {
return {
user: {
diff --git a/packages/server/src/models/objection/UserNotificationType.js b/packages/shared/src/models/objection/UserNotificationType.ts
similarity index 77%
rename from packages/server/src/models/objection/UserNotificationType.js
rename to packages/shared/src/models/objection/UserNotificationType.ts
index ae0b0a2..2ccbb86 100644
--- a/packages/server/src/models/objection/UserNotificationType.js
+++ b/packages/shared/src/models/objection/UserNotificationType.ts
@@ -1,10 +1,14 @@
-import BaseModel from './BaseModel'
+import { BaseModel, UserNotification } from './'
export default class UserNotificationType extends BaseModel {
static get tableName() {
return 'UserNotificationTypes'
}
+ model?: string
+ scannedAt?: Date
+ notifications?: UserNotification[]
+
static get relationMappings() {
return {
notifications: {
diff --git a/packages/shared/src/models/objection/index.ts b/packages/shared/src/models/objection/index.ts
new file mode 100644
index 0000000..381aed7
--- /dev/null
+++ b/packages/shared/src/models/objection/index.ts
@@ -0,0 +1,11 @@
+export { default as Admin } from './Admin'
+export { default as BaseModel } from './BaseModel'
+export { default as KeeperSuspiciousTransaction } from './KeeperSuspiciousTransaction'
+export { default as Reveal } from './Reveal'
+export { default as Session } from './Session'
+export { default as User } from './User'
+export { default as UserEmail } from './UserEmail'
+export { default as UserEmailVerificationToken } from './UserEmailVerificationToken'
+export { default as UserNotification } from './UserNotification'
+export { default as UserNotificationSetting } from './UserNotificationSetting'
+export { default as UserNotificationType } from './UserNotificationType'
diff --git a/packages/shared/src/scripts/db-setup.ts b/packages/shared/src/scripts/db-setup.ts
new file mode 100755
index 0000000..ad27c5a
--- /dev/null
+++ b/packages/shared/src/scripts/db-setup.ts
@@ -0,0 +1,35 @@
+import Knex from 'knex'
+import sleep from '../helpers/sleep'
+import { SECONDS } from '../helpers/times'
+
+import config from '../database/config'
+const knex = Knex(config)
+
+async function waitConnection() {
+ for (;;) {
+ try {
+ return await knex.migrate.currentVersion()
+ }
+ catch (error) {
+ if (error.code == 'ECONNREFUSED') {
+ console.log('Database connection timed out, retrying in 5 seconds...')
+ await sleep(5 * SECONDS)
+ }
+ else {
+ throw error
+ }
+ }
+ }
+}
+
+async function main() {
+ console.log('Running knex database migrations...')
+ await waitConnection()
+ await knex.migrate.latest()
+ knex.destroy()
+}
+
+main().catch((error) => {
+ console.error(error)
+ process.exit(1)
+})
diff --git a/yarn.lock b/yarn.lock
index 03c60a7..7336d34 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -27,24 +27,7 @@
resolved "https://registry.yarnpkg.com/@aragonone/erc20-faucet/-/erc20-faucet-1.0.0.tgz#ce671a03c25e3dd3930e1a0395830fe500fc8b22"
integrity sha512-0e7+5dH5xFfyj8LF7t1k6JEla0lFupwUezEekQTEGqz45CtVHiIjLjEbkQ9n29MITNvNtUFMZVruK7jprZRHBg==
-"@babel/cli@^7.12.1":
- version "7.12.1"
- resolved "https://testnet.thegraph.com/npm-registry/@babel%2fcli/-/cli-7.12.1.tgz#e08a0b1cb6fcd4b9eb6a606ba5602c5c0fe24a0c"
- integrity sha512-eRJREyrfAJ2r42Iaxe8h3v6yyj1wu9OyosaUHW6UImjGf9ahGL9nsFNh7OCopvtcPL8WnEo7tp78wrZaZ6vG9g==
- dependencies:
- commander "^4.0.1"
- convert-source-map "^1.1.0"
- fs-readdir-recursive "^1.1.0"
- glob "^7.0.0"
- lodash "^4.17.19"
- make-dir "^2.1.0"
- slash "^2.0.0"
- source-map "^0.5.0"
- optionalDependencies:
- "@nicolo-ribaudo/chokidar-2" "^2.1.8"
- chokidar "^3.4.0"
-
-"@babel/cli@^7.7.7":
+"@babel/cli@^7.12.1", "@babel/cli@^7.7.7":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.12.1.tgz#e08a0b1cb6fcd4b9eb6a606ba5602c5c0fe24a0c"
integrity sha512-eRJREyrfAJ2r42Iaxe8h3v6yyj1wu9OyosaUHW6UImjGf9ahGL9nsFNh7OCopvtcPL8WnEo7tp78wrZaZ6vG9g==
@@ -123,7 +106,7 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@^7.7.7":
+"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.4.5", "@babel/core@^7.7.7":
version "7.12.3"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8"
integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==
@@ -145,28 +128,6 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/core@^7.12.3":
- version "7.12.3"
- resolved "https://testnet.thegraph.com/npm-registry/@babel%2fcore/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8"
- integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==
- dependencies:
- "@babel/code-frame" "^7.10.4"
- "@babel/generator" "^7.12.1"
- "@babel/helper-module-transforms" "^7.12.1"
- "@babel/helpers" "^7.12.1"
- "@babel/parser" "^7.12.3"
- "@babel/template" "^7.10.4"
- "@babel/traverse" "^7.12.1"
- "@babel/types" "^7.12.1"
- convert-source-map "^1.7.0"
- debug "^4.1.0"
- gensync "^1.0.0-beta.1"
- json5 "^2.1.2"
- lodash "^4.17.19"
- resolve "^1.3.2"
- semver "^5.4.1"
- source-map "^0.5.0"
-
"@babel/generator@^7.12.1", "@babel/generator@^7.4.0", "@babel/generator@^7.8.4", "@babel/generator@^7.9.0":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468"
@@ -1097,79 +1058,7 @@
levenary "^1.1.1"
semver "^5.5.0"
-"@babel/preset-env@^7.12.1":
- version "7.12.1"
- resolved "https://testnet.thegraph.com/npm-registry/@babel%2fpreset-env/-/preset-env-7.12.1.tgz#9c7e5ca82a19efc865384bb4989148d2ee5d7ac2"
- integrity sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==
- dependencies:
- "@babel/compat-data" "^7.12.1"
- "@babel/helper-compilation-targets" "^7.12.1"
- "@babel/helper-module-imports" "^7.12.1"
- "@babel/helper-plugin-utils" "^7.10.4"
- "@babel/helper-validator-option" "^7.12.1"
- "@babel/plugin-proposal-async-generator-functions" "^7.12.1"
- "@babel/plugin-proposal-class-properties" "^7.12.1"
- "@babel/plugin-proposal-dynamic-import" "^7.12.1"
- "@babel/plugin-proposal-export-namespace-from" "^7.12.1"
- "@babel/plugin-proposal-json-strings" "^7.12.1"
- "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1"
- "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1"
- "@babel/plugin-proposal-numeric-separator" "^7.12.1"
- "@babel/plugin-proposal-object-rest-spread" "^7.12.1"
- "@babel/plugin-proposal-optional-catch-binding" "^7.12.1"
- "@babel/plugin-proposal-optional-chaining" "^7.12.1"
- "@babel/plugin-proposal-private-methods" "^7.12.1"
- "@babel/plugin-proposal-unicode-property-regex" "^7.12.1"
- "@babel/plugin-syntax-async-generators" "^7.8.0"
- "@babel/plugin-syntax-class-properties" "^7.12.1"
- "@babel/plugin-syntax-dynamic-import" "^7.8.0"
- "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
- "@babel/plugin-syntax-json-strings" "^7.8.0"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
- "@babel/plugin-syntax-numeric-separator" "^7.10.4"
- "@babel/plugin-syntax-object-rest-spread" "^7.8.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
- "@babel/plugin-syntax-optional-chaining" "^7.8.0"
- "@babel/plugin-syntax-top-level-await" "^7.12.1"
- "@babel/plugin-transform-arrow-functions" "^7.12.1"
- "@babel/plugin-transform-async-to-generator" "^7.12.1"
- "@babel/plugin-transform-block-scoped-functions" "^7.12.1"
- "@babel/plugin-transform-block-scoping" "^7.12.1"
- "@babel/plugin-transform-classes" "^7.12.1"
- "@babel/plugin-transform-computed-properties" "^7.12.1"
- "@babel/plugin-transform-destructuring" "^7.12.1"
- "@babel/plugin-transform-dotall-regex" "^7.12.1"
- "@babel/plugin-transform-duplicate-keys" "^7.12.1"
- "@babel/plugin-transform-exponentiation-operator" "^7.12.1"
- "@babel/plugin-transform-for-of" "^7.12.1"
- "@babel/plugin-transform-function-name" "^7.12.1"
- "@babel/plugin-transform-literals" "^7.12.1"
- "@babel/plugin-transform-member-expression-literals" "^7.12.1"
- "@babel/plugin-transform-modules-amd" "^7.12.1"
- "@babel/plugin-transform-modules-commonjs" "^7.12.1"
- "@babel/plugin-transform-modules-systemjs" "^7.12.1"
- "@babel/plugin-transform-modules-umd" "^7.12.1"
- "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1"
- "@babel/plugin-transform-new-target" "^7.12.1"
- "@babel/plugin-transform-object-super" "^7.12.1"
- "@babel/plugin-transform-parameters" "^7.12.1"
- "@babel/plugin-transform-property-literals" "^7.12.1"
- "@babel/plugin-transform-regenerator" "^7.12.1"
- "@babel/plugin-transform-reserved-words" "^7.12.1"
- "@babel/plugin-transform-shorthand-properties" "^7.12.1"
- "@babel/plugin-transform-spread" "^7.12.1"
- "@babel/plugin-transform-sticky-regex" "^7.12.1"
- "@babel/plugin-transform-template-literals" "^7.12.1"
- "@babel/plugin-transform-typeof-symbol" "^7.12.1"
- "@babel/plugin-transform-unicode-escapes" "^7.12.1"
- "@babel/plugin-transform-unicode-regex" "^7.12.1"
- "@babel/preset-modules" "^0.1.3"
- "@babel/types" "^7.12.1"
- core-js-compat "^3.6.2"
- semver "^5.5.0"
-
-"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.7.7":
+"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.4.5", "@babel/preset-env@^7.7.7":
version "7.12.1"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.1.tgz#9c7e5ca82a19efc865384bb4989148d2ee5d7ac2"
integrity sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==
@@ -3029,6 +2918,11 @@
dependencies:
"@babel/types" "^7.3.0"
+"@types/bcryptjs@^2.4.2":
+ version "2.4.2"
+ resolved "https://testnet.thegraph.com/npm-registry/@types%2fbcryptjs/-/bcryptjs-2.4.2.tgz#e3530eac9dd136bfdfb0e43df2c4c5ce1f77dfae"
+ integrity sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==
+
"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5":
version "4.11.6"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
@@ -3084,6 +2978,13 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==
+"@types/jsonwebtoken@^8.5.0":
+ version "8.5.0"
+ resolved "https://testnet.thegraph.com/npm-registry/@types%2fjsonwebtoken/-/jsonwebtoken-8.5.0.tgz#2531d5e300803aa63279b232c014acf780c981c5"
+ integrity sha512-9bVao7LvyorRGZCw0VmH/dr7Og+NdjYSsKAxB43OQoComFbBgsEpoR9JW6+qSq/ogwVBg8GI2MfAlk4SYI4OLg==
+ dependencies:
+ "@types/node" "*"
+
"@types/lodash@^4.14.149":
version "4.14.162"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.162.tgz#65d78c397e0d883f44afbf1f7ba9867022411470"
@@ -3900,7 +3801,7 @@ array-differ@^2.0.3:
array-each@^1.0.1:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
+ resolved "https://testnet.thegraph.com/npm-registry/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8=
array-equal@^1.0.0:
@@ -3939,7 +3840,7 @@ array-includes@^3.0.3, array-includes@^3.1.1:
array-slice@^1.0.0:
version "1.1.0"
- resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4"
+ resolved "https://testnet.thegraph.com/npm-registry/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4"
integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==
array-union@^1.0.1, array-union@^1.0.2:
@@ -4676,7 +4577,7 @@ buffer-crc32@~0.2.3:
buffer-equal-constant-time@1.0.1:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
+ resolved "https://testnet.thegraph.com/npm-registry/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
buffer-fill@^1.0.0:
@@ -5348,7 +5249,7 @@ commander@^4.0.1, commander@^4.1.1:
commander@^5.1.0:
version "5.1.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
+ resolved "https://testnet.thegraph.com/npm-registry/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
common-tags@^1.8.0:
@@ -6103,7 +6004,7 @@ dateformat@^3.0.0, dateformat@^3.0.3:
db-errors@^0.2.3:
version "0.2.3"
- resolved "https://registry.yarnpkg.com/db-errors/-/db-errors-0.2.3.tgz#a6a38952e00b20e790f2695a6446b3c65497ffa2"
+ resolved "https://testnet.thegraph.com/npm-registry/db-errors/-/db-errors-0.2.3.tgz#a6a38952e00b20e790f2695a6446b3c65497ffa2"
integrity sha512-OOgqgDuCavHXjYSJoV2yGhv6SeG8nk42aoCSoyXLZUH7VwFG27rxbavU1z+VrZbZjphw5UkDQwUlD21MwZpUng==
debug-fabulous@0.0.X:
@@ -6138,7 +6039,7 @@ debug@3.2.6, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
debug@4.1.1:
version "4.1.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
+ resolved "https://testnet.thegraph.com/npm-registry/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
@@ -6376,7 +6277,7 @@ destroy@~1.0.4:
detect-file@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
+ resolved "https://testnet.thegraph.com/npm-registry/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
detect-indent@^5.0.0:
@@ -6635,7 +6536,7 @@ ecc-jsbn@~0.1.1:
ecdsa-sig-formatter@1.0.11:
version "1.0.11"
- resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
+ resolved "https://testnet.thegraph.com/npm-registry/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
dependencies:
safe-buffer "^5.0.1"
@@ -7108,7 +7009,7 @@ eslint@^7.12.1:
esm@^3.2.25:
version "3.2.25"
- resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
+ resolved "https://testnet.thegraph.com/npm-registry/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
espree@^6.1.2:
@@ -7542,7 +7443,7 @@ expand-range@^1.8.1:
expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
- resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
+ resolved "https://testnet.thegraph.com/npm-registry/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
dependencies:
homedir-polyfill "^1.0.1"
@@ -7938,7 +7839,7 @@ find-up@^2.0.0, find-up@^2.1.0:
findup-sync@^3.0.0:
version "3.0.0"
- resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
+ resolved "https://testnet.thegraph.com/npm-registry/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
dependencies:
detect-file "^1.0.0"
@@ -7948,7 +7849,7 @@ findup-sync@^3.0.0:
fined@^1.0.1:
version "1.2.0"
- resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b"
+ resolved "https://testnet.thegraph.com/npm-registry/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b"
integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==
dependencies:
expand-tilde "^2.0.2"
@@ -7964,7 +7865,7 @@ first-chunk-stream@^1.0.0:
flagged-respawn@^1.0.0:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41"
+ resolved "https://testnet.thegraph.com/npm-registry/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41"
integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==
flat-cache@^2.0.1:
@@ -8032,7 +7933,7 @@ for-own@^0.1.3, for-own@^0.1.4:
for-own@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
+ resolved "https://testnet.thegraph.com/npm-registry/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
dependencies:
for-in "^1.0.1"
@@ -8305,7 +8206,7 @@ get-value@^2.0.3, get-value@^2.0.6:
getopts@2.2.5:
version "2.2.5"
- resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b"
+ resolved "https://testnet.thegraph.com/npm-registry/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b"
integrity sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==
getpass@^0.1.1:
@@ -8464,7 +8365,7 @@ global-modules@2.0.0:
global-modules@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
+ resolved "https://testnet.thegraph.com/npm-registry/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
dependencies:
global-prefix "^1.0.1"
@@ -8473,7 +8374,7 @@ global-modules@^1.0.0:
global-prefix@^1.0.1:
version "1.0.2"
- resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
+ resolved "https://testnet.thegraph.com/npm-registry/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
dependencies:
expand-tilde "^2.0.2"
@@ -9282,7 +9183,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -9383,7 +9284,7 @@ internal-ip@^4.3.0:
interpret@^2.2.0:
version "2.2.0"
- resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
+ resolved "https://testnet.thegraph.com/npm-registry/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==
invariant@^2.2.2, invariant@^2.2.4:
@@ -9430,7 +9331,7 @@ is-absolute-url@^3.0.3:
is-absolute@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576"
+ resolved "https://testnet.thegraph.com/npm-registry/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576"
integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==
dependencies:
is-relative "^1.0.0"
@@ -9803,7 +9704,7 @@ is-regexp@^1.0.0:
is-relative@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
+ resolved "https://testnet.thegraph.com/npm-registry/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==
dependencies:
is-unc-path "^1.0.0"
@@ -9868,7 +9769,7 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0:
is-unc-path@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d"
+ resolved "https://testnet.thegraph.com/npm-registry/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d"
integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==
dependencies:
unc-path-regex "^0.1.2"
@@ -10595,7 +10496,7 @@ jsonparse@^1.2.0:
jsonwebtoken@^8.5.1:
version "8.5.1"
- resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
+ resolved "https://testnet.thegraph.com/npm-registry/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
dependencies:
jws "^3.2.2"
@@ -10634,7 +10535,7 @@ just-extend@^4.0.2:
jwa@^1.4.1:
version "1.4.1"
- resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
+ resolved "https://testnet.thegraph.com/npm-registry/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
dependencies:
buffer-equal-constant-time "1.0.1"
@@ -10643,7 +10544,7 @@ jwa@^1.4.1:
jws@^3.2.2:
version "3.2.2"
- resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
+ resolved "https://testnet.thegraph.com/npm-registry/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
dependencies:
jwa "^1.4.1"
@@ -10705,25 +10606,22 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
-knex@^0.21.0:
- version "0.21.6"
- resolved "https://registry.yarnpkg.com/knex/-/knex-0.21.6.tgz#3e80ae38199c41e2dfe7d1d1a38470b1de1c93e7"
- integrity sha512-gFB2q4MamYCEqzCPNgK7DMcyyAxoHhhSDnPsNDJo50Gor5ibI2n5bNRW768IG5S06k6nE3Gik5/kcoTmbsYbZw==
+knex@^0.21.12:
+ version "0.21.12"
+ resolved "https://testnet.thegraph.com/npm-registry/knex/-/knex-0.21.12.tgz#961bdb484311eb853030f6f49bd5bf9eca89dc51"
+ integrity sha512-AEyyiTM9p/x/Pb38TPZkvphKPmn8UWxP7MdIphzjAOielOfFFeU6pjP6y3M7UJ7rxrQsCrAYHwdonLQ3l1JCDw==
dependencies:
colorette "1.2.1"
commander "^5.1.0"
debug "4.1.1"
esm "^3.2.25"
getopts "2.2.5"
- inherits "~2.0.4"
interpret "^2.2.0"
liftoff "3.1.0"
lodash "^4.17.20"
- mkdirp "^1.0.4"
pg-connection-string "2.3.0"
- tarn "^3.0.0"
+ tarn "^3.0.1"
tildify "2.0.0"
- uuid "^7.0.3"
v8flags "^3.2.0"
last-call-webpack-plugin@^3.0.0:
@@ -10886,7 +10784,7 @@ levn@^0.4.1:
liftoff@3.1.0:
version "3.1.0"
- resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3"
+ resolved "https://testnet.thegraph.com/npm-registry/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3"
integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==
dependencies:
extend "^3.0.0"
@@ -11036,12 +10934,12 @@ lodash.get@^4.4.2:
lodash.includes@^4.3.0:
version "4.3.0"
- resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
+ resolved "https://testnet.thegraph.com/npm-registry/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
lodash.isboolean@^3.0.3:
version "3.0.3"
- resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
+ resolved "https://testnet.thegraph.com/npm-registry/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
lodash.isequal@^4.0.0, lodash.isequal@^4.5.0:
@@ -11051,7 +10949,7 @@ lodash.isequal@^4.0.0, lodash.isequal@^4.5.0:
lodash.isinteger@^4.0.4:
version "4.0.4"
- resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
+ resolved "https://testnet.thegraph.com/npm-registry/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
lodash.ismatch@^4.4.0:
@@ -11061,17 +10959,17 @@ lodash.ismatch@^4.4.0:
lodash.isnumber@^3.0.3:
version "3.0.3"
- resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
+ resolved "https://testnet.thegraph.com/npm-registry/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
lodash.isplainobject@^4.0.6:
version "4.0.6"
- resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
+ resolved "https://testnet.thegraph.com/npm-registry/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.isstring@^4.0.1:
version "4.0.1"
- resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+ resolved "https://testnet.thegraph.com/npm-registry/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.keys@^4.0.0:
@@ -11248,7 +11146,7 @@ make-fetch-happen@^5.0.0:
make-iterator@^1.0.0:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6"
+ resolved "https://testnet.thegraph.com/npm-registry/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6"
integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==
dependencies:
kind-of "^6.0.2"
@@ -11739,7 +11637,7 @@ mkdirp-promise@^5.0.1:
dependencies:
mkdirp "*"
-mkdirp@*, mkdirp@^1.0.4:
+mkdirp@*:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@@ -12417,7 +12315,7 @@ object.assign@^4.1.0, object.assign@^4.1.1:
object.defaults@^1.1.0:
version "1.1.0"
- resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf"
+ resolved "https://testnet.thegraph.com/npm-registry/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf"
integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=
dependencies:
array-each "^1.0.1"
@@ -12454,7 +12352,7 @@ object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0
object.map@^1.0.0:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37"
+ resolved "https://testnet.thegraph.com/npm-registry/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37"
integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=
dependencies:
for-own "^1.0.0"
@@ -12485,9 +12383,9 @@ object.values@^1.1.0, object.values@^1.1.1:
function-bind "^1.1.1"
has "^1.0.3"
-objection@^2.1.3:
+objection@^2.2.3:
version "2.2.3"
- resolved "https://registry.yarnpkg.com/objection/-/objection-2.2.3.tgz#7509620b75a6907227cfb6a3fc4135222bb2e749"
+ resolved "https://testnet.thegraph.com/npm-registry/objection/-/objection-2.2.3.tgz#7509620b75a6907227cfb6a3fc4135222bb2e749"
integrity sha512-uNya9GuHlNeix7H0URthVE3+CmAlXmxkU69LAcRnncLjujJ8l1YX8JCB2GVSErTYS3Oc2xneF1ZWaR/MS8r63g==
dependencies:
ajv "^6.12.0"
@@ -12867,7 +12765,7 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5:
parse-filepath@^1.0.1:
version "1.0.2"
- resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
+ resolved "https://testnet.thegraph.com/npm-registry/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=
dependencies:
is-absolute "^1.0.0"
@@ -13024,12 +12922,12 @@ path-parse@^1.0.6:
path-root-regex@^0.1.0:
version "0.1.2"
- resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
+ resolved "https://testnet.thegraph.com/npm-registry/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=
path-root@^0.1.1:
version "0.1.1"
- resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
+ resolved "https://testnet.thegraph.com/npm-registry/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=
dependencies:
path-root-regex "^0.1.0"
@@ -13100,37 +12998,30 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-pg-connection-string@0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7"
- integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=
-
pg-connection-string@2.3.0:
version "2.3.0"
- resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.3.0.tgz#c13fcb84c298d0bfa9ba12b40dd6c23d946f55d6"
+ resolved "https://testnet.thegraph.com/npm-registry/pg-connection-string/-/pg-connection-string-2.3.0.tgz#c13fcb84c298d0bfa9ba12b40dd6c23d946f55d6"
integrity sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w==
-pg-hstore@^2.3.3:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.3.tgz#d1978c12a85359830b1388d3b0ff233b88928e96"
- integrity sha512-qpeTpdkguFgfdoidtfeTho1Q1zPVPbtMHgs8eQ+Aan05iLmIs3Z3oo5DOZRclPGoQ4i68I1kCtQSJSa7i0ZVYg==
- dependencies:
- underscore "^1.7.0"
+pg-connection-string@^2.4.0:
+ version "2.4.0"
+ resolved "https://testnet.thegraph.com/npm-registry/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10"
+ integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==
pg-int8@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
-pg-packet-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz#e45c3ae678b901a2873af1e17b92d787962ef914"
- integrity sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==
+pg-pool@^3.2.2:
+ version "3.2.2"
+ resolved "https://testnet.thegraph.com/npm-registry/pg-pool/-/pg-pool-3.2.2.tgz#a560e433443ed4ad946b84d774b3f22452694dff"
+ integrity sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==
-pg-pool@^2.0.10:
- version "2.0.10"
- resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.10.tgz#842ee23b04e86824ce9d786430f8365082d81c4a"
- integrity sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==
+pg-protocol@^1.3.0:
+ version "1.3.0"
+ resolved "https://testnet.thegraph.com/npm-registry/pg-protocol/-/pg-protocol-1.3.0.tgz#3c8fb7ca34dbbfcc42776ce34ac5f537d6e34770"
+ integrity sha512-64/bYByMrhWULUaCd+6/72c9PMWhiVFs3EVxl9Ct6a3v/U8+rKgqP2w+kKg/BIGgMJyB+Bk/eNivT32Al+Jghw==
pg-types@^2.1.0:
version "2.2.0"
@@ -13143,19 +13034,18 @@ pg-types@^2.1.0:
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
-pg@^7.18.2:
- version "7.18.2"
- resolved "https://registry.yarnpkg.com/pg/-/pg-7.18.2.tgz#4e219f05a00aff4db6aab1ba02f28ffa4513b0bb"
- integrity sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==
+pg@^8.4.2:
+ version "8.4.2"
+ resolved "https://testnet.thegraph.com/npm-registry/pg/-/pg-8.4.2.tgz#2aa58166a23391e91d56a7ea57c6d99931c0642a"
+ integrity sha512-E9FlUrrc7w3+sbRmL1CSw99vifACzB2TjhMM9J5w9D1LIg+6un0jKkpHS1EQf2CWhKhec2bhrBLVMmUBDbjPRQ==
dependencies:
buffer-writer "2.0.0"
packet-reader "1.0.0"
- pg-connection-string "0.1.3"
- pg-packet-stream "^1.1.0"
- pg-pool "^2.0.10"
+ pg-connection-string "^2.4.0"
+ pg-pool "^3.2.2"
+ pg-protocol "^1.3.0"
pg-types "^2.1.0"
pgpass "1.x"
- semver "4.3.2"
pgpass@1.x:
version "1.0.4"
@@ -14739,7 +14629,7 @@ realpath-native@^1.1.0:
rechoir@^0.6.2:
version "0.6.2"
- resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+ resolved "https://testnet.thegraph.com/npm-registry/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
dependencies:
resolve "^1.1.6"
@@ -15014,7 +14904,7 @@ resolve-cwd@^2.0.0:
resolve-dir@^1.0.0, resolve-dir@^1.0.1:
version "1.0.1"
- resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
+ resolved "https://testnet.thegraph.com/npm-registry/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=
dependencies:
expand-tilde "^2.0.0"
@@ -15380,11 +15270,6 @@ semver-diff@^3.1.1:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@4.3.2:
- version "4.3.2"
- resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7"
- integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=
-
semver@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db"
@@ -16371,10 +16256,10 @@ tar@^4, tar@^4.0.2, tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
safe-buffer "^5.1.2"
yallist "^3.0.3"
-tarn@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.0.tgz#a4082405216c0cce182b8b4cb2639c52c1e870d4"
- integrity sha512-PKUnlDFODZueoA8owLehl8vLcgtA8u4dRuVbZc92tspDYZixjJL6TqYOmryf/PfP/EBX+2rgNcrj96NO+RPkdQ==
+tarn@^3.0.1:
+ version "3.0.1"
+ resolved "https://testnet.thegraph.com/npm-registry/tarn/-/tarn-3.0.1.tgz#ebac2c6dbc6977d34d4526e0a7814200386a8aec"
+ integrity sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw==
tdigest@^0.1.1:
version "0.1.1"
@@ -16542,7 +16427,7 @@ tildify@1.2.0:
tildify@2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a"
+ resolved "https://testnet.thegraph.com/npm-registry/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a"
integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==
timed-out@^4.0.0, timed-out@^4.0.1:
@@ -16869,7 +16754,7 @@ unbzip2-stream@^1.0.9:
unc-path-regex@^0.1.2:
version "0.1.2"
- resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
+ resolved "https://testnet.thegraph.com/npm-registry/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
undefsafe@^2.0.3:
@@ -16884,11 +16769,6 @@ underscore@1.9.1:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
-underscore@^1.7.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.11.0.tgz#dd7c23a195db34267186044649870ff1bab5929e"
- integrity sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==
-
unicode-canonical-property-names-ecmascript@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
@@ -17179,11 +17059,6 @@ uuid@^3.0.1, uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-uuid@^7.0.3:
- version "7.0.3"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
- integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==
-
v8-compile-cache@^2.0.3:
version "2.1.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"