Merge branch 'main' into MNTOR-806/update-existing-emails

This commit is contained in:
Amri Toufali 2022-10-05 20:56:01 -07:00
Родитель fe282a9554 eff73b473b
Коммит 928a16f69f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 75269D7487754F5D
11 изменённых файлов: 48 добавлений и 9 удалений

Просмотреть файл

@ -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()