Merge branch 'main' into MNTOR-806/update-existing-emails
This commit is contained in:
Коммит
928a16f69f
|
@ -18,7 +18,7 @@ the "what" and "why" of data breach alerts.
|
|||
|
||||
### Requirements
|
||||
|
||||
* [Node](https://nodejs.org/) (with npm)
|
||||
* [Node](https://nodejs.org/) (with NPM): we recommend using [Node Version Manager](https://github.com/nvm-sh/nvm) to install and manage Node/NPM.
|
||||
* [Postgres](https://www.postgresql.org/)
|
||||
|
||||
### Code style
|
||||
|
@ -96,7 +96,7 @@ To create the database tables ...
|
|||
credentials:
|
||||
|
||||
```
|
||||
DATABASE_URL="postgres://<username>@localhost:<port>/blurts"
|
||||
DATABASE_URL="postgres://<username>:<password>@localhost:<port>/blurts"
|
||||
```
|
||||
|
||||
3. Run the migrations:
|
||||
|
@ -152,6 +152,8 @@ the `OAUTH_CLIENT_SECRET` value from someone in #fxmonitor-engineering.
|
|||
|
||||
The full test suite can be run via `npm test`.
|
||||
|
||||
At the beginning of a test suite run, the `test-blurts` database will be populated with test tables and seed data found in `db/seeds/`
|
||||
|
||||
At the end of a test suite run, coverage info will be sent to [Coveralls](https://coveralls.io/) to assess coverage changes and provide a neat badge. For this step to complete locally, you need a root `.coveralls.yml` which contains a token – get this from another member of the Monitor team. Alternatively, without the token you can simply ignore the `coveralls` error.
|
||||
|
||||
*TODO:* Disable Coveralls step for local testing?
|
||||
|
|
|
@ -38,6 +38,14 @@ function getAddressesAndLanguageForEmail (recipient) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever a breach is detected on the HIBP side, HIBP sends a request to this endpoint.
|
||||
* A breach notification contains the following parameters:
|
||||
* - breachName
|
||||
* - hashPrefix
|
||||
* - hashSuffixes
|
||||
* More about how account identities are anonymized: https://blog.mozilla.org/security/2018/06/25/scanning-breached-accounts-k-anonymity/
|
||||
*/
|
||||
async function notify (req, res) {
|
||||
if (!req.token || req.token !== AppConstants.HIBP_NOTIFY_TOKEN) {
|
||||
const errorMessage = 'HIBP notify endpoint requires valid authorization token.'
|
||||
|
|
|
@ -86,6 +86,9 @@
|
|||
"lint": "npm run lint:css && npm run lint:js",
|
||||
"lint:js": "eslint .",
|
||||
"lint:css": "stylelint public/css/",
|
||||
"fix": "npm run fix:css && npm run fix:js",
|
||||
"fix:js": "eslint . --fix",
|
||||
"fix:css": "stylelint public/css/ --fix",
|
||||
"test:db:migrate": "NODE_ENV=tests knex migrate:latest --knexfile db/knexfile.js --env tests",
|
||||
"test:tests": "NODE_ENV=tests HIBP_THROTTLE_DELAY=1000 HIBP_THROTTLE_MAX_TRIES=3 jest --runInBand --coverage tests/",
|
||||
"test:coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
const DB = require('../db/DB');
|
||||
|
||||
/**
|
||||
* Cron: Hourly
|
||||
* Delete any records of subscribers not verified within 24 hrs
|
||||
*/
|
||||
(async () => {
|
||||
await DB.deleteUnverifiedSubscribers()
|
||||
process.exit()
|
||||
|
|
|
@ -4,15 +4,19 @@ const readline = require('readline')
|
|||
|
||||
const DB = require('../db/DB')
|
||||
|
||||
/**
|
||||
* OBSOLETE
|
||||
* One-off script that deletes a subscriber record from the subscriber table
|
||||
*/
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
(async () => {
|
||||
rl.question('What FXA primary email address? ', first_answer => {
|
||||
rl.question('Please re-type the email address to confirm. ', async (second_answer) => {
|
||||
if (first_answer !== second_answer) {
|
||||
rl.question('What FXA primary email address? ', firstAnswer => {
|
||||
rl.question('Please re-type the email address to confirm. ', async (secondAnswer) => {
|
||||
if (firstAnswer !== secondAnswer) {
|
||||
console.error('Email addresses do not match.')
|
||||
process.exit(1)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ const knex = Knex(knexConfig)
|
|||
const HIBP = require('../hibp')
|
||||
const getSha1 = require('../sha1-utils')
|
||||
|
||||
/**
|
||||
* OBSOLETE
|
||||
* One-off script to lowercase email addresses of subscribers before hashing
|
||||
*/
|
||||
async function subscribeLowercaseHashToHIBP (emailAddress) {
|
||||
const lowerCasedEmail = emailAddress.toLowerCase()
|
||||
const lowerCasedSha1 = getSha1(lowerCasedEmail)
|
||||
|
|
|
@ -8,6 +8,9 @@ const hibp = require('../controllers/hibp')
|
|||
const { LocaleUtils } = require('../locale-utils')
|
||||
const sha1 = require('../sha1-utils')
|
||||
|
||||
/**
|
||||
* One-off script to send a breach email (test) to a subscriber
|
||||
*/
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
|
|
|
@ -4,7 +4,8 @@ const { LocaleUtils } = require('../locale-utils')
|
|||
const AppConstants = require('../app-constants')
|
||||
const { argv } = require('node:process')
|
||||
|
||||
/* Send a monthly email to each subscriber with unresolved breaches
|
||||
/* Cron: Hourly
|
||||
* Send a monthly email to each subscriber with unresolved breaches
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/send-email-to-unresolved-breach-subscribers.js
|
||||
|
|
|
@ -7,6 +7,11 @@ const knex = Knex(knexConfig)
|
|||
const HIBP = require('../hibp')
|
||||
const getSha1 = require('../sha1-utils')
|
||||
|
||||
/**
|
||||
* OBSOLETE
|
||||
* One-off script to find all non-lowercase email addresses
|
||||
* and lowercase them before hashing
|
||||
*/
|
||||
async function subscribeLowercaseHashToHIBP (emailAddress) {
|
||||
const lowerCasedEmail = emailAddress.toLowerCase()
|
||||
const lowerCasedSha1 = getSha1(lowerCasedEmail)
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Cron: Daily
|
||||
* From all the HIBP breaches, we parse out the new breaches that are not already present
|
||||
* in firefox remote settings, and update the data source accordingly
|
||||
*/
|
||||
const AppConstants = require('../app-constants')
|
||||
const HIBP = require('../hibp')
|
||||
const RemoteSettings = require('../lib/remote-settings')
|
||||
|
|
|
@ -55,13 +55,13 @@ const BreachRoutes = require('./routes/breach-details')
|
|||
const log = mozlog('server')
|
||||
|
||||
function getRedisStore () {
|
||||
const redisStoreConstructor = connectRedis(session)
|
||||
const RedisStoreConstructor = connectRedis(session)
|
||||
if (['', 'redis-mock'].includes(AppConstants.REDIS_URL)) {
|
||||
const redis = require('redis-mock')
|
||||
return new redisStoreConstructor({ client: redis.createClient() })
|
||||
return new RedisStoreConstructor({ client: redis.createClient() })
|
||||
}
|
||||
const redis = require('redis')
|
||||
return new redisStoreConstructor({ client: redis.createClient({ url: AppConstants.REDIS_URL }) })
|
||||
return new RedisStoreConstructor({ client: redis.createClient({ url: AppConstants.REDIS_URL }) })
|
||||
}
|
||||
|
||||
const app = express()
|
||||
|
|
Загрузка…
Ссылка в новой задаче