diff --git a/.circleci/.env b/.circleci/.env
new file mode 100644
index 0000000..45e5e71
--- /dev/null
+++ b/.circleci/.env
@@ -0,0 +1,7 @@
+FRONTEND_URL=https://test.com
+
+DATABASE_URL=mysql://user:password@localhost:3306/database
+CONNECTION_STR=mongodb://user:password@localhost:27017/database
+
+SESSION_SECRET=test
+EMAIL_SECRET=test
\ No newline at end of file
diff --git a/.circleci/config.yml b/.circleci/config.yml
new file mode 100644
index 0000000..a6c70bd
--- /dev/null
+++ b/.circleci/config.yml
@@ -0,0 +1,60 @@
+version: 2.1
+jobs:
+ build:
+ docker:
+ - image: circleci/node:12
+ - image: circleci/mysql:5.7
+ environment:
+ MYSQL_ROOT_PASSWORD: password
+ MYSQL_DATABASE: database
+ MYSQL_USER: user
+ MYSQL_PASSWORD: password
+ - image: mongo:latest
+ environment:
+ MONGO_INITDB_ROOT_USERNAME: root
+ MONGO_INITDB_ROOT_PASSWORD: password
+ MONGO_INITDB_DATABASE: database
+ working_directory: ~/build
+ steps:
+ - checkout
+ - run:
+ name: Install MongoDB Shell
+ command: |
+ curl https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -
+ echo "deb http://repo.mongodb.org/apt/debian stretch/mongodb-org/4.2 main" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list
+ sudo apt-get update
+ sudo apt-get install -y mongodb-org-shell
+ - run:
+ name: Configure MongoDB
+ command: mongo -u root -p password < ./mongo-init.js
+ - restore_cache:
+ keys:
+ - v1-dependencies-{{ checksum "package.json" }}
+ - v1-dependencies-
+ - run:
+ name: Install
+ command: npm install
+ - save_cache:
+ paths:
+ - node_modules
+ key: v1-dependencies-{{ checksum "package.json" }}
+ - run:
+ name: Test
+ command: npm run test #-circleci
+ deploy:
+ docker:
+ - image: circleci/node:12
+ steps:
+ - run: sudo apt-get install sshpass -y
+ - run: sshpass -p ${PASSWORD} ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password denis@35.225.244.173 './deploy.sh'
+workflows:
+ version: 2
+ build-and-deploy:
+ jobs:
+ - build
+ - deploy:
+ requires:
+ - build
+ filters:
+ branches:
+ only: feature/hw-12 # master, develop
diff --git a/.gitignore b/.gitignore
index 39e22bb..113cdaf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
node_modules
-.env
+/.env
service-key.json
-gcs-key.json
\ No newline at end of file
+gcs-key.json
+deploy.sh
\ No newline at end of file
diff --git a/__mocks__/@google-cloud/storage.js b/__mocks__/@google-cloud/storage.js
new file mode 100644
index 0000000..be1d31e
--- /dev/null
+++ b/__mocks__/@google-cloud/storage.js
@@ -0,0 +1,11 @@
+/* eslint-disable */
+
+class Storage {
+ constructor() {
+ this.bucket = jest.fn(() => {})
+ }
+ bucket() {
+ jest.fn(() => {})
+ }
+}
+module.exports = { Storage }
diff --git a/__mocks__/ioredis.js b/__mocks__/ioredis.js
new file mode 100644
index 0000000..8f153d7
--- /dev/null
+++ b/__mocks__/ioredis.js
@@ -0,0 +1,4 @@
+/* eslint-disable */
+const redis = require('redis-mock')
+
+module.exports = jest.fn(() => redis.createClient())
diff --git a/__mocks__/passport-facebook.js b/__mocks__/passport-facebook.js
new file mode 100644
index 0000000..f512644
--- /dev/null
+++ b/__mocks__/passport-facebook.js
@@ -0,0 +1,31 @@
+const { Strategy } = require('passport')
+const faker = require('faker')
+
+class MockStrategy extends Strategy {
+ constructor(options, verify) {
+ super()
+ this.user = {
+ id: faker.random.number(),
+ name: {
+ givenName: faker.name.firstName(),
+ familyName: faker.name.lastName()
+ },
+ _json: {
+ email: faker.internet.email()
+ }
+ }
+ this.name = 'facebook'
+ this.options = options
+ this.verify = verify
+ }
+
+ authenticate(req) {
+ if (req.query.code) return this.redirect('/')
+ this.verify(null, null, this.user, (err, user) => {
+ if (err) return this.fail(err)
+ return this.success(user)
+ })
+ }
+}
+
+module.exports = MockStrategy
diff --git a/__mocks__/passport-google-oauth20.js b/__mocks__/passport-google-oauth20.js
new file mode 100644
index 0000000..7cac013
--- /dev/null
+++ b/__mocks__/passport-google-oauth20.js
@@ -0,0 +1,29 @@
+const { Strategy } = require('passport')
+const faker = require('faker')
+
+class MockStrategy extends Strategy {
+ constructor(options, verify) {
+ super()
+ this.user = {
+ id: faker.random.number(),
+ _json: {
+ given_name: faker.name.firstName(),
+ family_name: faker.name.lastName(),
+ email: faker.internet.email()
+ }
+ }
+ this.name = 'google'
+ this.options = options
+ this.verify = verify
+ }
+
+ authenticate(req) {
+ if (req.query.code) return this.redirect('/')
+ this.verify(null, null, this.user, (err, user) => {
+ if (err) return this.fail(err)
+ return this.success(user)
+ })
+ }
+}
+
+module.exports = MockStrategy
diff --git a/__mocks__/sharp.js b/__mocks__/sharp.js
new file mode 100644
index 0000000..49e4b9c
--- /dev/null
+++ b/__mocks__/sharp.js
@@ -0,0 +1,7 @@
+const { Transform } = require('stream')
+
+const resize = new Transform({
+ transform: (chunk, enc, done) => done(null, chunk)
+})
+
+module.exports = () => ({ resize: () => resize })
diff --git a/__mocks__/stripe.js b/__mocks__/stripe.js
new file mode 100644
index 0000000..d691086
--- /dev/null
+++ b/__mocks__/stripe.js
@@ -0,0 +1,6 @@
+/* eslint-disable */
+class Stripe {}
+const stripe = jest.fn(() => new Stripe())
+
+module.exports = stripe
+module.exports.Stripe = Stripe
diff --git a/__mocks__/winston.js b/__mocks__/winston.js
new file mode 100644
index 0000000..2d73cef
--- /dev/null
+++ b/__mocks__/winston.js
@@ -0,0 +1,21 @@
+/* eslint-disable */
+const winston = {
+ format: {
+ combine: jest.fn(),
+ splat: jest.fn(),
+ simple: jest.fn()
+ },
+ transports: jest.fn(),
+ createLogger: jest.fn(() => {
+ return {
+ info: jest.fn(),
+ error: jest.fn(),
+ end: jest.fn()
+ }
+ })
+}
+
+winston.transports.Console = jest.fn()
+winston.transports.MongoDB = jest.fn()
+
+module.exports = winston
diff --git a/coverage/clover.xml b/coverage/clover.xml
new file mode 100644
index 0000000..b7e8e86
--- /dev/null
+++ b/coverage/clover.xml
@@ -0,0 +1,770 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json
new file mode 100644
index 0000000..7641316
--- /dev/null
+++ b/coverage/coverage-final.json
@@ -0,0 +1,37 @@
+{"/home/denis/Zazmic_Internship/hw5/index.js": {"path":"/home/denis/Zazmic_Internship/hw5/index.js","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},"1":{"start":{"line":2,"column":13},"end":{"line":2,"column":28}},"2":{"start":{"line":3,"column":16},"end":{"line":3,"column":34}},"3":{"start":{"line":4,"column":16},"end":{"line":4,"column":42}},"4":{"start":{"line":5,"column":17},"end":{"line":5,"column":36}},"5":{"start":{"line":8,"column":24},"end":{"line":8,"column":52}},"6":{"start":{"line":11,"column":11},"end":{"line":11,"column":39}},"7":{"start":{"line":12,"column":0},"end":{"line":12,"column":36}},"8":{"start":{"line":14,"column":21},"end":{"line":14,"column":45}},"9":{"start":{"line":15,"column":22},"end":{"line":15,"column":43}},"10":{"start":{"line":16,"column":15},"end":{"line":16,"column":56}},"11":{"start":{"line":19,"column":12},"end":{"line":19,"column":21}},"12":{"start":{"line":21,"column":0},"end":{"line":21,"column":61}},"13":{"start":{"line":22,"column":0},"end":{"line":22,"column":23}},"14":{"start":{"line":25,"column":15},"end":{"line":25,"column":67}},"15":{"start":{"line":26,"column":0},"end":{"line":34,"column":1}},"16":{"start":{"line":35,"column":0},"end":{"line":35,"column":30}},"17":{"start":{"line":36,"column":0},"end":{"line":36,"column":27}},"18":{"start":{"line":38,"column":0},"end":{"line":38,"column":25}},"19":{"start":{"line":40,"column":45},"end":{"line":40,"column":91}},"20":{"start":{"line":41,"column":0},"end":{"line":41,"column":32}},"21":{"start":{"line":42,"column":0},"end":{"line":42,"column":33}},"22":{"start":{"line":43,"column":0},"end":{"line":43,"column":35}},"23":{"start":{"line":44,"column":0},"end":{"line":44,"column":38}},"24":{"start":{"line":47,"column":0},"end":{"line":47,"column":37}},"25":{"start":{"line":50,"column":15},"end":{"line":50,"column":34}},"26":{"start":{"line":51,"column":0},"end":{"line":51,"column":15}},"27":{"start":{"line":54,"column":0},"end":{"line":58,"column":2}},"28":{"start":{"line":55,"column":15},"end":{"line":55,"column":37}},"29":{"start":{"line":56,"column":1},"end":{"line":56,"column":19}},"30":{"start":{"line":57,"column":1},"end":{"line":57,"column":12}},"31":{"start":{"line":59,"column":0},"end":{"line":62,"column":2}},"32":{"start":{"line":60,"column":1},"end":{"line":60,"column":32}},"33":{"start":{"line":61,"column":1},"end":{"line":61,"column":26}},"34":{"start":{"line":64,"column":15},"end":{"line":64,"column":37}},"35":{"start":{"line":66,"column":11},"end":{"line":66,"column":73}},"36":{"start":{"line":67,"column":0},"end":{"line":67,"column":23}},"37":{"start":{"line":70,"column":0},"end":{"line":77,"column":90}},"38":{"start":{"line":72,"column":2},"end":{"line":75,"column":4}},"39":{"start":{"line":73,"column":3},"end":{"line":73,"column":84}},"40":{"start":{"line":73,"column":12},"end":{"line":73,"column":84}},"41":{"start":{"line":74,"column":3},"end":{"line":74,"column":44}},"42":{"start":{"line":77,"column":15},"end":{"line":77,"column":89}},"43":{"start":{"line":79,"column":0},"end":{"line":79,"column":20}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":54,"column":8},"end":{"line":54,"column":9}},"loc":{"start":{"line":54,"column":28},"end":{"line":58,"column":1}},"line":54},"1":{"name":"(anonymous_1)","decl":{"start":{"line":59,"column":8},"end":{"line":59,"column":9}},"loc":{"start":{"line":59,"column":35},"end":{"line":62,"column":1}},"line":59},"2":{"name":"(anonymous_2)","decl":{"start":{"line":71,"column":7},"end":{"line":71,"column":8}},"loc":{"start":{"line":71,"column":13},"end":{"line":76,"column":2}},"line":71},"3":{"name":"(anonymous_3)","decl":{"start":{"line":72,"column":34},"end":{"line":72,"column":35}},"loc":{"start":{"line":72,"column":41},"end":{"line":75,"column":3}},"line":72},"4":{"name":"(anonymous_4)","decl":{"start":{"line":77,"column":8},"end":{"line":77,"column":9}},"loc":{"start":{"line":77,"column":15},"end":{"line":77,"column":89}},"line":77}},"branchMap":{"0":{"loc":{"start":{"line":60,"column":12},"end":{"line":60,"column":31}},"type":"binary-expr","locations":[{"start":{"line":60,"column":12},"end":{"line":60,"column":24}},{"start":{"line":60,"column":28},"end":{"line":60,"column":31}}],"line":60},"1":{"loc":{"start":{"line":73,"column":3},"end":{"line":73,"column":84}},"type":"if","locations":[{"start":{"line":73,"column":3},"end":{"line":73,"column":84}},{"start":{"line":73,"column":3},"end":{"line":73,"column":84}}],"line":73}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":0,"29":0,"30":0,"31":1,"32":0,"33":0,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":0,"41":1,"42":0,"43":1},"f":{"0":0,"1":0,"2":1,"3":1,"4":0},"b":{"0":[0,0],"1":[0,1]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"2af4d039199d816c5d66a8e1fbfe0617c07e7492"}
+,"/home/denis/Zazmic_Internship/hw5/db/constant.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/constant.js","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":5,"column":1}}},"fnMap":{},"branchMap":{},"s":{"0":1},"f":{},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"703d04588295e0ef0bcd527c13c626d4f7f6005f"}
+,"/home/denis/Zazmic_Internship/hw5/db/dbConnection.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/dbConnection.js","statementMap":{"0":{"start":{"line":1,"column":18},"end":{"line":1,"column":38}},"1":{"start":{"line":3,"column":0},"end":{"line":13,"column":2}}},"fnMap":{},"branchMap":{},"s":{"0":1,"1":1},"f":{},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"8d66b75cdc2afb38c5e9efd27550ffd5ef546703"}
+,"/home/denis/Zazmic_Internship/hw5/db/models/Articles.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/models/Articles.js","statementMap":{"0":{"start":{"line":1,"column":29},"end":{"line":1,"column":49}},"1":{"start":{"line":2,"column":18},"end":{"line":2,"column":44}},"2":{"start":{"line":6,"column":0},"end":{"line":54,"column":1}},"3":{"start":{"line":56,"column":0},"end":{"line":59,"column":1}},"4":{"start":{"line":57,"column":1},"end":{"line":57,"column":75}},"5":{"start":{"line":58,"column":1},"end":{"line":58,"column":79}},"6":{"start":{"line":61,"column":0},"end":{"line":61,"column":25}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":56,"column":21},"end":{"line":56,"column":22}},"loc":{"start":{"line":56,"column":31},"end":{"line":59,"column":1}},"line":56}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"53763d3b281b361ca68ab61fef1eadade8d18646"}
+,"/home/denis/Zazmic_Internship/hw5/db/models/Comments.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/models/Comments.js","statementMap":{"0":{"start":{"line":1,"column":29},"end":{"line":1,"column":49}},"1":{"start":{"line":2,"column":18},"end":{"line":2,"column":44}},"2":{"start":{"line":6,"column":0},"end":{"line":40,"column":1}},"3":{"start":{"line":42,"column":0},"end":{"line":45,"column":1}},"4":{"start":{"line":43,"column":1},"end":{"line":43,"column":75}},"5":{"start":{"line":44,"column":1},"end":{"line":44,"column":80}},"6":{"start":{"line":47,"column":0},"end":{"line":47,"column":25}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":42,"column":21},"end":{"line":42,"column":22}},"loc":{"start":{"line":42,"column":31},"end":{"line":45,"column":1}},"line":42}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"07447a4ff26a1120a0e8dc1848605732bfdc1d75"}
+,"/home/denis/Zazmic_Internship/hw5/db/models/Providers.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/models/Providers.js","statementMap":{"0":{"start":{"line":1,"column":29},"end":{"line":1,"column":49}},"1":{"start":{"line":2,"column":18},"end":{"line":2,"column":44}},"2":{"start":{"line":6,"column":0},"end":{"line":35,"column":1}},"3":{"start":{"line":37,"column":0},"end":{"line":42,"column":1}},"4":{"start":{"line":38,"column":1},"end":{"line":41,"column":3}},"5":{"start":{"line":44,"column":0},"end":{"line":44,"column":26}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":37,"column":22},"end":{"line":37,"column":23}},"loc":{"start":{"line":37,"column":32},"end":{"line":42,"column":1}},"line":37}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"93c7bbee4819890a4964be6ace532ab9759eb282"}
+,"/home/denis/Zazmic_Internship/hw5/db/models/Users.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/models/Users.js","statementMap":{"0":{"start":{"line":1,"column":29},"end":{"line":1,"column":49}},"1":{"start":{"line":2,"column":18},"end":{"line":2,"column":44}},"2":{"start":{"line":3,"column":25},"end":{"line":3,"column":58}},"3":{"start":{"line":7,"column":0},"end":{"line":87,"column":1}},"4":{"start":{"line":89,"column":0},"end":{"line":93,"column":1}},"5":{"start":{"line":90,"column":1},"end":{"line":90,"column":75}},"6":{"start":{"line":91,"column":1},"end":{"line":91,"column":80}},"7":{"start":{"line":92,"column":1},"end":{"line":92,"column":75}},"8":{"start":{"line":95,"column":0},"end":{"line":95,"column":22}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":89,"column":18},"end":{"line":89,"column":19}},"loc":{"start":{"line":89,"column":28},"end":{"line":93,"column":1}},"line":89}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"961bbb413915188160c6a8e2ccc7b94f9686835d"}
+,"/home/denis/Zazmic_Internship/hw5/db/models/index.js": {"path":"/home/denis/Zazmic_Internship/hw5/db/models/index.js","statementMap":{"0":{"start":{"line":1,"column":15},"end":{"line":6,"column":1}},"1":{"start":{"line":8,"column":19},"end":{"line":8,"column":38}},"2":{"start":{"line":10,"column":0},"end":{"line":14,"column":2}},"3":{"start":{"line":11,"column":1},"end":{"line":13,"column":2}},"4":{"start":{"line":12,"column":2},"end":{"line":12,"column":37}},"5":{"start":{"line":16,"column":0},"end":{"line":16,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":10,"column":19},"end":{"line":10,"column":20}},"loc":{"start":{"line":10,"column":32},"end":{"line":14,"column":1}},"line":10}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":1},"end":{"line":13,"column":2}},"type":"if","locations":[{"start":{"line":11,"column":1},"end":{"line":13,"column":2}},{"start":{"line":11,"column":1},"end":{"line":13,"column":2}}],"line":11}},"s":{"0":1,"1":1,"2":1,"3":4,"4":4,"5":1},"f":{"0":4},"b":{"0":[4,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"d9bed98b60d38c7a537e082138bfb11f8032b069"}
+,"/home/denis/Zazmic_Internship/hw5/mongodb/mongoConnection.js": {"path":"/home/denis/Zazmic_Internship/hw5/mongodb/mongoConnection.js","statementMap":{"0":{"start":{"line":1,"column":17},"end":{"line":1,"column":36}},"1":{"start":{"line":5,"column":2},"end":{"line":12,"column":3}},"2":{"start":{"line":6,"column":3},"end":{"line":9,"column":5}},"3":{"start":{"line":11,"column":3},"end":{"line":11,"column":10}},"4":{"start":{"line":15,"column":0},"end":{"line":15,"column":19}},"5":{"start":{"line":17,"column":0},"end":{"line":17,"column":26}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":4,"column":1},"end":{"line":4,"column":2}},"loc":{"start":{"line":4,"column":24},"end":{"line":13,"column":2}},"line":4}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":0,"4":1,"5":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"bef40774ca1fd1e0eba82d08e42e314dbc2847ac"}
+,"/home/denis/Zazmic_Internship/hw5/mongodb/queries.js": {"path":"/home/denis/Zazmic_Internship/hw5/mongodb/queries.js","statementMap":{"0":{"start":{"line":1,"column":22},"end":{"line":1,"column":55}},"1":{"start":{"line":2,"column":56},"end":{"line":2,"column":87}},"2":{"start":{"line":4,"column":0},"end":{"line":6,"column":87}},"3":{"start":{"line":5,"column":13},"end":{"line":5,"column":67}},"4":{"start":{"line":6,"column":13},"end":{"line":6,"column":86}},"5":{"start":{"line":8,"column":19},"end":{"line":16,"column":1}},"6":{"start":{"line":9,"column":1},"end":{"line":15,"column":2}},"7":{"start":{"line":10,"column":2},"end":{"line":10,"column":34}},"8":{"start":{"line":11,"column":2},"end":{"line":11,"column":89}},"9":{"start":{"line":13,"column":2},"end":{"line":13,"column":77}},"10":{"start":{"line":14,"column":2},"end":{"line":14,"column":13}},"11":{"start":{"line":18,"column":19},"end":{"line":26,"column":1}},"12":{"start":{"line":19,"column":1},"end":{"line":25,"column":2}},"13":{"start":{"line":20,"column":2},"end":{"line":20,"column":64}},"14":{"start":{"line":21,"column":2},"end":{"line":21,"column":83}},"15":{"start":{"line":23,"column":2},"end":{"line":23,"column":77}},"16":{"start":{"line":24,"column":2},"end":{"line":24,"column":13}},"17":{"start":{"line":28,"column":16},"end":{"line":39,"column":1}},"18":{"start":{"line":29,"column":1},"end":{"line":38,"column":2}},"19":{"start":{"line":30,"column":22},"end":{"line":30,"column":108}},"20":{"start":{"line":31,"column":16},"end":{"line":31,"column":42}},"21":{"start":{"line":32,"column":2},"end":{"line":32,"column":83}},"22":{"start":{"line":33,"column":2},"end":{"line":33,"column":82}},"23":{"start":{"line":34,"column":2},"end":{"line":34,"column":14}},"24":{"start":{"line":36,"column":2},"end":{"line":36,"column":77}},"25":{"start":{"line":37,"column":2},"end":{"line":37,"column":13}},"26":{"start":{"line":41,"column":17},"end":{"line":48,"column":1}},"27":{"start":{"line":42,"column":1},"end":{"line":47,"column":2}},"28":{"start":{"line":43,"column":2},"end":{"line":43,"column":35}},"29":{"start":{"line":45,"column":2},"end":{"line":45,"column":77}},"30":{"start":{"line":46,"column":2},"end":{"line":46,"column":13}},"31":{"start":{"line":50,"column":0},"end":{"line":50,"column":62}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":7},"end":{"line":5,"column":8}},"loc":{"start":{"line":5,"column":13},"end":{"line":5,"column":67}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":6,"column":8},"end":{"line":6,"column":9}},"loc":{"start":{"line":6,"column":13},"end":{"line":6,"column":86}},"line":6},"2":{"name":"(anonymous_2)","decl":{"start":{"line":8,"column":19},"end":{"line":8,"column":20}},"loc":{"start":{"line":8,"column":33},"end":{"line":16,"column":1}},"line":8},"3":{"name":"(anonymous_3)","decl":{"start":{"line":18,"column":19},"end":{"line":18,"column":20}},"loc":{"start":{"line":18,"column":38},"end":{"line":26,"column":1}},"line":18},"4":{"name":"(anonymous_4)","decl":{"start":{"line":28,"column":16},"end":{"line":28,"column":17}},"loc":{"start":{"line":28,"column":35},"end":{"line":39,"column":1}},"line":28},"5":{"name":"(anonymous_5)","decl":{"start":{"line":41,"column":17},"end":{"line":41,"column":18}},"loc":{"start":{"line":41,"column":29},"end":{"line":48,"column":1}},"line":41}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0,"11":1,"12":0,"13":0,"14":0,"15":0,"16":0,"17":1,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":1,"27":0,"28":0,"29":0,"30":0,"31":1},"f":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"b5984df6b089a59691ca0a8ed7252c4c645d3afa"}
+,"/home/denis/Zazmic_Internship/hw5/mongodb/models/ArticlesViews.js": {"path":"/home/denis/Zazmic_Internship/hw5/mongodb/models/ArticlesViews.js","statementMap":{"0":{"start":{"line":1,"column":17},"end":{"line":1,"column":36}},"1":{"start":{"line":2,"column":19},"end":{"line":2,"column":27}},"2":{"start":{"line":4,"column":27},"end":{"line":4,"column":59}},"3":{"start":{"line":6,"column":22},"end":{"line":12,"column":2}},"4":{"start":{"line":14,"column":0},"end":{"line":17,"column":2}},"5":{"start":{"line":15,"column":1},"end":{"line":15,"column":36}},"6":{"start":{"line":16,"column":1},"end":{"line":16,"column":7}},"7":{"start":{"line":19,"column":0},"end":{"line":22,"column":2}},"8":{"start":{"line":20,"column":1},"end":{"line":20,"column":36}},"9":{"start":{"line":21,"column":1},"end":{"line":21,"column":7}},"10":{"start":{"line":25,"column":0},"end":{"line":28,"column":2}},"11":{"start":{"line":26,"column":13},"end":{"line":26,"column":43}},"12":{"start":{"line":26,"column":29},"end":{"line":26,"column":42}},"13":{"start":{"line":27,"column":1},"end":{"line":27,"column":68}},"14":{"start":{"line":30,"column":0},"end":{"line":32,"column":2}},"15":{"start":{"line":31,"column":1},"end":{"line":31,"column":72}},"16":{"start":{"line":33,"column":0},"end":{"line":35,"column":2}},"17":{"start":{"line":34,"column":1},"end":{"line":34,"column":72}},"18":{"start":{"line":37,"column":0},"end":{"line":39,"column":2}},"19":{"start":{"line":38,"column":1},"end":{"line":38,"column":72}},"20":{"start":{"line":41,"column":0},"end":{"line":41,"column":63}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":14,"column":31},"end":{"line":14,"column":32}},"loc":{"start":{"line":14,"column":46},"end":{"line":17,"column":1}},"line":14},"1":{"name":"(anonymous_1)","decl":{"start":{"line":19,"column":26},"end":{"line":19,"column":27}},"loc":{"start":{"line":19,"column":41},"end":{"line":22,"column":1}},"line":19},"2":{"name":"(anonymous_2)","decl":{"start":{"line":25,"column":27},"end":{"line":25,"column":28}},"loc":{"start":{"line":25,"column":42},"end":{"line":28,"column":1}},"line":25},"3":{"name":"(anonymous_3)","decl":{"start":{"line":26,"column":22},"end":{"line":26,"column":23}},"loc":{"start":{"line":26,"column":29},"end":{"line":26,"column":42}},"line":26},"4":{"name":"(anonymous_4)","decl":{"start":{"line":30,"column":39},"end":{"line":30,"column":40}},"loc":{"start":{"line":30,"column":53},"end":{"line":32,"column":1}},"line":30},"5":{"name":"(anonymous_5)","decl":{"start":{"line":33,"column":39},"end":{"line":33,"column":40}},"loc":{"start":{"line":33,"column":53},"end":{"line":35,"column":1}},"line":33},"6":{"name":"(anonymous_6)","decl":{"start":{"line":37,"column":27},"end":{"line":37,"column":28}},"loc":{"start":{"line":37,"column":41},"end":{"line":39,"column":1}},"line":37}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":0,"6":0,"7":1,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":1,"15":0,"16":1,"17":0,"18":1,"19":0,"20":1},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"303c9e3bcedda07f9ecac61167b5f241da7746e4"}
+,"/home/denis/Zazmic_Internship/hw5/routes/auth.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/auth.js","statementMap":{"0":{"start":{"line":8,"column":16},"end":{"line":8,"column":34}},"1":{"start":{"line":9,"column":15},"end":{"line":9,"column":31}},"2":{"start":{"line":10,"column":21},"end":{"line":10,"column":53}},"3":{"start":{"line":11,"column":17},"end":{"line":11,"column":36}},"4":{"start":{"line":12,"column":12},"end":{"line":12,"column":35}},"5":{"start":{"line":14,"column":18},"end":{"line":14,"column":50}},"6":{"start":{"line":15,"column":0},"end":{"line":15,"column":48}},"7":{"start":{"line":16,"column":36},"end":{"line":16,"column":66}},"8":{"start":{"line":17,"column":52},"end":{"line":17,"column":92}},"9":{"start":{"line":18,"column":28},"end":{"line":18,"column":63}},"10":{"start":{"line":19,"column":23},"end":{"line":19,"column":48}},"11":{"start":{"line":21,"column":0},"end":{"line":49,"column":1}},"12":{"start":{"line":25,"column":19},"end":{"line":25,"column":76}},"13":{"start":{"line":26,"column":2},"end":{"line":47,"column":3}},"14":{"start":{"line":27,"column":3},"end":{"line":27,"column":18}},"15":{"start":{"line":28,"column":3},"end":{"line":28,"column":67}},"16":{"start":{"line":30,"column":20},"end":{"line":35,"column":4}},"17":{"start":{"line":36,"column":19},"end":{"line":36,"column":47}},"18":{"start":{"line":37,"column":23},"end":{"line":37,"column":51}},"19":{"start":{"line":38,"column":3},"end":{"line":46,"column":5}},"20":{"start":{"line":39,"column":4},"end":{"line":39,"column":56}},"21":{"start":{"line":39,"column":13},"end":{"line":39,"column":56}},"22":{"start":{"line":40,"column":23},"end":{"line":40,"column":70}},"23":{"start":{"line":41,"column":4},"end":{"line":44,"column":6}},"24":{"start":{"line":45,"column":4},"end":{"line":45,"column":31}},"25":{"start":{"line":51,"column":0},"end":{"line":64,"column":2}},"26":{"start":{"line":52,"column":1},"end":{"line":63,"column":2}},"27":{"start":{"line":53,"column":18},"end":{"line":53,"column":63}},"28":{"start":{"line":54,"column":19},"end":{"line":54,"column":44}},"29":{"start":{"line":55,"column":2},"end":{"line":55,"column":45}},"30":{"start":{"line":56,"column":13},"end":{"line":56,"column":42}},"31":{"start":{"line":57,"column":2},"end":{"line":60,"column":4}},"32":{"start":{"line":58,"column":3},"end":{"line":58,"column":48}},"33":{"start":{"line":58,"column":12},"end":{"line":58,"column":48}},"34":{"start":{"line":59,"column":3},"end":{"line":59,"column":27}},"35":{"start":{"line":62,"column":2},"end":{"line":62,"column":77}},"36":{"start":{"line":66,"column":0},"end":{"line":73,"column":1}},"37":{"start":{"line":72,"column":15},"end":{"line":72,"column":43}},"38":{"start":{"line":75,"column":0},"end":{"line":75,"column":54}},"39":{"start":{"line":75,"column":37},"end":{"line":75,"column":53}},"40":{"start":{"line":80,"column":0},"end":{"line":84,"column":2}},"41":{"start":{"line":81,"column":1},"end":{"line":83,"column":3}},"42":{"start":{"line":82,"column":2},"end":{"line":82,"column":86}},"43":{"start":{"line":86,"column":0},"end":{"line":92,"column":2}},"44":{"start":{"line":87,"column":14},"end":{"line":87,"column":68}},"45":{"start":{"line":88,"column":1},"end":{"line":88,"column":24}},"46":{"start":{"line":89,"column":1},"end":{"line":91,"column":3}},"47":{"start":{"line":90,"column":2},"end":{"line":90,"column":49}},"48":{"start":{"line":96,"column":22},"end":{"line":96,"column":50}},"49":{"start":{"line":97,"column":1},"end":{"line":106,"column":2}},"50":{"start":{"line":99,"column":17},"end":{"line":99,"column":40}},"51":{"start":{"line":100,"column":22},"end":{"line":100,"column":31}},"52":{"start":{"line":101,"column":2},"end":{"line":101,"column":25}},"53":{"start":{"line":102,"column":2},"end":{"line":102,"column":8}},"54":{"start":{"line":105,"column":2},"end":{"line":105,"column":21}},"55":{"start":{"line":109,"column":0},"end":{"line":109,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":24,"column":14},"end":{"line":24,"column":15}},"loc":{"start":{"line":24,"column":34},"end":{"line":48,"column":2}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":38,"column":71},"end":{"line":38,"column":72}},"loc":{"start":{"line":38,"column":93},"end":{"line":46,"column":4}},"line":38},"2":{"name":"(anonymous_2)","decl":{"start":{"line":51,"column":36},"end":{"line":51,"column":37}},"loc":{"start":{"line":51,"column":56},"end":{"line":64,"column":1}},"line":51},"3":{"name":"(anonymous_3)","decl":{"start":{"line":57,"column":24},"end":{"line":57,"column":25}},"loc":{"start":{"line":57,"column":31},"end":{"line":60,"column":3}},"line":57},"4":{"name":"(anonymous_4)","decl":{"start":{"line":72,"column":1},"end":{"line":72,"column":2}},"loc":{"start":{"line":72,"column":15},"end":{"line":72,"column":43}},"line":72},"5":{"name":"(anonymous_5)","decl":{"start":{"line":75,"column":23},"end":{"line":75,"column":24}},"loc":{"start":{"line":75,"column":37},"end":{"line":75,"column":53}},"line":75},"6":{"name":"(anonymous_6)","decl":{"start":{"line":80,"column":48},"end":{"line":80,"column":49}},"loc":{"start":{"line":80,"column":62},"end":{"line":84,"column":1}},"line":80},"7":{"name":"(anonymous_7)","decl":{"start":{"line":81,"column":36},"end":{"line":81,"column":37}},"loc":{"start":{"line":81,"column":55},"end":{"line":83,"column":2}},"line":81},"8":{"name":"(anonymous_8)","decl":{"start":{"line":86,"column":26},"end":{"line":86,"column":27}},"loc":{"start":{"line":86,"column":40},"end":{"line":92,"column":1}},"line":86},"9":{"name":"(anonymous_9)","decl":{"start":{"line":89,"column":79},"end":{"line":89,"column":80}},"loc":{"start":{"line":89,"column":95},"end":{"line":91,"column":2}},"line":89},"10":{"name":"verifyToken","decl":{"start":{"line":94,"column":9},"end":{"line":94,"column":20}},"loc":{"start":{"line":94,"column":37},"end":{"line":107,"column":1}},"line":94}},"branchMap":{"0":{"loc":{"start":{"line":26,"column":2},"end":{"line":47,"column":3}},"type":"if","locations":[{"start":{"line":26,"column":2},"end":{"line":47,"column":3}},{"start":{"line":26,"column":2},"end":{"line":47,"column":3}}],"line":26},"1":{"loc":{"start":{"line":39,"column":4},"end":{"line":39,"column":56}},"type":"if","locations":[{"start":{"line":39,"column":4},"end":{"line":39,"column":56}},{"start":{"line":39,"column":4},"end":{"line":39,"column":56}}],"line":39},"2":{"loc":{"start":{"line":58,"column":3},"end":{"line":58,"column":48}},"type":"if","locations":[{"start":{"line":58,"column":3},"end":{"line":58,"column":48}},{"start":{"line":58,"column":3},"end":{"line":58,"column":48}}],"line":58},"3":{"loc":{"start":{"line":82,"column":2},"end":{"line":82,"column":86}},"type":"cond-expr","locations":[{"start":{"line":82,"column":8},"end":{"line":82,"column":27}},{"start":{"line":82,"column":30},"end":{"line":82,"column":86}}],"line":82},"4":{"loc":{"start":{"line":90,"column":2},"end":{"line":90,"column":49}},"type":"cond-expr","locations":[{"start":{"line":90,"column":8},"end":{"line":90,"column":27}},{"start":{"line":90,"column":30},"end":{"line":90,"column":49}}],"line":90},"5":{"loc":{"start":{"line":97,"column":1},"end":{"line":106,"column":2}},"type":"if","locations":[{"start":{"line":97,"column":1},"end":{"line":106,"column":2}},{"start":{"line":97,"column":1},"end":{"line":106,"column":2}}],"line":97}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":0,"15":0,"16":1,"17":1,"18":1,"19":1,"20":1,"21":0,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":0,"34":1,"35":0,"36":1,"37":0,"38":1,"39":1,"40":1,"41":0,"42":0,"43":1,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":1},"f":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[0,1],"1":[0,1],"2":[0,1],"3":[0,0],"4":[0,0],"5":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"1ffaddb912d89ba7e2a761741576496069bf6375"}
+,"/home/denis/Zazmic_Internship/hw5/routes/blogs.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/blogs.js","statementMap":{"0":{"start":{"line":12,"column":16},"end":{"line":12,"column":34}},"1":{"start":{"line":13,"column":15},"end":{"line":13,"column":31}},"2":{"start":{"line":14,"column":21},"end":{"line":14,"column":53}},"3":{"start":{"line":16,"column":38},"end":{"line":16,"column":70}},"4":{"start":{"line":17,"column":74},"end":{"line":17,"column":103}},"5":{"start":{"line":18,"column":34},"end":{"line":18,"column":64}},"6":{"start":{"line":19,"column":18},"end":{"line":19,"column":62}},"7":{"start":{"line":20,"column":27},"end":{"line":20,"column":56}},"8":{"start":{"line":21,"column":33},"end":{"line":21,"column":72}},"9":{"start":{"line":22,"column":37},"end":{"line":22,"column":78}},"10":{"start":{"line":23,"column":49},"end":{"line":23,"column":89}},"11":{"start":{"line":25,"column":0},"end":{"line":33,"column":1}},"12":{"start":{"line":28,"column":19},"end":{"line":28,"column":59}},"13":{"start":{"line":29,"column":16},"end":{"line":29,"column":32}},"14":{"start":{"line":30,"column":2},"end":{"line":30,"column":40}},"15":{"start":{"line":31,"column":2},"end":{"line":31,"column":30}},"16":{"start":{"line":35,"column":0},"end":{"line":47,"column":1}},"17":{"start":{"line":39,"column":19},"end":{"line":39,"column":23}},"18":{"start":{"line":40,"column":2},"end":{"line":40,"column":33}},"19":{"start":{"line":41,"column":2},"end":{"line":41,"column":48}},"20":{"start":{"line":41,"column":16},"end":{"line":41,"column":48}},"21":{"start":{"line":42,"column":2},"end":{"line":42,"column":53}},"22":{"start":{"line":43,"column":2},"end":{"line":43,"column":89}},"23":{"start":{"line":44,"column":2},"end":{"line":44,"column":21}},"24":{"start":{"line":45,"column":2},"end":{"line":45,"column":32}},"25":{"start":{"line":48,"column":0},"end":{"line":64,"column":1}},"26":{"start":{"line":52,"column":15},"end":{"line":52,"column":94}},"27":{"start":{"line":53,"column":22},"end":{"line":53,"column":47}},"28":{"start":{"line":54,"column":2},"end":{"line":62,"column":3}},"29":{"start":{"line":55,"column":24},"end":{"line":55,"column":28}},"30":{"start":{"line":56,"column":3},"end":{"line":56,"column":49}},"31":{"start":{"line":56,"column":17},"end":{"line":56,"column":49}},"32":{"start":{"line":57,"column":3},"end":{"line":57,"column":82}},"33":{"start":{"line":57,"column":28},"end":{"line":57,"column":82}},"34":{"start":{"line":58,"column":3},"end":{"line":58,"column":92}},"35":{"start":{"line":59,"column":3},"end":{"line":59,"column":77}},"36":{"start":{"line":61,"column":3},"end":{"line":61,"column":22}},"37":{"start":{"line":66,"column":0},"end":{"line":77,"column":1}},"38":{"start":{"line":69,"column":18},"end":{"line":72,"column":4}},"39":{"start":{"line":73,"column":16},"end":{"line":73,"column":45}},"40":{"start":{"line":74,"column":2},"end":{"line":74,"column":34}},"41":{"start":{"line":75,"column":2},"end":{"line":75,"column":29}},"42":{"start":{"line":79,"column":0},"end":{"line":93,"column":1}},"43":{"start":{"line":82,"column":15},"end":{"line":82,"column":94}},"44":{"start":{"line":83,"column":22},"end":{"line":83,"column":47}},"45":{"start":{"line":84,"column":2},"end":{"line":91,"column":3}},"46":{"start":{"line":85,"column":28},"end":{"line":85,"column":84}},"47":{"start":{"line":86,"column":3},"end":{"line":86,"column":42}},"48":{"start":{"line":87,"column":3},"end":{"line":87,"column":82}},"49":{"start":{"line":87,"column":28},"end":{"line":87,"column":82}},"50":{"start":{"line":88,"column":3},"end":{"line":88,"column":79}},"51":{"start":{"line":90,"column":3},"end":{"line":90,"column":22}},"52":{"start":{"line":96,"column":0},"end":{"line":102,"column":1}},"53":{"start":{"line":99,"column":19},"end":{"line":99,"column":69}},"54":{"start":{"line":100,"column":2},"end":{"line":100,"column":30}},"55":{"start":{"line":104,"column":0},"end":{"line":119,"column":1}},"56":{"start":{"line":109,"column":2},"end":{"line":109,"column":33}},"57":{"start":{"line":110,"column":2},"end":{"line":110,"column":37}},"58":{"start":{"line":111,"column":21},"end":{"line":111,"column":52}},"59":{"start":{"line":112,"column":18},"end":{"line":112,"column":49}},"60":{"start":{"line":113,"column":2},"end":{"line":113,"column":27}},"61":{"start":{"line":115,"column":13},"end":{"line":115,"column":36}},"62":{"start":{"line":116,"column":2},"end":{"line":116,"column":89}},"63":{"start":{"line":117,"column":2},"end":{"line":117,"column":29}},"64":{"start":{"line":121,"column":0},"end":{"line":135,"column":1}},"65":{"start":{"line":125,"column":2},"end":{"line":125,"column":29}},"66":{"start":{"line":126,"column":18},"end":{"line":126,"column":56}},"67":{"start":{"line":127,"column":2},"end":{"line":132,"column":3}},"68":{"start":{"line":128,"column":3},"end":{"line":128,"column":26}},"69":{"start":{"line":129,"column":14},"end":{"line":129,"column":37}},"70":{"start":{"line":130,"column":3},"end":{"line":130,"column":98}},"71":{"start":{"line":131,"column":3},"end":{"line":131,"column":29}},"72":{"start":{"line":133,"column":2},"end":{"line":133,"column":21}},"73":{"start":{"line":137,"column":0},"end":{"line":137,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":27,"column":14},"end":{"line":27,"column":15}},"loc":{"start":{"line":27,"column":34},"end":{"line":32,"column":2}},"line":27},"1":{"name":"(anonymous_1)","decl":{"start":{"line":38,"column":14},"end":{"line":38,"column":15}},"loc":{"start":{"line":38,"column":34},"end":{"line":46,"column":2}},"line":38},"2":{"name":"(anonymous_2)","decl":{"start":{"line":51,"column":14},"end":{"line":51,"column":15}},"loc":{"start":{"line":51,"column":34},"end":{"line":63,"column":2}},"line":51},"3":{"name":"(anonymous_3)","decl":{"start":{"line":68,"column":14},"end":{"line":68,"column":15}},"loc":{"start":{"line":68,"column":34},"end":{"line":76,"column":2}},"line":68},"4":{"name":"(anonymous_4)","decl":{"start":{"line":81,"column":14},"end":{"line":81,"column":15}},"loc":{"start":{"line":81,"column":34},"end":{"line":92,"column":2}},"line":81},"5":{"name":"(anonymous_5)","decl":{"start":{"line":98,"column":14},"end":{"line":98,"column":15}},"loc":{"start":{"line":98,"column":34},"end":{"line":101,"column":2}},"line":98},"6":{"name":"(anonymous_6)","decl":{"start":{"line":108,"column":14},"end":{"line":108,"column":15}},"loc":{"start":{"line":108,"column":34},"end":{"line":118,"column":2}},"line":108},"7":{"name":"(anonymous_7)","decl":{"start":{"line":124,"column":14},"end":{"line":124,"column":15}},"loc":{"start":{"line":124,"column":34},"end":{"line":134,"column":2}},"line":124}},"branchMap":{"0":{"loc":{"start":{"line":41,"column":2},"end":{"line":41,"column":48}},"type":"if","locations":[{"start":{"line":41,"column":2},"end":{"line":41,"column":48}},{"start":{"line":41,"column":2},"end":{"line":41,"column":48}}],"line":41},"1":{"loc":{"start":{"line":54,"column":2},"end":{"line":62,"column":3}},"type":"if","locations":[{"start":{"line":54,"column":2},"end":{"line":62,"column":3}},{"start":{"line":54,"column":2},"end":{"line":62,"column":3}}],"line":54},"2":{"loc":{"start":{"line":56,"column":3},"end":{"line":56,"column":49}},"type":"if","locations":[{"start":{"line":56,"column":3},"end":{"line":56,"column":49}},{"start":{"line":56,"column":3},"end":{"line":56,"column":49}}],"line":56},"3":{"loc":{"start":{"line":57,"column":3},"end":{"line":57,"column":82}},"type":"if","locations":[{"start":{"line":57,"column":3},"end":{"line":57,"column":82}},{"start":{"line":57,"column":3},"end":{"line":57,"column":82}}],"line":57},"4":{"loc":{"start":{"line":59,"column":10},"end":{"line":59,"column":77}},"type":"cond-expr","locations":[{"start":{"line":59,"column":31},"end":{"line":59,"column":55}},{"start":{"line":59,"column":58},"end":{"line":59,"column":77}}],"line":59},"5":{"loc":{"start":{"line":84,"column":2},"end":{"line":91,"column":3}},"type":"if","locations":[{"start":{"line":84,"column":2},"end":{"line":91,"column":3}},{"start":{"line":84,"column":2},"end":{"line":91,"column":3}}],"line":84},"6":{"loc":{"start":{"line":87,"column":3},"end":{"line":87,"column":82}},"type":"if","locations":[{"start":{"line":87,"column":3},"end":{"line":87,"column":82}},{"start":{"line":87,"column":3},"end":{"line":87,"column":82}}],"line":87},"7":{"loc":{"start":{"line":88,"column":3},"end":{"line":88,"column":79}},"type":"cond-expr","locations":[{"start":{"line":88,"column":26},"end":{"line":88,"column":57}},{"start":{"line":88,"column":60},"end":{"line":88,"column":79}}],"line":88},"8":{"loc":{"start":{"line":127,"column":2},"end":{"line":132,"column":3}},"type":"if","locations":[{"start":{"line":127,"column":2},"end":{"line":132,"column":3}},{"start":{"line":127,"column":2},"end":{"line":132,"column":3}}],"line":127}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":0,"13":0,"14":0,"15":0,"16":1,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":1,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":1,"38":0,"39":0,"40":0,"41":0,"42":1,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":1,"53":0,"54":0,"55":1,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":1,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":1},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0},"b":{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"2b32ada5d49ad9087abadd66088a72c7fca483e6"}
+,"/home/denis/Zazmic_Internship/hw5/routes/fees.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/fees.js","statementMap":{"0":{"start":{"line":6,"column":16},"end":{"line":6,"column":34}},"1":{"start":{"line":7,"column":15},"end":{"line":7,"column":31}},"2":{"start":{"line":8,"column":21},"end":{"line":8,"column":53}},"3":{"start":{"line":10,"column":18},"end":{"line":10,"column":62}},"4":{"start":{"line":11,"column":43},"end":{"line":11,"column":79}},"5":{"start":{"line":12,"column":19},"end":{"line":12,"column":54}},"6":{"start":{"line":13,"column":23},"end":{"line":13,"column":48}},"7":{"start":{"line":14,"column":18},"end":{"line":14,"column":21}},"8":{"start":{"line":15,"column":14},"end":{"line":15,"column":17}},"9":{"start":{"line":17,"column":0},"end":{"line":27,"column":1}},"10":{"start":{"line":21,"column":15},"end":{"line":21,"column":44}},"11":{"start":{"line":22,"column":2},"end":{"line":22,"column":59}},"12":{"start":{"line":22,"column":19},"end":{"line":22,"column":59}},"13":{"start":{"line":23,"column":2},"end":{"line":23,"column":74}},"14":{"start":{"line":23,"column":32},"end":{"line":23,"column":74}},"15":{"start":{"line":24,"column":16},"end":{"line":24,"column":63}},"16":{"start":{"line":25,"column":2},"end":{"line":25,"column":51}},"17":{"start":{"line":29,"column":0},"end":{"line":57,"column":1}},"18":{"start":{"line":33,"column":15},"end":{"line":33,"column":44}},"19":{"start":{"line":34,"column":23},"end":{"line":34,"column":124}},"20":{"start":{"line":35,"column":16},"end":{"line":35,"column":63}},"21":{"start":{"line":36,"column":2},"end":{"line":45,"column":4}},"22":{"start":{"line":47,"column":2},"end":{"line":54,"column":3}},"23":{"start":{"line":48,"column":3},"end":{"line":48,"column":42}},"24":{"start":{"line":49,"column":3},"end":{"line":53,"column":5}},"25":{"start":{"line":55,"column":2},"end":{"line":55,"column":63}},"26":{"start":{"line":59,"column":0},"end":{"line":59,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":20,"column":14},"end":{"line":20,"column":15}},"loc":{"start":{"line":20,"column":34},"end":{"line":26,"column":2}},"line":20},"1":{"name":"(anonymous_1)","decl":{"start":{"line":32,"column":14},"end":{"line":32,"column":15}},"loc":{"start":{"line":32,"column":34},"end":{"line":56,"column":2}},"line":32}},"branchMap":{"0":{"loc":{"start":{"line":22,"column":2},"end":{"line":22,"column":59}},"type":"if","locations":[{"start":{"line":22,"column":2},"end":{"line":22,"column":59}},{"start":{"line":22,"column":2},"end":{"line":22,"column":59}}],"line":22},"1":{"loc":{"start":{"line":23,"column":2},"end":{"line":23,"column":74}},"type":"if","locations":[{"start":{"line":23,"column":2},"end":{"line":23,"column":74}},{"start":{"line":23,"column":2},"end":{"line":23,"column":74}}],"line":23},"2":{"loc":{"start":{"line":43,"column":10},"end":{"line":43,"column":51}},"type":"cond-expr","locations":[{"start":{"line":43,"column":30},"end":{"line":43,"column":47}},{"start":{"line":43,"column":50},"end":{"line":43,"column":51}}],"line":43},"3":{"loc":{"start":{"line":47,"column":2},"end":{"line":54,"column":3}},"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":54,"column":3}},{"start":{"line":47,"column":2},"end":{"line":54,"column":3}}],"line":47},"4":{"loc":{"start":{"line":47,"column":6},"end":{"line":47,"column":40}},"type":"binary-expr","locations":[{"start":{"line":47,"column":6},"end":{"line":47,"column":18}},{"start":{"line":47,"column":22},"end":{"line":47,"column":40}}],"line":47}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":1,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":1},"f":{"0":0,"1":0},"b":{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"dd89d8c5d0cec8e719e74a38e4fc187686ba3f21"}
+,"/home/denis/Zazmic_Internship/hw5/routes/index.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/index.js","statementMap":{"0":{"start":{"line":1,"column":14},"end":{"line":1,"column":30}},"1":{"start":{"line":2,"column":15},"end":{"line":2,"column":42}},"2":{"start":{"line":4,"column":13},"end":{"line":4,"column":30}},"3":{"start":{"line":5,"column":14},"end":{"line":5,"column":32}},"4":{"start":{"line":6,"column":13},"end":{"line":6,"column":31}},"5":{"start":{"line":7,"column":13},"end":{"line":7,"column":31}},"6":{"start":{"line":8,"column":16},"end":{"line":8,"column":36}},"7":{"start":{"line":9,"column":13},"end":{"line":9,"column":30}},"8":{"start":{"line":11,"column":27},"end":{"line":11,"column":56}},"9":{"start":{"line":13,"column":0},"end":{"line":13,"column":34}},"10":{"start":{"line":14,"column":0},"end":{"line":14,"column":27}},"11":{"start":{"line":15,"column":0},"end":{"line":15,"column":38}},"12":{"start":{"line":16,"column":0},"end":{"line":16,"column":33}},"13":{"start":{"line":17,"column":0},"end":{"line":17,"column":32}},"14":{"start":{"line":18,"column":0},"end":{"line":18,"column":32}},"15":{"start":{"line":20,"column":0},"end":{"line":24,"column":2}},"16":{"start":{"line":21,"column":1},"end":{"line":21,"column":68}},"17":{"start":{"line":21,"column":49},"end":{"line":21,"column":67}},"18":{"start":{"line":22,"column":14},"end":{"line":22,"column":24}},"19":{"start":{"line":23,"column":1},"end":{"line":23,"column":70}},"20":{"start":{"line":26,"column":0},"end":{"line":26,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":20,"column":16},"end":{"line":20,"column":17}},"loc":{"start":{"line":20,"column":30},"end":{"line":24,"column":1}},"line":20},"1":{"name":"(anonymous_1)","decl":{"start":{"line":21,"column":37},"end":{"line":21,"column":38}},"loc":{"start":{"line":21,"column":49},"end":{"line":21,"column":67}},"line":21}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":0,"17":0,"18":0,"19":0,"20":1},"f":{"0":0,"1":0},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"3e16867d0f6b67fc71d64c54561dfe444152ca69"}
+,"/home/denis/Zazmic_Internship/hw5/routes/oauth.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/oauth.js","statementMap":{"0":{"start":{"line":7,"column":16},"end":{"line":7,"column":34}},"1":{"start":{"line":8,"column":15},"end":{"line":8,"column":31}},"2":{"start":{"line":9,"column":17},"end":{"line":9,"column":36}},"3":{"start":{"line":11,"column":0},"end":{"line":11,"column":87}},"4":{"start":{"line":13,"column":0},"end":{"line":13,"column":80}},"5":{"start":{"line":15,"column":0},"end":{"line":17,"column":2}},"6":{"start":{"line":16,"column":1},"end":{"line":16,"column":29}},"7":{"start":{"line":19,"column":0},"end":{"line":21,"column":2}},"8":{"start":{"line":20,"column":1},"end":{"line":20,"column":29}},"9":{"start":{"line":23,"column":0},"end":{"line":23,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":15,"column":65},"end":{"line":15,"column":66}},"loc":{"start":{"line":15,"column":79},"end":{"line":17,"column":1}},"line":15},"1":{"name":"(anonymous_1)","decl":{"start":{"line":19,"column":69},"end":{"line":19,"column":70}},"loc":{"start":{"line":19,"column":83},"end":{"line":21,"column":1}},"line":19}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":0,"7":1,"8":0,"9":1},"f":{"0":0,"1":0},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"09021805b1b3e6092c37885c5fdfa20438f39722"}
+,"/home/denis/Zazmic_Internship/hw5/routes/profile.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/profile.js","statementMap":{"0":{"start":{"line":7,"column":16},"end":{"line":7,"column":34}},"1":{"start":{"line":8,"column":15},"end":{"line":8,"column":31}},"2":{"start":{"line":9,"column":21},"end":{"line":9,"column":53}},"3":{"start":{"line":11,"column":28},"end":{"line":11,"column":60}},"4":{"start":{"line":12,"column":18},"end":{"line":12,"column":62}},"5":{"start":{"line":13,"column":19},"end":{"line":13,"column":49}},"6":{"start":{"line":14,"column":25},"end":{"line":14,"column":54}},"7":{"start":{"line":15,"column":29},"end":{"line":15,"column":68}},"8":{"start":{"line":16,"column":31},"end":{"line":16,"column":71}},"9":{"start":{"line":17,"column":27},"end":{"line":17,"column":63}},"10":{"start":{"line":19,"column":0},"end":{"line":27,"column":1}},"11":{"start":{"line":24,"column":2},"end":{"line":24,"column":87}},"12":{"start":{"line":25,"column":2},"end":{"line":25,"column":30}},"13":{"start":{"line":29,"column":0},"end":{"line":40,"column":1}},"14":{"start":{"line":33,"column":15},"end":{"line":33,"column":111}},"15":{"start":{"line":34,"column":2},"end":{"line":34,"column":64}},"16":{"start":{"line":34,"column":24},"end":{"line":34,"column":64}},"17":{"start":{"line":35,"column":2},"end":{"line":35,"column":54}},"18":{"start":{"line":35,"column":19},"end":{"line":35,"column":54}},"19":{"start":{"line":36,"column":24},"end":{"line":36,"column":75}},"20":{"start":{"line":37,"column":2},"end":{"line":37,"column":48}},"21":{"start":{"line":37,"column":25},"end":{"line":37,"column":48}},"22":{"start":{"line":38,"column":2},"end":{"line":38,"column":21}},"23":{"start":{"line":42,"column":0},"end":{"line":51,"column":1}},"24":{"start":{"line":47,"column":2},"end":{"line":47,"column":65}},"25":{"start":{"line":47,"column":17},"end":{"line":47,"column":65}},"26":{"start":{"line":48,"column":2},"end":{"line":48,"column":51}},"27":{"start":{"line":49,"column":2},"end":{"line":49,"column":48}},"28":{"start":{"line":53,"column":0},"end":{"line":61,"column":1}},"29":{"start":{"line":57,"column":15},"end":{"line":57,"column":44}},"30":{"start":{"line":58,"column":22},"end":{"line":58,"column":64}},"31":{"start":{"line":59,"column":2},"end":{"line":59,"column":49}},"32":{"start":{"line":63,"column":0},"end":{"line":63,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":23,"column":14},"end":{"line":23,"column":15}},"loc":{"start":{"line":23,"column":34},"end":{"line":26,"column":2}},"line":23},"1":{"name":"(anonymous_1)","decl":{"start":{"line":32,"column":14},"end":{"line":32,"column":15}},"loc":{"start":{"line":32,"column":34},"end":{"line":39,"column":2}},"line":32},"2":{"name":"(anonymous_2)","decl":{"start":{"line":46,"column":14},"end":{"line":46,"column":15}},"loc":{"start":{"line":46,"column":34},"end":{"line":50,"column":2}},"line":46},"3":{"name":"(anonymous_3)","decl":{"start":{"line":56,"column":14},"end":{"line":56,"column":15}},"loc":{"start":{"line":56,"column":34},"end":{"line":60,"column":2}},"line":56}},"branchMap":{"0":{"loc":{"start":{"line":34,"column":2},"end":{"line":34,"column":64}},"type":"if","locations":[{"start":{"line":34,"column":2},"end":{"line":34,"column":64}},{"start":{"line":34,"column":2},"end":{"line":34,"column":64}}],"line":34},"1":{"loc":{"start":{"line":35,"column":2},"end":{"line":35,"column":54}},"type":"if","locations":[{"start":{"line":35,"column":2},"end":{"line":35,"column":54}},{"start":{"line":35,"column":2},"end":{"line":35,"column":54}}],"line":35},"2":{"loc":{"start":{"line":37,"column":2},"end":{"line":37,"column":48}},"type":"if","locations":[{"start":{"line":37,"column":2},"end":{"line":37,"column":48}},{"start":{"line":37,"column":2},"end":{"line":37,"column":48}}],"line":37},"3":{"loc":{"start":{"line":47,"column":2},"end":{"line":47,"column":65}},"type":"if","locations":[{"start":{"line":47,"column":2},"end":{"line":47,"column":65}},{"start":{"line":47,"column":2},"end":{"line":47,"column":65}}],"line":47}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":0,"12":0,"13":1,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":1,"24":0,"25":0,"26":0,"27":0,"28":1,"29":0,"30":0,"31":0,"32":1},"f":{"0":0,"1":0,"2":0,"3":0},"b":{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"f16e59877408485faa7e8471eaf82729eb54f0a7"}
+,"/home/denis/Zazmic_Internship/hw5/routes/users.js": {"path":"/home/denis/Zazmic_Internship/hw5/routes/users.js","statementMap":{"0":{"start":{"line":9,"column":16},"end":{"line":9,"column":34}},"1":{"start":{"line":10,"column":15},"end":{"line":10,"column":31}},"2":{"start":{"line":11,"column":21},"end":{"line":11,"column":53}},"3":{"start":{"line":13,"column":18},"end":{"line":13,"column":50}},"4":{"start":{"line":14,"column":11},"end":{"line":14,"column":40}},"5":{"start":{"line":16,"column":21},"end":{"line":16,"column":50}},"6":{"start":{"line":17,"column":34},"end":{"line":17,"column":64}},"7":{"start":{"line":18,"column":18},"end":{"line":18,"column":62}},"8":{"start":{"line":19,"column":24},"end":{"line":19,"column":65}},"9":{"start":{"line":21,"column":0},"end":{"line":50,"column":1}},"10":{"start":{"line":25,"column":16},"end":{"line":39,"column":3}},"11":{"start":{"line":40,"column":16},"end":{"line":40,"column":32}},"12":{"start":{"line":41,"column":2},"end":{"line":47,"column":4}},"13":{"start":{"line":42,"column":20},"end":{"line":42,"column":21}},"14":{"start":{"line":43,"column":3},"end":{"line":45,"column":5}},"15":{"start":{"line":44,"column":4},"end":{"line":44,"column":59}},"16":{"start":{"line":44,"column":35},"end":{"line":44,"column":59}},"17":{"start":{"line":46,"column":3},"end":{"line":46,"column":31}},"18":{"start":{"line":48,"column":2},"end":{"line":48,"column":27}},"19":{"start":{"line":52,"column":0},"end":{"line":58,"column":1}},"20":{"start":{"line":55,"column":15},"end":{"line":55,"column":50}},"21":{"start":{"line":56,"column":2},"end":{"line":56,"column":26}},"22":{"start":{"line":60,"column":0},"end":{"line":68,"column":1}},"23":{"start":{"line":63,"column":19},"end":{"line":63,"column":68}},"24":{"start":{"line":64,"column":16},"end":{"line":64,"column":45}},"25":{"start":{"line":65,"column":2},"end":{"line":65,"column":40}},"26":{"start":{"line":66,"column":2},"end":{"line":66,"column":30}},"27":{"start":{"line":70,"column":0},"end":{"line":70,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":24,"column":14},"end":{"line":24,"column":15}},"loc":{"start":{"line":24,"column":34},"end":{"line":49,"column":2}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":41,"column":16},"end":{"line":41,"column":17}},"loc":{"start":{"line":41,"column":24},"end":{"line":47,"column":3}},"line":41},"2":{"name":"(anonymous_2)","decl":{"start":{"line":43,"column":17},"end":{"line":43,"column":18}},"loc":{"start":{"line":43,"column":25},"end":{"line":45,"column":4}},"line":43},"3":{"name":"(anonymous_3)","decl":{"start":{"line":54,"column":14},"end":{"line":54,"column":15}},"loc":{"start":{"line":54,"column":34},"end":{"line":57,"column":2}},"line":54},"4":{"name":"(anonymous_4)","decl":{"start":{"line":62,"column":14},"end":{"line":62,"column":15}},"loc":{"start":{"line":62,"column":34},"end":{"line":67,"column":2}},"line":62}},"branchMap":{"0":{"loc":{"start":{"line":44,"column":4},"end":{"line":44,"column":59}},"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":59}},{"start":{"line":44,"column":4},"end":{"line":44,"column":59}}],"line":44}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":1,"20":0,"21":0,"22":1,"23":0,"24":0,"25":0,"26":0,"27":1},"f":{"0":0,"1":0,"2":0,"3":0,"4":0},"b":{"0":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"3a82dcb0052af4f2f4652b20839e3681c9973a73"}
+,"/home/denis/Zazmic_Internship/hw5/services/AuthService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/AuthService.js","statementMap":{"0":{"start":{"line":1,"column":24},"end":{"line":1,"column":43}},"1":{"start":{"line":2,"column":29},"end":{"line":2,"column":61}},"2":{"start":{"line":6,"column":2},"end":{"line":22,"column":3}},"3":{"start":{"line":7,"column":20},"end":{"line":7,"column":61}},"4":{"start":{"line":8,"column":3},"end":{"line":19,"column":4}},"5":{"start":{"line":9,"column":4},"end":{"line":9,"column":47}},"6":{"start":{"line":10,"column":17},"end":{"line":10,"column":46}},"7":{"start":{"line":11,"column":23},"end":{"line":11,"column":77}},"8":{"start":{"line":12,"column":4},"end":{"line":12,"column":85}},"9":{"start":{"line":12,"column":21},"end":{"line":12,"column":85}},"10":{"start":{"line":13,"column":4},"end":{"line":13,"column":15}},"11":{"start":{"line":15,"column":20},"end":{"line":15,"column":69}},"12":{"start":{"line":16,"column":4},"end":{"line":16,"column":46}},"13":{"start":{"line":17,"column":4},"end":{"line":17,"column":82}},"14":{"start":{"line":18,"column":4},"end":{"line":18,"column":39}},"15":{"start":{"line":21,"column":3},"end":{"line":21,"column":68}},"16":{"start":{"line":26,"column":2},"end":{"line":26,"column":62}},"17":{"start":{"line":30,"column":2},"end":{"line":30,"column":79}},"18":{"start":{"line":34,"column":0},"end":{"line":34,"column":32}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":1},"end":{"line":5,"column":2}},"loc":{"start":{"line":5,"column":98},"end":{"line":23,"column":2}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":25,"column":1},"end":{"line":25,"column":2}},"loc":{"start":{"line":25,"column":67},"end":{"line":27,"column":2}},"line":25},"2":{"name":"(anonymous_2)","decl":{"start":{"line":29,"column":1},"end":{"line":29,"column":2}},"loc":{"start":{"line":29,"column":53},"end":{"line":31,"column":2}},"line":29}},"branchMap":{"0":{"loc":{"start":{"line":8,"column":3},"end":{"line":19,"column":4}},"type":"if","locations":[{"start":{"line":8,"column":3},"end":{"line":19,"column":4}},{"start":{"line":8,"column":3},"end":{"line":19,"column":4}}],"line":8},"1":{"loc":{"start":{"line":12,"column":4},"end":{"line":12,"column":85}},"type":"if","locations":[{"start":{"line":12,"column":4},"end":{"line":12,"column":85}},{"start":{"line":12,"column":4},"end":{"line":12,"column":85}}],"line":12}},"s":{"0":1,"1":1,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":1},"f":{"0":0,"1":0,"2":0},"b":{"0":[0,0],"1":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"23a53f10e09e6594cfba4e9d6fc74cda2f483ed9"}
+,"/home/denis/Zazmic_Internship/hw5/services/emailService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/emailService.js","statementMap":{"0":{"start":{"line":1,"column":15},"end":{"line":1,"column":40}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":46}},"2":{"start":{"line":6,"column":2},"end":{"line":11,"column":4}},"3":{"start":{"line":15,"column":0},"end":{"line":15,"column":44}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":1},"end":{"line":5,"column":2}},"loc":{"start":{"line":5,"column":69},"end":{"line":12,"column":2}},"line":5}},"branchMap":{"0":{"loc":{"start":{"line":5,"column":34},"end":{"line":5,"column":49}},"type":"default-arg","locations":[{"start":{"line":5,"column":47},"end":{"line":5,"column":49}}],"line":5},"1":{"loc":{"start":{"line":5,"column":51},"end":{"line":5,"column":67}},"type":"default-arg","locations":[{"start":{"line":5,"column":65},"end":{"line":5,"column":67}}],"line":5}},"s":{"0":1,"1":1,"2":0,"3":1},"f":{"0":0},"b":{"0":[0],"1":[0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"c7e335c2c03c8313e68f15cddb3b68e1b66ff3bb"}
+,"/home/denis/Zazmic_Internship/hw5/services/gcRemovalService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/gcRemovalService.js","statementMap":{"0":{"start":{"line":1,"column":43},"end":{"line":1,"column":72}},"1":{"start":{"line":2,"column":24},"end":{"line":2,"column":43}},"2":{"start":{"line":6,"column":2},"end":{"line":6,"column":26}},"3":{"start":{"line":7,"column":2},"end":{"line":7,"column":25}},"4":{"start":{"line":10,"column":2},"end":{"line":10,"column":68}},"5":{"start":{"line":14,"column":2},"end":{"line":14,"column":65}},"6":{"start":{"line":14,"column":36},"end":{"line":14,"column":63}},"7":{"start":{"line":18,"column":19},"end":{"line":18,"column":40}},"8":{"start":{"line":19,"column":19},"end":{"line":19,"column":83}},"9":{"start":{"line":20,"column":17},"end":{"line":20,"column":55}},"10":{"start":{"line":21,"column":2},"end":{"line":21,"column":109}},"11":{"start":{"line":21,"column":35},"end":{"line":21,"column":108}},"12":{"start":{"line":25,"column":25},"end":{"line":25,"column":92}},"13":{"start":{"line":26,"column":29},"end":{"line":26,"column":100}},"14":{"start":{"line":28,"column":0},"end":{"line":28,"column":59}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":1},"end":{"line":5,"column":2}},"loc":{"start":{"line":5,"column":30},"end":{"line":8,"column":2}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":9,"column":1},"end":{"line":9,"column":2}},"loc":{"start":{"line":9,"column":14},"end":{"line":11,"column":2}},"line":9},"2":{"name":"(anonymous_2)","decl":{"start":{"line":13,"column":1},"end":{"line":13,"column":2}},"loc":{"start":{"line":13,"column":24},"end":{"line":15,"column":2}},"line":13},"3":{"name":"(anonymous_3)","decl":{"start":{"line":14,"column":29},"end":{"line":14,"column":30}},"loc":{"start":{"line":14,"column":36},"end":{"line":14,"column":63}},"line":14},"4":{"name":"(anonymous_4)","decl":{"start":{"line":17,"column":1},"end":{"line":17,"column":2}},"loc":{"start":{"line":17,"column":22},"end":{"line":22,"column":2}},"line":17},"5":{"name":"(anonymous_5)","decl":{"start":{"line":21,"column":30},"end":{"line":21,"column":31}},"loc":{"start":{"line":21,"column":35},"end":{"line":21,"column":108}},"line":21}},"branchMap":{"0":{"loc":{"start":{"line":10,"column":2},"end":{"line":10,"column":68}},"type":"cond-expr","locations":[{"start":{"line":10,"column":24},"end":{"line":10,"column":45}},{"start":{"line":10,"column":48},"end":{"line":10,"column":68}}],"line":10}},"s":{"0":1,"1":1,"2":2,"3":2,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":1,"13":1,"14":1},"f":{"0":2,"1":0,"2":0,"3":0,"4":0,"5":0},"b":{"0":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"42215053b228af6782cbfab845d9dcad510e4a4b"}
+,"/home/denis/Zazmic_Internship/hw5/services/gcStorageService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/gcStorageService.js","statementMap":{"0":{"start":{"line":1,"column":20},"end":{"line":1,"column":52}},"1":{"start":{"line":2,"column":13},"end":{"line":2,"column":28}},"2":{"start":{"line":3,"column":14},"end":{"line":3,"column":30}},"3":{"start":{"line":4,"column":24},"end":{"line":4,"column":43}},"4":{"start":{"line":8,"column":2},"end":{"line":8,"column":80}},"5":{"start":{"line":8,"column":20},"end":{"line":8,"column":80}},"6":{"start":{"line":9,"column":2},"end":{"line":9,"column":99}},"7":{"start":{"line":9,"column":25},"end":{"line":9,"column":99}},"8":{"start":{"line":10,"column":2},"end":{"line":10,"column":63}},"9":{"start":{"line":11,"column":2},"end":{"line":11,"column":54}},"10":{"start":{"line":12,"column":2},"end":{"line":12,"column":65}},"11":{"start":{"line":13,"column":2},"end":{"line":13,"column":53}},"12":{"start":{"line":14,"column":2},"end":{"line":14,"column":21}},"13":{"start":{"line":18,"column":2},"end":{"line":18,"column":92}},"14":{"start":{"line":22,"column":17},"end":{"line":22,"column":27}},"15":{"start":{"line":23,"column":2},"end":{"line":23,"column":44}},"16":{"start":{"line":27,"column":2},"end":{"line":49,"column":4}},"17":{"start":{"line":28,"column":3},"end":{"line":28,"column":26}},"18":{"start":{"line":28,"column":12},"end":{"line":28,"column":26}},"19":{"start":{"line":29,"column":3},"end":{"line":48,"column":5}},"20":{"start":{"line":30,"column":4},"end":{"line":30,"column":27}},"21":{"start":{"line":30,"column":13},"end":{"line":30,"column":27}},"22":{"start":{"line":31,"column":22},"end":{"line":31,"column":54}},"23":{"start":{"line":32,"column":17},"end":{"line":32,"column":47}},"24":{"start":{"line":33,"column":23},"end":{"line":33,"column":74}},"25":{"start":{"line":34,"column":25},"end":{"line":34,"column":90}},"26":{"start":{"line":35,"column":4},"end":{"line":47,"column":7}},"27":{"start":{"line":39,"column":6},"end":{"line":39,"column":72}},"28":{"start":{"line":40,"column":6},"end":{"line":40,"column":13}},"29":{"start":{"line":43,"column":6},"end":{"line":46,"column":8}},"30":{"start":{"line":53,"column":2},"end":{"line":53,"column":45}},"31":{"start":{"line":57,"column":22},"end":{"line":62,"column":2}},"32":{"start":{"line":64,"column":24},"end":{"line":69,"column":2}},"33":{"start":{"line":71,"column":0},"end":{"line":71,"column":51}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":7,"column":1},"end":{"line":7,"column":2}},"loc":{"start":{"line":7,"column":19},"end":{"line":15,"column":2}},"line":7},"1":{"name":"(anonymous_1)","decl":{"start":{"line":17,"column":1},"end":{"line":17,"column":2}},"loc":{"start":{"line":17,"column":31},"end":{"line":19,"column":2}},"line":17},"2":{"name":"(anonymous_2)","decl":{"start":{"line":21,"column":1},"end":{"line":21,"column":2}},"loc":{"start":{"line":21,"column":28},"end":{"line":24,"column":2}},"line":21},"3":{"name":"(anonymous_3)","decl":{"start":{"line":26,"column":1},"end":{"line":26,"column":2}},"loc":{"start":{"line":26,"column":28},"end":{"line":50,"column":2}},"line":26},"4":{"name":"(anonymous_4)","decl":{"start":{"line":27,"column":33},"end":{"line":27,"column":34}},"loc":{"start":{"line":27,"column":55},"end":{"line":49,"column":3}},"line":27},"5":{"name":"(anonymous_5)","decl":{"start":{"line":29,"column":31},"end":{"line":29,"column":32}},"loc":{"start":{"line":29,"column":56},"end":{"line":48,"column":4}},"line":29},"6":{"name":"(anonymous_6)","decl":{"start":{"line":38,"column":18},"end":{"line":38,"column":19}},"loc":{"start":{"line":38,"column":25},"end":{"line":41,"column":6}},"line":38},"7":{"name":"(anonymous_7)","decl":{"start":{"line":42,"column":19},"end":{"line":42,"column":20}},"loc":{"start":{"line":42,"column":25},"end":{"line":47,"column":6}},"line":42},"8":{"name":"(anonymous_8)","decl":{"start":{"line":52,"column":1},"end":{"line":52,"column":2}},"loc":{"start":{"line":52,"column":28},"end":{"line":54,"column":2}},"line":52}},"branchMap":{"0":{"loc":{"start":{"line":8,"column":2},"end":{"line":8,"column":80}},"type":"if","locations":[{"start":{"line":8,"column":2},"end":{"line":8,"column":80}},{"start":{"line":8,"column":2},"end":{"line":8,"column":80}}],"line":8},"1":{"loc":{"start":{"line":9,"column":2},"end":{"line":9,"column":99}},"type":"if","locations":[{"start":{"line":9,"column":2},"end":{"line":9,"column":99}},{"start":{"line":9,"column":2},"end":{"line":9,"column":99}}],"line":9},"2":{"loc":{"start":{"line":10,"column":24},"end":{"line":10,"column":63}},"type":"binary-expr","locations":[{"start":{"line":10,"column":24},"end":{"line":10,"column":40}},{"start":{"line":10,"column":44},"end":{"line":10,"column":63}}],"line":10},"3":{"loc":{"start":{"line":11,"column":21},"end":{"line":11,"column":54}},"type":"binary-expr","locations":[{"start":{"line":11,"column":21},"end":{"line":11,"column":34}},{"start":{"line":11,"column":38},"end":{"line":11,"column":54}}],"line":11},"4":{"loc":{"start":{"line":28,"column":3},"end":{"line":28,"column":26}},"type":"if","locations":[{"start":{"line":28,"column":3},"end":{"line":28,"column":26}},{"start":{"line":28,"column":3},"end":{"line":28,"column":26}}],"line":28},"5":{"loc":{"start":{"line":30,"column":4},"end":{"line":30,"column":27}},"type":"if","locations":[{"start":{"line":30,"column":4},"end":{"line":30,"column":27}},{"start":{"line":30,"column":4},"end":{"line":30,"column":27}}],"line":30},"6":{"loc":{"start":{"line":33,"column":40},"end":{"line":33,"column":72}},"type":"binary-expr","locations":[{"start":{"line":33,"column":40},"end":{"line":33,"column":56}},{"start":{"line":33,"column":60},"end":{"line":33,"column":72}}],"line":33}},"s":{"0":1,"1":1,"2":1,"3":1,"4":2,"5":0,"6":2,"7":0,"8":2,"9":2,"10":2,"11":2,"12":2,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":1,"32":1,"33":1},"f":{"0":2,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0},"b":{"0":[0,2],"1":[0,2],"2":[2,2],"3":[2,2],"4":[0,0],"5":[0,0],"6":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"75aeca3c3beace292294e922e9183393e6490dab"}
+,"/home/denis/Zazmic_Internship/hw5/services/hashPsw.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/hashPsw.js","statementMap":{"0":{"start":{"line":1,"column":15},"end":{"line":1,"column":32}},"1":{"start":{"line":2,"column":24},"end":{"line":2,"column":43}},"2":{"start":{"line":3,"column":18},"end":{"line":3,"column":20}},"3":{"start":{"line":5,"column":21},"end":{"line":13,"column":1}},"4":{"start":{"line":6,"column":1},"end":{"line":12,"column":2}},"5":{"start":{"line":7,"column":2},"end":{"line":9,"column":3}},"6":{"start":{"line":8,"column":3},"end":{"line":8,"column":62}},"7":{"start":{"line":11,"column":2},"end":{"line":11,"column":77}},"8":{"start":{"line":15,"column":17},"end":{"line":15,"column":57}},"9":{"start":{"line":15,"column":32},"end":{"line":15,"column":57}},"10":{"start":{"line":17,"column":0},"end":{"line":17,"column":43}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":21},"end":{"line":5,"column":22}},"loc":{"start":{"line":5,"column":35},"end":{"line":13,"column":1}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":15,"column":17},"end":{"line":15,"column":18}},"loc":{"start":{"line":15,"column":32},"end":{"line":15,"column":57}},"line":15}},"branchMap":{"0":{"loc":{"start":{"line":7,"column":2},"end":{"line":9,"column":3}},"type":"if","locations":[{"start":{"line":7,"column":2},"end":{"line":9,"column":3}},{"start":{"line":7,"column":2},"end":{"line":9,"column":3}}],"line":7}},"s":{"0":1,"1":1,"2":1,"3":1,"4":2,"5":2,"6":1,"7":0,"8":1,"9":0,"10":1},"f":{"0":2,"1":0},"b":{"0":[1,1]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"4fba305e51456a27d019709fa766696cfcdebda8"}
+,"/home/denis/Zazmic_Internship/hw5/services/helpers.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/helpers.js","statementMap":{"0":{"start":{"line":1,"column":12},"end":{"line":1,"column":26}},"1":{"start":{"line":3,"column":30},"end":{"line":9,"column":1}},"2":{"start":{"line":4,"column":1},"end":{"line":8,"column":3}},"3":{"start":{"line":5,"column":2},"end":{"line":7,"column":4}},"4":{"start":{"line":6,"column":3},"end":{"line":6,"column":80}},"5":{"start":{"line":6,"column":46},"end":{"line":6,"column":80}},"6":{"start":{"line":11,"column":15},"end":{"line":15,"column":1}},"7":{"start":{"line":12,"column":1},"end":{"line":12,"column":13}},"8":{"start":{"line":13,"column":1},"end":{"line":13,"column":22}},"9":{"start":{"line":14,"column":1},"end":{"line":14,"column":13}},"10":{"start":{"line":17,"column":24},"end":{"line":17,"column":92}},"11":{"start":{"line":17,"column":31},"end":{"line":17,"column":92}},"12":{"start":{"line":19,"column":0},"end":{"line":19,"column":67}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":3,"column":30},"end":{"line":3,"column":31}},"loc":{"start":{"line":3,"column":51},"end":{"line":9,"column":1}},"line":3},"1":{"name":"(anonymous_1)","decl":{"start":{"line":4,"column":18},"end":{"line":4,"column":19}},"loc":{"start":{"line":4,"column":26},"end":{"line":8,"column":2}},"line":4},"2":{"name":"(anonymous_2)","decl":{"start":{"line":5,"column":16},"end":{"line":5,"column":17}},"loc":{"start":{"line":5,"column":24},"end":{"line":7,"column":3}},"line":5},"3":{"name":"(anonymous_3)","decl":{"start":{"line":11,"column":15},"end":{"line":11,"column":16}},"loc":{"start":{"line":11,"column":29},"end":{"line":15,"column":1}},"line":11},"4":{"name":"(anonymous_4)","decl":{"start":{"line":17,"column":24},"end":{"line":17,"column":25}},"loc":{"start":{"line":17,"column":31},"end":{"line":17,"column":92}},"line":17}},"branchMap":{"0":{"loc":{"start":{"line":6,"column":3},"end":{"line":6,"column":80}},"type":"if","locations":[{"start":{"line":6,"column":3},"end":{"line":6,"column":80}},{"start":{"line":6,"column":3},"end":{"line":6,"column":80}}],"line":6}},"s":{"0":1,"1":1,"2":0,"3":0,"4":0,"5":0,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1},"f":{"0":0,"1":0,"2":0,"3":1,"4":1},"b":{"0":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"da9e9ae3a912e86cde558b4b715ce8db3ef21d49"}
+,"/home/denis/Zazmic_Internship/hw5/services/logger.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/logger.js","statementMap":{"0":{"start":{"line":1,"column":16},"end":{"line":1,"column":34}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":26}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":37}},"3":{"start":{"line":5,"column":45},"end":{"line":5,"column":52}},"4":{"start":{"line":7,"column":23},"end":{"line":24,"column":2}},"5":{"start":{"line":26,"column":20},"end":{"line":44,"column":2}},"6":{"start":{"line":46,"column":23},"end":{"line":64,"column":2}},"7":{"start":{"line":66,"column":24},"end":{"line":69,"column":1}},"8":{"start":{"line":67,"column":1},"end":{"line":67,"column":61}},"9":{"start":{"line":68,"column":1},"end":{"line":68,"column":39}},"10":{"start":{"line":68,"column":23},"end":{"line":68,"column":38}},"11":{"start":{"line":71,"column":0},"end":{"line":71,"column":48}},"12":{"start":{"line":72,"column":0},"end":{"line":72,"column":49}},"13":{"start":{"line":74,"column":0},"end":{"line":78,"column":1}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":66,"column":24},"end":{"line":66,"column":25}},"loc":{"start":{"line":66,"column":33},"end":{"line":69,"column":1}},"line":66},"1":{"name":"(anonymous_1)","decl":{"start":{"line":68,"column":17},"end":{"line":68,"column":18}},"loc":{"start":{"line":68,"column":23},"end":{"line":68,"column":38}},"line":68}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":0,"9":0,"10":0,"11":1,"12":1,"13":1},"f":{"0":0,"1":0},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"b954a0172387f7be8517682f687c7e2189e050bf"}
+,"/home/denis/Zazmic_Internship/hw5/services/multer.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/multer.js","statementMap":{"0":{"start":{"line":1,"column":15},"end":{"line":1,"column":32}},"1":{"start":{"line":3,"column":43},"end":{"line":3,"column":72}},"2":{"start":{"line":5,"column":21},"end":{"line":10,"column":2}},"3":{"start":{"line":12,"column":23},"end":{"line":17,"column":2}},"4":{"start":{"line":19,"column":0},"end":{"line":19,"column":49}}},"fnMap":{},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1},"f":{},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"ce37a63705b31f9094c8b3f1d12e6fcf2ea0bc83"}
+,"/home/denis/Zazmic_Internship/hw5/services/passportService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/passportService.js","statementMap":{"0":{"start":{"line":1,"column":22},"end":{"line":1,"column":56}},"1":{"start":{"line":2,"column":23},"end":{"line":2,"column":57}},"2":{"start":{"line":3,"column":25},"end":{"line":3,"column":62}},"3":{"start":{"line":5,"column":24},"end":{"line":5,"column":43}},"4":{"start":{"line":6,"column":21},"end":{"line":6,"column":41}},"5":{"start":{"line":7,"column":18},"end":{"line":7,"column":50}},"6":{"start":{"line":8,"column":24},"end":{"line":8,"column":48}},"7":{"start":{"line":10,"column":0},"end":{"line":88,"column":1}},"8":{"start":{"line":11,"column":1},"end":{"line":11,"column":60}},"9":{"start":{"line":11,"column":40},"end":{"line":11,"column":59}},"10":{"start":{"line":13,"column":1},"end":{"line":21,"column":3}},"11":{"start":{"line":14,"column":2},"end":{"line":20,"column":3}},"12":{"start":{"line":15,"column":16},"end":{"line":15,"column":40}},"13":{"start":{"line":16,"column":3},"end":{"line":16,"column":26}},"14":{"start":{"line":18,"column":3},"end":{"line":18,"column":12}},"15":{"start":{"line":19,"column":3},"end":{"line":19,"column":68}},"16":{"start":{"line":23,"column":1},"end":{"line":37,"column":2}},"17":{"start":{"line":25,"column":3},"end":{"line":35,"column":4}},"18":{"start":{"line":26,"column":21},"end":{"line":26,"column":80}},"19":{"start":{"line":27,"column":17},"end":{"line":27,"column":46}},"20":{"start":{"line":28,"column":4},"end":{"line":28,"column":94}},"21":{"start":{"line":28,"column":26},"end":{"line":28,"column":94}},"22":{"start":{"line":29,"column":18},"end":{"line":29,"column":57}},"23":{"start":{"line":30,"column":4},"end":{"line":30,"column":38}},"24":{"start":{"line":30,"column":15},"end":{"line":30,"column":38}},"25":{"start":{"line":31,"column":4},"end":{"line":31,"column":25}},"26":{"start":{"line":33,"column":4},"end":{"line":33,"column":13}},"27":{"start":{"line":34,"column":4},"end":{"line":34,"column":69}},"28":{"start":{"line":39,"column":1},"end":{"line":61,"column":2}},"29":{"start":{"line":47,"column":4},"end":{"line":58,"column":5}},"30":{"start":{"line":48,"column":18},"end":{"line":54,"column":7}},"31":{"start":{"line":55,"column":5},"end":{"line":55,"column":21}},"32":{"start":{"line":57,"column":5},"end":{"line":57,"column":12}},"33":{"start":{"line":63,"column":1},"end":{"line":87,"column":2}},"34":{"start":{"line":73,"column":4},"end":{"line":84,"column":5}},"35":{"start":{"line":74,"column":18},"end":{"line":80,"column":7}},"36":{"start":{"line":81,"column":5},"end":{"line":81,"column":21}},"37":{"start":{"line":83,"column":5},"end":{"line":83,"column":16}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":10,"column":17},"end":{"line":10,"column":18}},"loc":{"start":{"line":10,"column":29},"end":{"line":88,"column":1}},"line":10},"1":{"name":"(anonymous_1)","decl":{"start":{"line":11,"column":24},"end":{"line":11,"column":25}},"loc":{"start":{"line":11,"column":40},"end":{"line":11,"column":59}},"line":11},"2":{"name":"(anonymous_2)","decl":{"start":{"line":13,"column":26},"end":{"line":13,"column":27}},"loc":{"start":{"line":13,"column":46},"end":{"line":21,"column":2}},"line":13},"3":{"name":"(anonymous_3)","decl":{"start":{"line":24,"column":75},"end":{"line":24,"column":76}},"loc":{"start":{"line":24,"column":108},"end":{"line":36,"column":3}},"line":24},"4":{"name":"(anonymous_4)","decl":{"start":{"line":46,"column":3},"end":{"line":46,"column":4}},"loc":{"start":{"line":46,"column":55},"end":{"line":59,"column":4}},"line":46},"5":{"name":"(anonymous_5)","decl":{"start":{"line":72,"column":3},"end":{"line":72,"column":4}},"loc":{"start":{"line":72,"column":55},"end":{"line":85,"column":4}},"line":72}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":4},"end":{"line":28,"column":94}},"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":28,"column":94}},{"start":{"line":28,"column":4},"end":{"line":28,"column":94}}],"line":28},"1":{"loc":{"start":{"line":30,"column":4},"end":{"line":30,"column":38}},"type":"if","locations":[{"start":{"line":30,"column":4},"end":{"line":30,"column":38}},{"start":{"line":30,"column":4},"end":{"line":30,"column":38}}],"line":30}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":0,"15":0,"16":1,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":1,"29":0,"30":0,"31":0,"32":0,"33":1,"34":0,"35":0,"36":0,"37":0},"f":{"0":1,"1":1,"2":1,"3":0,"4":0,"5":0},"b":{"0":[0,0],"1":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"75bf855ce67969158e80663c898f5d9b220a32b7"}
+,"/home/denis/Zazmic_Internship/hw5/services/queryHelperService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/queryHelperService.js","statementMap":{"0":{"start":{"line":1,"column":11},"end":{"line":1,"column":34}},"1":{"start":{"line":2,"column":38},"end":{"line":2,"column":67}},"2":{"start":{"line":4,"column":20},"end":{"line":17,"column":1}},"3":{"start":{"line":5,"column":16},"end":{"line":5,"column":18}},"4":{"start":{"line":6,"column":1},"end":{"line":9,"column":2}},"5":{"start":{"line":7,"column":26},"end":{"line":7,"column":42}},"6":{"start":{"line":8,"column":2},"end":{"line":8,"column":75}},"7":{"start":{"line":10,"column":1},"end":{"line":10,"column":43}},"8":{"start":{"line":10,"column":15},"end":{"line":10,"column":43}},"9":{"start":{"line":11,"column":1},"end":{"line":16,"column":3}},"10":{"start":{"line":19,"column":20},"end":{"line":27,"column":1}},"11":{"start":{"line":20,"column":16},"end":{"line":20,"column":92}},"12":{"start":{"line":21,"column":1},"end":{"line":26,"column":3}},"13":{"start":{"line":29,"column":0},"end":{"line":29,"column":45}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":4,"column":20},"end":{"line":4,"column":21}},"loc":{"start":{"line":4,"column":47},"end":{"line":17,"column":1}},"line":4},"1":{"name":"(anonymous_1)","decl":{"start":{"line":19,"column":20},"end":{"line":19,"column":21}},"loc":{"start":{"line":19,"column":55},"end":{"line":27,"column":1}},"line":19}},"branchMap":{"0":{"loc":{"start":{"line":6,"column":1},"end":{"line":9,"column":2}},"type":"if","locations":[{"start":{"line":6,"column":1},"end":{"line":9,"column":2}},{"start":{"line":6,"column":1},"end":{"line":9,"column":2}}],"line":6},"1":{"loc":{"start":{"line":10,"column":1},"end":{"line":10,"column":43}},"type":"if","locations":[{"start":{"line":10,"column":1},"end":{"line":10,"column":43}},{"start":{"line":10,"column":1},"end":{"line":10,"column":43}}],"line":10},"2":{"loc":{"start":{"line":20,"column":16},"end":{"line":20,"column":92}},"type":"cond-expr","locations":[{"start":{"line":20,"column":32},"end":{"line":20,"column":45}},{"start":{"line":20,"column":48},"end":{"line":20,"column":92}}],"line":20}},"s":{"0":1,"1":1,"2":1,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":0,"13":1},"f":{"0":0,"1":0},"b":{"0":[0,0],"1":[0,0],"2":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"f3dae97792637a222329b6856891e0aaeaf2d301"}
+,"/home/denis/Zazmic_Internship/hw5/services/rateLimitService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/rateLimitService.js","statementMap":{"0":{"start":{"line":1,"column":18},"end":{"line":1,"column":47}},"1":{"start":{"line":2,"column":20},"end":{"line":2,"column":47}},"2":{"start":{"line":3,"column":29},"end":{"line":3,"column":61}},"3":{"start":{"line":5,"column":0},"end":{"line":33,"column":1}},"4":{"start":{"line":6,"column":17},"end":{"line":13,"column":3}},"5":{"start":{"line":15,"column":22},"end":{"line":23,"column":3}},"6":{"start":{"line":25,"column":19},"end":{"line":30,"column":3}},"7":{"start":{"line":32,"column":1},"end":{"line":32,"column":44}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":17},"end":{"line":5,"column":18}},"loc":{"start":{"line":5,"column":27},"end":{"line":33,"column":1}},"line":5}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"c9dcba3e89082818906335383353098399a9b727"}
+,"/home/denis/Zazmic_Internship/hw5/services/redisConnectService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/redisConnectService.js","statementMap":{"0":{"start":{"line":1,"column":10},"end":{"line":1,"column":28}},"1":{"start":{"line":2,"column":15},"end":{"line":2,"column":43}},"2":{"start":{"line":3,"column":24},"end":{"line":3,"column":43}},"3":{"start":{"line":5,"column":0},"end":{"line":7,"column":2}},"4":{"start":{"line":6,"column":1},"end":{"line":6,"column":58}},"5":{"start":{"line":9,"column":0},"end":{"line":9,"column":23}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":19},"end":{"line":5,"column":20}},"loc":{"start":{"line":5,"column":26},"end":{"line":7,"column":1}},"line":5}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":1},"f":{"0":0},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"821831e44397782ecec8c8f7438128d33fce7f24"}
+,"/home/denis/Zazmic_Internship/hw5/services/socketService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/socketService.js","statementMap":{"0":{"start":{"line":1,"column":17},"end":{"line":1,"column":37}},"1":{"start":{"line":2,"column":25},"end":{"line":2,"column":53}},"2":{"start":{"line":3,"column":16},"end":{"line":3,"column":42}},"3":{"start":{"line":5,"column":24},"end":{"line":5,"column":43}},"4":{"start":{"line":7,"column":0},"end":{"line":39,"column":1}},"5":{"start":{"line":8,"column":12},"end":{"line":8,"column":28}},"6":{"start":{"line":9,"column":1},"end":{"line":9,"column":43}},"7":{"start":{"line":10,"column":1},"end":{"line":16,"column":2}},"8":{"start":{"line":14,"column":43},"end":{"line":14,"column":51}},"9":{"start":{"line":18,"column":1},"end":{"line":37,"column":3}},"10":{"start":{"line":19,"column":2},"end":{"line":21,"column":4}},"11":{"start":{"line":20,"column":3},"end":{"line":20,"column":87}},"12":{"start":{"line":20,"column":12},"end":{"line":20,"column":87}},"13":{"start":{"line":22,"column":13},"end":{"line":22,"column":52}},"14":{"start":{"line":23,"column":2},"end":{"line":28,"column":4}},"15":{"start":{"line":24,"column":3},"end":{"line":27,"column":58}},"16":{"start":{"line":26,"column":21},"end":{"line":26,"column":27}},"17":{"start":{"line":27,"column":22},"end":{"line":27,"column":57}},"18":{"start":{"line":29,"column":2},"end":{"line":36,"column":3}},"19":{"start":{"line":30,"column":3},"end":{"line":30,"column":77}},"20":{"start":{"line":30,"column":44},"end":{"line":30,"column":76}},"21":{"start":{"line":31,"column":3},"end":{"line":31,"column":80}},"22":{"start":{"line":31,"column":46},"end":{"line":31,"column":79}},"23":{"start":{"line":33,"column":3},"end":{"line":35,"column":5}},"24":{"start":{"line":34,"column":4},"end":{"line":34,"column":79}},"25":{"start":{"line":38,"column":1},"end":{"line":38,"column":10}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":7,"column":17},"end":{"line":7,"column":18}},"loc":{"start":{"line":7,"column":48},"end":{"line":39,"column":1}},"line":7},"1":{"name":"(anonymous_1)","decl":{"start":{"line":14,"column":9},"end":{"line":14,"column":10}},"loc":{"start":{"line":14,"column":43},"end":{"line":14,"column":51}},"line":14},"2":{"name":"(anonymous_2)","decl":{"start":{"line":18,"column":21},"end":{"line":18,"column":22}},"loc":{"start":{"line":18,"column":38},"end":{"line":37,"column":2}},"line":18},"3":{"name":"(anonymous_3)","decl":{"start":{"line":19,"column":29},"end":{"line":19,"column":30}},"loc":{"start":{"line":19,"column":47},"end":{"line":21,"column":3}},"line":19},"4":{"name":"(anonymous_4)","decl":{"start":{"line":23,"column":13},"end":{"line":23,"column":14}},"loc":{"start":{"line":23,"column":31},"end":{"line":28,"column":3}},"line":23},"5":{"name":"(anonymous_5)","decl":{"start":{"line":26,"column":10},"end":{"line":26,"column":11}},"loc":{"start":{"line":26,"column":21},"end":{"line":26,"column":27}},"line":26},"6":{"name":"(anonymous_6)","decl":{"start":{"line":27,"column":11},"end":{"line":27,"column":12}},"loc":{"start":{"line":27,"column":22},"end":{"line":27,"column":57}},"line":27},"7":{"name":"(anonymous_7)","decl":{"start":{"line":30,"column":31},"end":{"line":30,"column":32}},"loc":{"start":{"line":30,"column":44},"end":{"line":30,"column":76}},"line":30},"8":{"name":"(anonymous_8)","decl":{"start":{"line":31,"column":33},"end":{"line":31,"column":34}},"loc":{"start":{"line":31,"column":46},"end":{"line":31,"column":79}},"line":31},"9":{"name":"(anonymous_9)","decl":{"start":{"line":33,"column":31},"end":{"line":33,"column":32}},"loc":{"start":{"line":33,"column":44},"end":{"line":35,"column":4}},"line":33}},"branchMap":{"0":{"loc":{"start":{"line":20,"column":3},"end":{"line":20,"column":87}},"type":"if","locations":[{"start":{"line":20,"column":3},"end":{"line":20,"column":87}},{"start":{"line":20,"column":3},"end":{"line":20,"column":87}}],"line":20},"1":{"loc":{"start":{"line":29,"column":2},"end":{"line":36,"column":3}},"type":"if","locations":[{"start":{"line":29,"column":2},"end":{"line":36,"column":3}},{"start":{"line":29,"column":2},"end":{"line":36,"column":3}}],"line":29}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":0,"9":1,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":1},"f":{"0":1,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0},"b":{"0":[0,0],"1":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"74419e1df21ef0e52cddf14450c4db6638a40dab"}
+,"/home/denis/Zazmic_Internship/hw5/services/stripeService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/stripeService.js","statementMap":{"0":{"start":{"line":1,"column":15},"end":{"line":1,"column":55}},"1":{"start":{"line":2,"column":21},"end":{"line":2,"column":53}},"2":{"start":{"line":3,"column":18},"end":{"line":3,"column":47}},"3":{"start":{"line":5,"column":23},"end":{"line":12,"column":2}},"4":{"start":{"line":6,"column":18},"end":{"line":6,"column":85}},"5":{"start":{"line":7,"column":17},"end":{"line":10,"column":2}},"6":{"start":{"line":11,"column":1},"end":{"line":11,"column":101}},"7":{"start":{"line":14,"column":21},"end":{"line":23,"column":2}},"8":{"start":{"line":15,"column":16},"end":{"line":21,"column":3}},"9":{"start":{"line":22,"column":1},"end":{"line":22,"column":42}},"10":{"start":{"line":25,"column":25},"end":{"line":32,"column":2}},"11":{"start":{"line":26,"column":17},"end":{"line":26,"column":68}},"12":{"start":{"line":27,"column":11},"end":{"line":27,"column":12}},"13":{"start":{"line":28,"column":1},"end":{"line":30,"column":3}},"14":{"start":{"line":29,"column":2},"end":{"line":29,"column":20}},"15":{"start":{"line":31,"column":1},"end":{"line":31,"column":17}},"16":{"start":{"line":34,"column":0},"end":{"line":34,"column":67}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":36},"end":{"line":5,"column":37}},"loc":{"start":{"line":5,"column":59},"end":{"line":12,"column":1}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":14,"column":34},"end":{"line":14,"column":35}},"loc":{"start":{"line":14,"column":79},"end":{"line":23,"column":1}},"line":14},"2":{"name":"(anonymous_2)","decl":{"start":{"line":25,"column":38},"end":{"line":25,"column":39}},"loc":{"start":{"line":25,"column":58},"end":{"line":32,"column":1}},"line":25},"3":{"name":"(anonymous_3)","decl":{"start":{"line":28,"column":22},"end":{"line":28,"column":23}},"loc":{"start":{"line":28,"column":30},"end":{"line":30,"column":2}},"line":28}},"branchMap":{"0":{"loc":{"start":{"line":11,"column":8},"end":{"line":11,"column":101}},"type":"cond-expr","locations":[{"start":{"line":11,"column":18},"end":{"line":11,"column":94}},{"start":{"line":11,"column":97},"end":{"line":11,"column":101}}],"line":11},"1":{"loc":{"start":{"line":22,"column":8},"end":{"line":22,"column":42}},"type":"cond-expr","locations":[{"start":{"line":22,"column":17},"end":{"line":22,"column":35}},{"start":{"line":22,"column":38},"end":{"line":22,"column":42}}],"line":22}},"s":{"0":1,"1":1,"2":1,"3":1,"4":0,"5":0,"6":0,"7":1,"8":0,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":0,"16":1},"f":{"0":0,"1":0,"2":0,"3":0},"b":{"0":[0,0],"1":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"a0a642d6369c9117dbcf87f8e72f9cbf3ba2735a"}
+,"/home/denis/Zazmic_Internship/hw5/services/validationService.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/validationService.js","statementMap":{"0":{"start":{"line":1,"column":17},"end":{"line":1,"column":45}},"1":{"start":{"line":3,"column":23},"end":{"line":3,"column":68}},"2":{"start":{"line":5,"column":15},"end":{"line":12,"column":1}},"3":{"start":{"line":6,"column":17},"end":{"line":6,"column":27}},"4":{"start":{"line":7,"column":17},"end":{"line":7,"column":24}},"5":{"start":{"line":8,"column":1},"end":{"line":8,"column":35}},"6":{"start":{"line":8,"column":23},"end":{"line":8,"column":35}},"7":{"start":{"line":9,"column":1},"end":{"line":9,"column":39}},"8":{"start":{"line":9,"column":27},"end":{"line":9,"column":39}},"9":{"start":{"line":10,"column":1},"end":{"line":10,"column":39}},"10":{"start":{"line":10,"column":27},"end":{"line":10,"column":39}},"11":{"start":{"line":11,"column":1},"end":{"line":11,"column":12}},"12":{"start":{"line":14,"column":27},"end":{"line":14,"column":53}},"13":{"start":{"line":14,"column":36},"end":{"line":14,"column":53}},"14":{"start":{"line":16,"column":31},"end":{"line":33,"column":2}},"15":{"start":{"line":35,"column":24},"end":{"line":46,"column":2}},"16":{"start":{"line":48,"column":20},"end":{"line":52,"column":1}},"17":{"start":{"line":49,"column":14},"end":{"line":49,"column":29}},"18":{"start":{"line":50,"column":1},"end":{"line":50,"column":30}},"19":{"start":{"line":50,"column":19},"end":{"line":50,"column":30}},"20":{"start":{"line":51,"column":1},"end":{"line":51,"column":13}},"21":{"start":{"line":54,"column":26},"end":{"line":66,"column":2}},"22":{"start":{"line":68,"column":27},"end":{"line":75,"column":2}},"23":{"start":{"line":77,"column":26},"end":{"line":83,"column":2}},"24":{"start":{"line":85,"column":0},"end":{"line":85,"column":118}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":5,"column":15},"end":{"line":5,"column":16}},"loc":{"start":{"line":5,"column":24},"end":{"line":12,"column":1}},"line":5},"1":{"name":"(anonymous_1)","decl":{"start":{"line":14,"column":27},"end":{"line":14,"column":28}},"loc":{"start":{"line":14,"column":36},"end":{"line":14,"column":53}},"line":14},"2":{"name":"(anonymous_2)","decl":{"start":{"line":48,"column":20},"end":{"line":48,"column":21}},"loc":{"start":{"line":48,"column":29},"end":{"line":52,"column":1}},"line":48}},"branchMap":{"0":{"loc":{"start":{"line":8,"column":1},"end":{"line":8,"column":35}},"type":"if","locations":[{"start":{"line":8,"column":1},"end":{"line":8,"column":35}},{"start":{"line":8,"column":1},"end":{"line":8,"column":35}}],"line":8},"1":{"loc":{"start":{"line":9,"column":1},"end":{"line":9,"column":39}},"type":"if","locations":[{"start":{"line":9,"column":1},"end":{"line":9,"column":39}},{"start":{"line":9,"column":1},"end":{"line":9,"column":39}}],"line":9},"2":{"loc":{"start":{"line":10,"column":1},"end":{"line":10,"column":39}},"type":"if","locations":[{"start":{"line":10,"column":1},"end":{"line":10,"column":39}},{"start":{"line":10,"column":1},"end":{"line":10,"column":39}}],"line":10},"3":{"loc":{"start":{"line":50,"column":1},"end":{"line":50,"column":30}},"type":"if","locations":[{"start":{"line":50,"column":1},"end":{"line":50,"column":30}},{"start":{"line":50,"column":1},"end":{"line":50,"column":30}}],"line":50}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":0,"7":1,"8":0,"9":1,"10":0,"11":1,"12":1,"13":0,"14":1,"15":1,"16":1,"17":0,"18":0,"19":0,"20":0,"21":1,"22":1,"23":1,"24":1},"f":{"0":1,"1":0,"2":0},"b":{"0":[0,1],"1":[0,1],"2":[0,1],"3":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"e239f4c62f3446e899fb6feb0c63777486531dff"}
+,"/home/denis/Zazmic_Internship/hw5/services/middlewares/authCheck.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/middlewares/authCheck.js","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":5,"column":1}},"1":{"start":{"line":3,"column":1},"end":{"line":3,"column":41}},"2":{"start":{"line":3,"column":28},"end":{"line":3,"column":41}},"3":{"start":{"line":4,"column":1},"end":{"line":4,"column":54}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":2,"column":17},"end":{"line":2,"column":18}},"loc":{"start":{"line":2,"column":37},"end":{"line":5,"column":1}},"line":2}},"branchMap":{"0":{"loc":{"start":{"line":3,"column":1},"end":{"line":3,"column":41}},"type":"if","locations":[{"start":{"line":3,"column":1},"end":{"line":3,"column":41}},{"start":{"line":3,"column":1},"end":{"line":3,"column":41}}],"line":3}},"s":{"0":1,"1":0,"2":0,"3":0},"f":{"0":0},"b":{"0":[0,0]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"b9c2c02e5423ca7c1b8892858085319f1895ee08"}
+,"/home/denis/Zazmic_Internship/hw5/services/middlewares/validation.js": {"path":"/home/denis/Zazmic_Internship/hw5/services/middlewares/validation.js","statementMap":{"0":{"start":{"line":1,"column":29},"end":{"line":1,"column":57}},"1":{"start":{"line":3,"column":19},"end":{"line":13,"column":1}},"2":{"start":{"line":4,"column":21},"end":{"line":11,"column":2}},"3":{"start":{"line":7,"column":18},"end":{"line":7,"column":39}},"4":{"start":{"line":8,"column":3},"end":{"line":8,"column":81}},"5":{"start":{"line":8,"column":26},"end":{"line":8,"column":81}},"6":{"start":{"line":9,"column":3},"end":{"line":9,"column":9}},"7":{"start":{"line":12,"column":1},"end":{"line":12,"column":19}},"8":{"start":{"line":15,"column":0},"end":{"line":15,"column":31}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":3,"column":19},"end":{"line":3,"column":20}},"loc":{"start":{"line":3,"column":28},"end":{"line":13,"column":1}},"line":3},"1":{"name":"(anonymous_1)","decl":{"start":{"line":6,"column":2},"end":{"line":6,"column":3}},"loc":{"start":{"line":6,"column":22},"end":{"line":10,"column":3}},"line":6}},"branchMap":{"0":{"loc":{"start":{"line":8,"column":3},"end":{"line":8,"column":81}},"type":"if","locations":[{"start":{"line":8,"column":3},"end":{"line":8,"column":81}},{"start":{"line":8,"column":3},"end":{"line":8,"column":81}}],"line":8}},"s":{"0":1,"1":1,"2":5,"3":1,"4":1,"5":0,"6":1,"7":5,"8":1},"f":{"0":5,"1":1},"b":{"0":[0,1]},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"379fa192f1cc03574715685d6e3aaa9db9006901"}
+,"/home/denis/Zazmic_Internship/hw5/tests/helpers.js": {"path":"/home/denis/Zazmic_Internship/hw5/tests/helpers.js","statementMap":{"0":{"start":{"line":2,"column":14},"end":{"line":2,"column":30}},"1":{"start":{"line":3,"column":18},"end":{"line":3,"column":38}},"2":{"start":{"line":4,"column":12},"end":{"line":4,"column":31}},"3":{"start":{"line":5,"column":28},"end":{"line":5,"column":63}},"4":{"start":{"line":6,"column":16},"end":{"line":6,"column":30}},"5":{"start":{"line":8,"column":0},"end":{"line":27,"column":1}},"6":{"start":{"line":10,"column":20},"end":{"line":10,"column":42}},"7":{"start":{"line":11,"column":19},"end":{"line":11,"column":40}},"8":{"start":{"line":12,"column":16},"end":{"line":12,"column":38}},"9":{"start":{"line":13,"column":19},"end":{"line":13,"column":44}},"10":{"start":{"line":14,"column":23},"end":{"line":14,"column":84}},"11":{"start":{"line":16,"column":2},"end":{"line":16,"column":91}},"12":{"start":{"line":17,"column":25},"end":{"line":17,"column":54}},"13":{"start":{"line":18,"column":16},"end":{"line":18,"column":48}},"14":{"start":{"line":19,"column":19},"end":{"line":19,"column":84}},"15":{"start":{"line":21,"column":2},"end":{"line":21,"column":26}},"16":{"start":{"line":22,"column":15},"end":{"line":22,"column":33}},"17":{"start":{"line":23,"column":2},"end":{"line":23,"column":72}},"18":{"start":{"line":25,"column":2},"end":{"line":25,"column":13}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":9,"column":15},"end":{"line":9,"column":16}},"loc":{"start":{"line":9,"column":27},"end":{"line":26,"column":2}},"line":9}},"branchMap":{},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1},"f":{"0":1},"b":{},"_coverageSchema":"43e27e138ebf9cfc5966b082cf9a028302ed4184","hash":"1454659821cf0611c68224bf96b942fb5d06c79b"}
+}
diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css
new file mode 100644
index 0000000..f418035
--- /dev/null
+++ b/coverage/lcov-report/base.css
@@ -0,0 +1,224 @@
+body, html {
+ margin:0; padding: 0;
+ height: 100%;
+}
+body {
+ font-family: Helvetica Neue, Helvetica, Arial;
+ font-size: 14px;
+ color:#333;
+}
+.small { font-size: 12px; }
+*, *:after, *:before {
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ box-sizing:border-box;
+ }
+h1 { font-size: 20px; margin: 0;}
+h2 { font-size: 14px; }
+pre {
+ font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ margin: 0;
+ padding: 0;
+ -moz-tab-size: 2;
+ -o-tab-size: 2;
+ tab-size: 2;
+}
+a { color:#0074D9; text-decoration:none; }
+a:hover { text-decoration:underline; }
+.strong { font-weight: bold; }
+.space-top1 { padding: 10px 0 0 0; }
+.pad2y { padding: 20px 0; }
+.pad1y { padding: 10px 0; }
+.pad2x { padding: 0 20px; }
+.pad2 { padding: 20px; }
+.pad1 { padding: 10px; }
+.space-left2 { padding-left:55px; }
+.space-right2 { padding-right:20px; }
+.center { text-align:center; }
+.clearfix { display:block; }
+.clearfix:after {
+ content:'';
+ display:block;
+ height:0;
+ clear:both;
+ visibility:hidden;
+ }
+.fl { float: left; }
+@media only screen and (max-width:640px) {
+ .col3 { width:100%; max-width:100%; }
+ .hide-mobile { display:none!important; }
+}
+
+.quiet {
+ color: #7f7f7f;
+ color: rgba(0,0,0,0.5);
+}
+.quiet a { opacity: 0.7; }
+
+.fraction {
+ font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
+ font-size: 10px;
+ color: #555;
+ background: #E8E8E8;
+ padding: 4px 5px;
+ border-radius: 3px;
+ vertical-align: middle;
+}
+
+div.path a:link, div.path a:visited { color: #333; }
+table.coverage {
+ border-collapse: collapse;
+ margin: 10px 0 0 0;
+ padding: 0;
+}
+
+table.coverage td {
+ margin: 0;
+ padding: 0;
+ vertical-align: top;
+}
+table.coverage td.line-count {
+ text-align: right;
+ padding: 0 5px 0 20px;
+}
+table.coverage td.line-coverage {
+ text-align: right;
+ padding-right: 10px;
+ min-width:20px;
+}
+
+table.coverage td span.cline-any {
+ display: inline-block;
+ padding: 0 5px;
+ width: 100%;
+}
+.missing-if-branch {
+ display: inline-block;
+ margin-right: 5px;
+ border-radius: 3px;
+ position: relative;
+ padding: 0 4px;
+ background: #333;
+ color: yellow;
+}
+
+.skip-if-branch {
+ display: none;
+ margin-right: 10px;
+ position: relative;
+ padding: 0 4px;
+ background: #ccc;
+ color: white;
+}
+.missing-if-branch .typ, .skip-if-branch .typ {
+ color: inherit !important;
+}
+.coverage-summary {
+ border-collapse: collapse;
+ width: 100%;
+}
+.coverage-summary tr { border-bottom: 1px solid #bbb; }
+.keyline-all { border: 1px solid #ddd; }
+.coverage-summary td, .coverage-summary th { padding: 10px; }
+.coverage-summary tbody { border: 1px solid #bbb; }
+.coverage-summary td { border-right: 1px solid #bbb; }
+.coverage-summary td:last-child { border-right: none; }
+.coverage-summary th {
+ text-align: left;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.coverage-summary th.file { border-right: none !important; }
+.coverage-summary th.pct { }
+.coverage-summary th.pic,
+.coverage-summary th.abs,
+.coverage-summary td.pct,
+.coverage-summary td.abs { text-align: right; }
+.coverage-summary td.file { white-space: nowrap; }
+.coverage-summary td.pic { min-width: 120px !important; }
+.coverage-summary tfoot td { }
+
+.coverage-summary .sorter {
+ height: 10px;
+ width: 7px;
+ display: inline-block;
+ margin-left: 0.5em;
+ background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
+}
+.coverage-summary .sorted .sorter {
+ background-position: 0 -20px;
+}
+.coverage-summary .sorted-desc .sorter {
+ background-position: 0 -10px;
+}
+.status-line { height: 10px; }
+/* yellow */
+.cbranch-no { background: yellow !important; color: #111; }
+/* dark red */
+.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
+.low .chart { border:1px solid #C21F39 }
+.highlighted,
+.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
+ background: #C21F39 !important;
+}
+/* medium red */
+.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
+/* light red */
+.low, .cline-no { background:#FCE1E5 }
+/* light green */
+.high, .cline-yes { background:rgb(230,245,208) }
+/* medium green */
+.cstat-yes { background:rgb(161,215,106) }
+/* dark green */
+.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
+.high .chart { border:1px solid rgb(77,146,33) }
+/* dark yellow (gold) */
+.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
+.medium .chart { border:1px solid #f9cd0b; }
+/* light yellow */
+.medium { background: #fff4c2; }
+
+.cstat-skip { background: #ddd; color: #111; }
+.fstat-skip { background: #ddd; color: #111 !important; }
+.cbranch-skip { background: #ddd !important; color: #111; }
+
+span.cline-neutral { background: #eaeaea; }
+
+.coverage-summary td.empty {
+ opacity: .5;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ line-height: 1;
+ color: #888;
+}
+
+.cover-fill, .cover-empty {
+ display:inline-block;
+ height: 12px;
+}
+.chart {
+ line-height: 0;
+}
+.cover-empty {
+ background: white;
+}
+.cover-full {
+ border-right: none !important;
+}
+pre.prettyprint {
+ border: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+}
+.com { color: #999 !important; }
+.ignore-none { color: #999; font-weight: normal; }
+
+.wrapper {
+ min-height: 100%;
+ height: auto !important;
+ height: 100%;
+ margin: 0 auto -48px;
+}
+.footer, .push {
+ height: 48px;
+}
diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js
new file mode 100644
index 0000000..c7ff5a5
--- /dev/null
+++ b/coverage/lcov-report/block-navigation.js
@@ -0,0 +1,79 @@
+/* eslint-disable */
+var jumpToCode = (function init() {
+ // Classes of code we would like to highlight in the file view
+ var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
+
+ // Elements to highlight in the file listing view
+ var fileListingElements = ['td.pct.low'];
+
+ // We don't want to select elements that are direct descendants of another match
+ var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
+
+ // Selecter that finds elements on the page to which we can jump
+ var selector =
+ fileListingElements.join(', ') +
+ ', ' +
+ notSelector +
+ missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
+
+ // The NodeList of matching elements
+ var missingCoverageElements = document.querySelectorAll(selector);
+
+ var currentIndex;
+
+ function toggleClass(index) {
+ missingCoverageElements
+ .item(currentIndex)
+ .classList.remove('highlighted');
+ missingCoverageElements.item(index).classList.add('highlighted');
+ }
+
+ function makeCurrent(index) {
+ toggleClass(index);
+ currentIndex = index;
+ missingCoverageElements.item(index).scrollIntoView({
+ behavior: 'smooth',
+ block: 'center',
+ inline: 'center'
+ });
+ }
+
+ function goToPrevious() {
+ var nextIndex = 0;
+ if (typeof currentIndex !== 'number' || currentIndex === 0) {
+ nextIndex = missingCoverageElements.length - 1;
+ } else if (missingCoverageElements.length > 1) {
+ nextIndex = currentIndex - 1;
+ }
+
+ makeCurrent(nextIndex);
+ }
+
+ function goToNext() {
+ var nextIndex = 0;
+
+ if (
+ typeof currentIndex === 'number' &&
+ currentIndex < missingCoverageElements.length - 1
+ ) {
+ nextIndex = currentIndex + 1;
+ }
+
+ makeCurrent(nextIndex);
+ }
+
+ return function jump(event) {
+ switch (event.which) {
+ case 78: // n
+ case 74: // j
+ goToNext();
+ break;
+ case 66: // b
+ case 75: // k
+ case 80: // p
+ goToPrevious();
+ break;
+ }
+ };
+})();
+window.addEventListener('keydown', jumpToCode);
diff --git a/coverage/lcov-report/hw5/db/constant.js.html b/coverage/lcov-report/hw5/db/constant.js.html
new file mode 100644
index 0000000..10c80f9
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/constant.js.html
@@ -0,0 +1,84 @@
+
+
+
+ Code coverage report for hw5/db/constant.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 1/1
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 0/0
+
+
+ 100%
+ Lines
+ 1/1
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6 1x
+
+
+
+
+ module.exports = {
+ paymentTemplate: 'd-66a2ce523e89461eb90b499d7cffe10a',
+ accountVerificationTemplate: 'd-e4b6aa6a05744c0689953f70995abf11',
+ proAccountTemplate: 'd-d39047ffe8324992ad23c3b539f7b43d'
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/dbConnection.js.html b/coverage/lcov-report/hw5/db/dbConnection.js.html
new file mode 100644
index 0000000..db8ff7f
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/dbConnection.js.html
@@ -0,0 +1,108 @@
+
+
+
+ Code coverage report for hw5/db/dbConnection.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 2/2
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 0/0
+
+
+ 100%
+ Lines
+ 2/2
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14 1x
+
+1x
+
+
+
+
+
+
+
+
+
+
+ const Sequelize = require('sequelize')
+
+module.exports = new Sequelize(process.env.DATABASE_URL, {
+ dialect: 'mysql',
+ logging: console.log,
+ benchmark: true,
+ pool: {
+ max: 5,
+ min: 0,
+ acquire: 30000,
+ idle: 10000
+ }
+})
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/index.html b/coverage/lcov-report/hw5/db/index.html
new file mode 100644
index 0000000..4c6991b
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/index.html
@@ -0,0 +1,110 @@
+
+
+
+ Code coverage report for hw5/db
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 3/3
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 0/0
+
+
+ 100%
+ Lines
+ 3/3
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ constant.js
+
+ 100%
+ 1/1
+ 100%
+ 0/0
+ 100%
+ 0/0
+ 100%
+ 1/1
+
+
+
+ dbConnection.js
+
+ 100%
+ 2/2
+ 100%
+ 0/0
+ 100%
+ 0/0
+ 100%
+ 2/2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/models/Articles.js.html b/coverage/lcov-report/hw5/db/models/Articles.js.html
new file mode 100644
index 0000000..bcc6eab
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/models/Articles.js.html
@@ -0,0 +1,252 @@
+
+
+
+ Code coverage report for hw5/db/models/Articles.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 7/7
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 7/7
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62 1x
+1x
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+1x
+1x
+
+
+1x
+ const { Model, DataTypes } = require('sequelize')
+const sequelize = require('../dbConnection')
+
+class Articles extends Model {}
+
+Articles.init(
+ {
+ id: {
+ type: DataTypes.INTEGER,
+ unique: true,
+ allowNull: false,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ title: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ content: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ picture: {
+ type: DataTypes.STRING,
+ allowNull: true
+ },
+ createdAt: {
+ type: DataTypes.DATE,
+ defaultValue: DataTypes.NOW,
+ allowNull: false,
+ field: 'created_at'
+ },
+ updatedAt: {
+ type: DataTypes.DATE,
+ defaultValue: DataTypes.NOW,
+ allowNull: false,
+ field: 'updated_at'
+ },
+ publishedAt: {
+ type: DataTypes.DATE,
+ defaultValue: DataTypes.NOW,
+ allowNull: false,
+ field: 'published_at'
+ },
+ authorId: {
+ type: DataTypes.INTEGER,
+ field: 'author_id'
+ }
+ },
+ {
+ sequelize,
+ modelName: 'articles'
+ }
+)
+
+Articles.associate = models => {
+ Articles.belongsTo(models.Users, { as: 'author', foreignKey: 'authorId' })
+ Articles.hasMany(models.Comments, { as: 'comments', foreignKey: 'articleId' })
+}
+
+module.exports = Articles
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/models/Comments.js.html b/coverage/lcov-report/hw5/db/models/Comments.js.html
new file mode 100644
index 0000000..c0ef547
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/models/Comments.js.html
@@ -0,0 +1,210 @@
+
+
+
+ Code coverage report for hw5/db/models/Comments.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 7/7
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 7/7
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48 1x
+1x
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+1x
+1x
+
+
+1x
+ const { Model, DataTypes } = require('sequelize')
+const sequelize = require('../dbConnection')
+
+class Comments extends Model {}
+
+Comments.init(
+ {
+ id: {
+ type: DataTypes.INTEGER,
+ unique: true,
+ allowNull: false,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ content: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ authorId: {
+ type: DataTypes.INTEGER,
+ field: 'author_id'
+ },
+ articleId: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ field: 'article_id'
+ },
+ createdAt: {
+ type: DataTypes.DATE,
+ defaultValue: DataTypes.NOW,
+ allowNull: false,
+ field: 'created_at'
+ }
+ },
+ {
+ sequelize,
+ timestamps: false,
+ modelName: 'comments'
+ }
+)
+
+Comments.associate = models => {
+ Comments.belongsTo(models.Users, { as: 'author', foreignKey: 'authorId' })
+ Comments.belongsTo(models.Articles, { as: 'article', foreignKey: 'articleId' })
+}
+
+module.exports = Comments
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/models/Providers.js.html b/coverage/lcov-report/hw5/db/models/Providers.js.html
new file mode 100644
index 0000000..c1fc816
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/models/Providers.js.html
@@ -0,0 +1,201 @@
+
+
+
+ Code coverage report for hw5/db/models/Providers.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 6/6
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 6/6
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45 1x
+1x
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+1x
+
+
+
+
+
+1x
+ const { Model, DataTypes } = require('sequelize')
+const sequelize = require('../dbConnection')
+
+class Providers extends Model {}
+
+Providers.init(
+ {
+ id: {
+ type: DataTypes.INTEGER,
+ unique: true,
+ allowNull: false,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ userId: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ field: 'user_id'
+ },
+ provider: {
+ type: DataTypes.STRING,
+ allowNull: false
+ },
+ providerUserId: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ field: 'provider_user_id'
+ }
+ },
+ {
+ sequelize,
+ timestamps: false,
+ modelName: 'oauth_accounts'
+ }
+)
+
+Providers.associate = models => {
+ Providers.belongsTo(models.Users, {
+ as: 'user',
+ foreignKey: 'userId'
+ })
+}
+
+module.exports = Providers
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/models/Users.js.html b/coverage/lcov-report/hw5/db/models/Users.js.html
new file mode 100644
index 0000000..a0c0029
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/models/Users.js.html
@@ -0,0 +1,354 @@
+
+
+
+ Code coverage report for hw5/db/models/Users.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 9/9
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 9/9
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96 1x
+1x
+1x
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+1x
+1x
+1x
+
+
+1x
+ const { Model, DataTypes } = require('sequelize')
+const sequelize = require('../dbConnection')
+const { hashPassword } = require('../../services/hashPsw')
+
+class Users extends Model {}
+
+Users.init(
+ {
+ id: {
+ type: DataTypes.INTEGER,
+ unique: true,
+ allowNull: false,
+ primaryKey: true,
+ autoIncrement: true
+ },
+ firstName: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ field: 'first_name'
+ },
+ lastName: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ field: 'last_name'
+ },
+ email: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ field: 'email'
+ },
+ password: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ field: 'password'
+ },
+ picture: {
+ type: DataTypes.STRING
+ },
+ createdAt: {
+ type: DataTypes.DATE,
+ defaultValue: DataTypes.NOW,
+ allowNull: false,
+ field: 'created_at'
+ },
+ updatedAt: {
+ type: DataTypes.DATE,
+ defaultValue: DataTypes.NOW,
+ allowNull: false,
+ field: 'updated_at'
+ },
+ isVerified: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: 0,
+ allowNull: false,
+ field: 'is_verified'
+ },
+ is_pro: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: 0,
+ allowNull: false,
+ field: 'is_pro'
+ },
+ stripe_customer_id: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: null,
+ allowNull: true,
+ field: 'stripe_customer_id'
+ },
+ stripe_card_id: {
+ type: DataTypes.BOOLEAN,
+ defaultValue: null,
+ allowNull: true,
+ field: 'stripe_card_id'
+ }
+ },
+ {
+ sequelize,
+ modelName: 'users',
+ defaultScope: {
+ attributes: { exclude: ['password'] }
+ },
+ hooks: {
+ beforeCreate: hashPassword,
+ beforeUpdate: hashPassword
+ }
+ }
+)
+
+Users.associate = models => {
+ Users.hasMany(models.Articles, { as: 'articles', foreignKey: 'authorId' })
+ Users.hasMany(models.Providers, { as: 'oauth_accounts', foreignKey: 'userId' })
+ Users.hasMany(models.Comments, { as: 'comments', foreignKey: 'authorId' })
+}
+
+module.exports = Users
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/models/index.html b/coverage/lcov-report/hw5/db/models/index.html
new file mode 100644
index 0000000..f14f913
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/models/index.html
@@ -0,0 +1,149 @@
+
+
+
+ Code coverage report for hw5/db/models
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 35/35
+
+
+ 50%
+ Branches
+ 1/2
+
+
+ 100%
+ Functions
+ 5/5
+
+
+ 100%
+ Lines
+ 35/35
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ Articles.js
+
+ 100%
+ 7/7
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 7/7
+
+
+
+ Comments.js
+
+ 100%
+ 7/7
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 7/7
+
+
+
+ Providers.js
+
+ 100%
+ 6/6
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 6/6
+
+
+
+ Users.js
+
+ 100%
+ 9/9
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 9/9
+
+
+
+ index.js
+
+ 100%
+ 6/6
+ 50%
+ 1/2
+ 100%
+ 1/1
+ 100%
+ 6/6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/db/models/index.js.html b/coverage/lcov-report/hw5/db/models/index.js.html
new file mode 100644
index 0000000..71874ac
--- /dev/null
+++ b/coverage/lcov-report/hw5/db/models/index.js.html
@@ -0,0 +1,117 @@
+
+
+
+ Code coverage report for hw5/db/models/index.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 6/6
+
+
+ 50%
+ Branches
+ 1/2
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 6/6
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17 1x
+
+
+
+
+
+
+1x
+
+1x
+4x
+4x
+
+
+
+1x
+ const models = {
+ Users: require('./Users'),
+ Articles: require('./Articles'),
+ Providers: require('./Providers'),
+ Comments: require('./Comments')
+}
+
+const modelNames = Object.keys(models)
+
+modelNames.forEach(modelName => {
+ E if (models[modelName].associate) {
+ models[modelName].associate(models)
+ }
+})
+
+module.exports = models
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/index.html b/coverage/lcov-report/hw5/index.html
new file mode 100644
index 0000000..1d6bbda
--- /dev/null
+++ b/coverage/lcov-report/hw5/index.html
@@ -0,0 +1,97 @@
+
+
+
+ Code coverage report for hw5
+
+
+
+
+
+
+
+
+
+
+
+
+ 84.09%
+ Statements
+ 37/44
+
+
+ 25%
+ Branches
+ 1/4
+
+
+ 40%
+ Functions
+ 2/5
+
+
+ 86.05%
+ Lines
+ 37/43
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ index.js
+
+ 84.09%
+ 37/44
+ 25%
+ 1/4
+ 40%
+ 2/5
+ 86.05%
+ 37/43
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/index.js.html b/coverage/lcov-report/hw5/index.js.html
new file mode 100644
index 0000000..a061f9e
--- /dev/null
+++ b/coverage/lcov-report/hw5/index.js.html
@@ -0,0 +1,306 @@
+
+
+
+ Code coverage report for hw5/index.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 84.09%
+ Statements
+ 37/44
+
+
+ 25%
+ Branches
+ 1/4
+
+
+ 40%
+ Functions
+ 2/5
+
+
+ 86.05%
+ Lines
+ 37/43
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80 1x
+1x
+1x
+1x
+1x
+
+
+1x
+
+
+1x
+1x
+
+1x
+1x
+1x
+
+
+1x
+
+1x
+1x
+
+
+1x
+1x
+
+
+
+
+
+
+
+
+1x
+1x
+
+1x
+
+1x
+1x
+1x
+1x
+1x
+
+
+1x
+
+
+1x
+1x
+
+
+1x
+
+
+
+
+1x
+
+
+
+
+1x
+
+1x
+1x
+
+
+1x
+
+1x
+1x
+1x
+
+
+
+
+1x
+ require('dotenv').config()
+const http = require('http')
+const express = require('express')
+const session = require('express-session')
+const passport = require('passport')
+
+// logger
+const { errorLogger } = require('./services/logger')
+
+// Databases
+const db = require('./db/dbConnection')
+require('./mongodb/mongoConnection')
+
+const connectRedis = require('connect-redis')
+const RSessionStore = connectRedis(session)
+const client = require('./services/redisConnectService')
+
+// app
+const app = express()
+
+app.use(express.urlencoded({ extended: true, limit: '1mb' }))
+app.use(express.json())
+
+// authentication
+const rStore = new RSessionStore({ client, prefix: 'denis:sess:' })
+app.use(
+ session({
+ store: rStore,
+ secret: process.env.SESSION_SECRET,
+ saveUninitialized: false,
+ rolling: false,
+ resave: false
+ })
+)
+app.use(passport.initialize())
+app.use(passport.session())
+
+app.set('trust proxy', 1)
+// apply Limiters
+const { limiter, loginLimiter, wsLimiter } = require('./services/rateLimitService')(client)
+app.use('/api/v1/blog', limiter)
+app.use('/api/v1/users', limiter)
+app.use('/api/v1/profile', limiter)
+app.use('/api/v1/login', loginLimiter)
+
+// docs
+require('./docs/swagger-config')(app)
+
+// routes
+const routes = require('./routes')
+app.use(routes)
+
+// error handlers
+app.use((r eq, res, next) => {
+ const error = new Error('Not found')
+ error.status = 404
+ next(error)
+})
+app.use((e rror, req, res, next) => {
+ res.status(error.status || 500)
+ res.json({ data: error })
+})
+
+const server = http.createServer(app)
+// WS
+const io = require('./services/socketService')(server, rStore, wsLimiter)
+app.set('socketio', io)
+
+// Connect to DB and run the server
+db.authenticate()
+ .then(() => {
+ server.listen(process.env.PORT, err => {
+ I if (err) errorLogger.error(`Some problem with server running`, { metadata: err })
+ console.log('server listening port 8803')
+ })
+ })
+ .catch(er r => errorLogger.error(`Some problem with MySQL connection`, { metadata: err }))
+
+module.exports = app
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/mongodb/index.html b/coverage/lcov-report/hw5/mongodb/index.html
new file mode 100644
index 0000000..b9ab5d5
--- /dev/null
+++ b/coverage/lcov-report/hw5/mongodb/index.html
@@ -0,0 +1,110 @@
+
+
+
+ Code coverage report for hw5/mongodb
+
+
+
+
+
+
+
+
+
+
+
+
+ 36.84%
+ Statements
+ 14/38
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 28.57%
+ Functions
+ 2/7
+
+
+ 36.84%
+ Lines
+ 14/38
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ mongoConnection.js
+
+ 83.33%
+ 5/6
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 83.33%
+ 5/6
+
+
+
+ queries.js
+
+ 28.13%
+ 9/32
+ 100%
+ 0/0
+ 16.67%
+ 1/6
+ 28.13%
+ 9/32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/mongodb/models/ArticlesViews.js.html b/coverage/lcov-report/hw5/mongodb/models/ArticlesViews.js.html
new file mode 100644
index 0000000..3ef98d7
--- /dev/null
+++ b/coverage/lcov-report/hw5/mongodb/models/ArticlesViews.js.html
@@ -0,0 +1,192 @@
+
+
+
+ Code coverage report for hw5/mongodb/models/ArticlesViews.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 52.38%
+ Statements
+ 11/21
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 0%
+ Functions
+ 0/7
+
+
+ 55%
+ Lines
+ 11/20
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42 1x
+1x
+
+1x
+
+1x
+
+
+
+
+
+
+
+1x
+
+
+
+
+1x
+
+
+
+
+
+1x
+
+
+
+
+1x
+
+
+1x
+
+
+
+1x
+
+
+
+1x
+ const mongoose = require('mongoose')
+const { Schema } = mongoose
+
+const { mongooseLogger } = require('../../services/logger')
+
+const articlesViews = new Schema({
+ articleId: Number,
+ authorId: Number,
+ views: Number,
+ updatedAt: Date,
+ createdAt: Date
+})
+
+articlesViews.pre('updateOne', fu nction(next) {
+ this.set({ updatedAt: new Date() })
+ next()
+})
+
+articlesViews.pre('save', fu nction(next) {
+ this.set({ createdAt: new Date() })
+ next()
+})
+
+// logging changes in mongoDB
+articlesViews.post('find', fu nction(docs) {
+ const ids = docs.map(do c => doc.articleId)
+ mongooseLogger.info(`The articles were requested with ids: ${ids}`)
+})
+
+articlesViews.post('findOneAndUpdate', fu nction(doc) {
+ mongooseLogger.info(`An article was updated with id: ${doc.articleId}`)
+})
+articlesViews.post('findOneAndDelete', fu nction(doc) {
+ mongooseLogger.info(`An article was deleted with id: ${doc.articleId}`)
+})
+
+articlesViews.post('save', fu nction(doc) {
+ mongooseLogger.info(`An article was created with id: ${doc.articleId}`)
+})
+
+module.exports = mongoose.model('articles_view', articlesViews)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/mongodb/models/index.html b/coverage/lcov-report/hw5/mongodb/models/index.html
new file mode 100644
index 0000000..bfcdfe9
--- /dev/null
+++ b/coverage/lcov-report/hw5/mongodb/models/index.html
@@ -0,0 +1,97 @@
+
+
+
+ Code coverage report for hw5/mongodb/models
+
+
+
+
+
+
+
+
+
+
+ All files hw5/mongodb/models
+
+
+
+ 52.38%
+ Statements
+ 11/21
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 0%
+ Functions
+ 0/7
+
+
+ 55%
+ Lines
+ 11/20
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ ArticlesViews.js
+
+ 52.38%
+ 11/21
+ 100%
+ 0/0
+ 0%
+ 0/7
+ 55%
+ 11/20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/mongodb/mongoConnection.js.html b/coverage/lcov-report/hw5/mongodb/mongoConnection.js.html
new file mode 100644
index 0000000..6bf9c2d
--- /dev/null
+++ b/coverage/lcov-report/hw5/mongodb/mongoConnection.js.html
@@ -0,0 +1,120 @@
+
+
+
+ Code coverage report for hw5/mongodb/mongoConnection.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 83.33%
+ Statements
+ 5/6
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 83.33%
+ Lines
+ 5/6
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18 1x
+
+
+
+1x
+1x
+
+
+
+
+
+
+
+
+1x
+
+1x
+ const mongoose = require('mongoose')
+
+class MDatabase {
+ static async connect() {
+ try {
+ return mongoose.connect(process.env.CONNECTION_STR, {
+ useNewUrlParser: true,
+ useUnifiedTopology: true
+ })
+ } catch (e) {
+ throw e
+ }
+ }
+}
+MDatabase.connect()
+
+module.exports = MDatabase
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/mongodb/queries.js.html b/coverage/lcov-report/hw5/mongodb/queries.js.html
new file mode 100644
index 0000000..d6007cf
--- /dev/null
+++ b/coverage/lcov-report/hw5/mongodb/queries.js.html
@@ -0,0 +1,219 @@
+
+
+
+ Code coverage report for hw5/mongodb/queries.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 28.13%
+ Statements
+ 9/32
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 16.67%
+ Functions
+ 1/6
+
+
+ 28.13%
+ Lines
+ 9/32
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51 1x
+1x
+
+1x
+1x
+
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+1x
+ const ArticlesViews = require('./models/ArticlesViews')
+const { articlesLogger, errorLogger, mongooseLogger } = require('./../services/logger')
+
+ArticlesViews.createCollection()
+ .then(() => mongooseLogger.info(`The collection is ready to use.`))
+ .catch(e => errorLogger.error(`An error on CreateCollection method`, { metadata: e }))
+
+const insertView = as ync data => {
+ try {
+ await ArticlesViews(data).save()
+ mongooseLogger.info(`Added a new article`, { metadata: { articleId: data.articleId } })
+ } catch (error) {
+ errorLogger.error(`An error on MongoDB's transaction`, { metadata: error })
+ throw error
+ }
+}
+
+const removeView = as ync articleId => {
+ try {
+ await ArticlesViews.findOneAndDelete({ articleId: articleId })
+ mongooseLogger.info(`Removed an article`, { metadata: { articleId: articleId } })
+ } catch (error) {
+ errorLogger.error(`An error on MongoDB's transaction`, { metadata: error })
+ throw error
+ }
+}
+
+const getView = as ync articleId => {
+ try {
+ const viewsResult = await ArticlesViews.findOneAndUpdate({ articleId: articleId }, { $inc: { views: 1 } })
+ const views = viewsResult._doc.views + 1
+ mongooseLogger.info(`Updated an article`, { metadata: { articleId: articleId } })
+ articlesLogger.info(`Viewed an article`, { metadata: { articleId: articleId } })
+ return views
+ } catch (error) {
+ errorLogger.error(`An error on MongoDB's transaction`, { metadata: error })
+ throw error
+ }
+}
+
+const getViews = as ync () => {
+ try {
+ return await ArticlesViews.find()
+ } catch (error) {
+ errorLogger.error(`An error on MongoDB's transaction`, { metadata: error })
+ throw error
+ }
+}
+
+module.exports = { insertView, removeView, getView, getViews }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/auth.js.html b/coverage/lcov-report/hw5/routes/auth.js.html
new file mode 100644
index 0000000..f7ff2fb
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/auth.js.html
@@ -0,0 +1,396 @@
+
+
+
+ Code coverage report for hw5/routes/auth.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 66.07%
+ Statements
+ 37/56
+
+
+ 25%
+ Branches
+ 3/12
+
+
+ 45.45%
+ Functions
+ 5/11
+
+
+ 67.92%
+ Lines
+ 36/53
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+
+
+
+
+
+
+1x
+1x
+1x
+1x
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+
+
+1x
+1x
+
+
+
+1x
+
+
+
+
+
+1x
+1x
+1x
+1x
+1x
+1x
+
+
+
+1x
+
+
+
+
+
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+1x
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+ /*
+ POST /api/v1/registration
+ POST /api/v1/registration/verify
+ POST /api/v1/login
+ POST /api/v1/logout
+*/
+
+const express = require('express')
+const router = express.Router()
+const asyncHandler = require('express-async-handler')
+const passport = require('passport')
+const jwt = require('jsonwebtoken')
+
+const { Users } = require('../db/models/index.js')
+require('../services/passportService')(passport)
+const { logOut, getFormattedUrl } = require('../services/helpers')
+const { userCreationValidation, loginValidation } = require('../services/validationService')
+const { SendgridService } = require('../services/emailService')
+const emailTemplates = require('../db/constant')
+
+router.post(
+ '/registration',
+ userCreationValidation,
+ asyncHandler(async (req, res) => {
+ const userData = await Users.findOne({ where: { email: req.body.email } })
+ I if (userData) {
+ res.status(500)
+ res.send('{ error: "User with this email already exist"}').end()
+ } else {
+ const userItem = {
+ firstName: req.body.firstName,
+ lastName: req.body.lastName,
+ email: req.body.email,
+ password: req.body.password
+ }
+ const newUser = await Users.create(userItem)
+ const createdUser = newUser.get({ plain: true })
+ jwt.sign({ uid: createdUser.id }, 'secretkey', { expiresIn: '1h' }, async (err, token) => {
+ I if (err) return res.status(403).send({ error: err })
+ const verifyLink = `${getFormattedUrl(req)}/verify?token=${token}`
+ await SendgridService.sendEmail(createdUser.email, 'internship@zazmic.com', emailTemplates.accountVerificationTemplate, {
+ verifyLink: verifyLink,
+ name: createdUser.firstName
+ })
+ res.send({ data: newUser })
+ })
+ }
+ })
+)
+
+router.post('/registration/verify', async (req, res) => {
+ try {
+ const { uid } = await jwt.verify(req.body.token, 'secretkey')
+ const userData = await Users.findByPk(uid)
+ await userData.update({ isVerified: true })
+ let user = userData.get({ plain: true })
+ await req.logIn(user, err => {
+ I if (err) res.status(500).send({ error: err })
+ res.send({ data: user })
+ })
+ } catch (e) {
+ return res.status(403).json({ errors: [{ msg: 'Try to register again' }] })
+ }
+})
+
+router.post(
+ '/login',
+ loginValidation,
+ passport.authenticate('local', {
+ failureRedirect: '/login'
+ }),
+ (r eq, res) => res.send({ data: req.user })
+)
+
+router.post('/logout', (req, res) => logOut(req, res))
+
+// JWT test
+// FORMAT OF TOKEN
+// Authorization: Bearer <access_token>
+router.post('/jwt/protected-info', verifyToken, (r eq, res) => {
+ jwt.verify(req.token, 'secretkey', (e rr, authData) => {
+ err ? res.sendStatus(403) : res.json({ message: 'Info have been got...', authData })
+ })
+})
+
+router.post('/jwt/login', (r eq, res) => {
+ const user = { id: 1, userName: 'David', email: 'david@gmail.com' }
+ req.query = { ...user }
+ jwt.sign({ userName: req.query.userName }, 'secretkey', { expiresIn: '60s' }, (e rr, token) => {
+ err ? res.sendStatus(403) : res.json({ token })
+ })
+})
+
+function verifyToken( req, res, next) {
+ // Get auth header value
+ const bearerHeader = req.headers['authorization']
+ if (typeof bearerHeader !== 'undefined') {
+ // Split at the space and get token from array
+ const bearer = bearerHeader.split(' ')
+ const bearerToken = bearer[1]
+ req.token = bearerToken
+ next()
+ } else {
+ // Forbidden
+ res.sendStatus(403)
+ }
+}
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/blogs.js.html b/coverage/lcov-report/hw5/routes/blogs.js.html
new file mode 100644
index 0000000..783dfa1
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/blogs.js.html
@@ -0,0 +1,480 @@
+
+
+
+ Code coverage report for hw5/routes/blogs.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 27.03%
+ Statements
+ 20/74
+
+
+ 0%
+ Branches
+ 0/18
+
+
+ 0%
+ Functions
+ 0/8
+
+
+ 28.57%
+ Lines
+ 20/70
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+
+
+
+
+
+
+
+
+
+
+1x
+1x
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+ /*
+ GET /api/v1/blog - get all blogs
+ POST /api/v1/blog - add a new blog
+ GET /api/v1/blog/:id - get the blog by id
+ PUT /api/v1/blog/:id - update the blog by id
+ DELETE /api/v1/blog/:id - delete the blog by id
+ GET /blog/:articleId/comments - get all comments
+ POST /blog/:articleId/comments - add a new comment
+ DELETE /blog/:articleId/comments/:id - delete the comments
+*/
+
+const express = require('express')
+const router = express.Router()
+const asyncHandler = require('express-async-handler')
+
+const { Articles, Users, Comments } = require('../db/models/index.js')
+const { insertView, removeView: removeArticlesView, getView, getViews } = require('../mongodb/queries')
+const { combineArticles2Views } = require('../services/helpers')
+const authCheck = require('../services/middlewares/authCheck')
+const { articlesMulter } = require('../services/multer')
+const { gcArticlesIMGRemover } = require('../services/gcRemovalService')
+const { getArticles, getComments } = require('../services/queryHelperService')
+const { articleValidation, commentValidation } = require('../services/validationService')
+
+router.get(
+ '/',
+ asyncHandler(as ync (req, res) => {
+ const articles = await getArticles(req.query.after, null)
+ const views = await getViews()
+ combineArticles2Views(articles, views)
+ res.send({ data: articles })
+ })
+)
+
+router.post(
+ '/',
+ [authCheck, articlesMulter.single('picture'), articleValidation],
+ asyncHandler(as ync (req, res) => {
+ let newArticle = null
+ req.body.authorId = req.user.id
+ if (req.file) req.body.picture = req.file.path
+ newArticle = await Articles.create({ ...req.body })
+ await insertView({ articleId: newArticle.id, authorId: newArticle.authorId, views: 0 })
+ newArticle.view = 0
+ res.send({ data: newArticle })
+ })
+)
+router.put(
+ '/:id',
+ [authCheck, articlesMulter.single('picture'), articleValidation],
+ asyncHandler(as ync (req, res) => {
+ const data = await Articles.findByPk(req.params.id, { attributes: ['authorId', 'picture'] })
+ const articleData = data.get({ plain: true })
+ if (articleData.authorId === req.user.id) {
+ let updatedArticle = null
+ if (req.file) req.body.picture = req.file.path
+ if (articleData.picture) await gcArticlesIMGRemover.remove(articleData.picture)
+ updatedArticle = await Articles.update({ ...req.body }, { where: { id: req.params.id } })
+ return updatedArticle > 0 ? res.status(200).send({}) : res.sendStatus(500)
+ } else {
+ res.sendStatus(403)
+ }
+ })
+)
+
+router.get(
+ '/:id',
+ asyncHandler(as ync (req, res) => {
+ const article = await Articles.findByPk(req.params.id, {
+ order: [['createdAt', 'DESC']],
+ include: [{ model: Users, as: 'author' }]
+ })
+ const views = await getView(+req.params.id)
+ article.dataValues.views = views
+ res.send({ data: article })
+ })
+)
+
+router.delete(
+ '/:id',
+ asyncHandler(as ync (req, res) => {
+ const data = await Articles.findByPk(req.params.id, { attributes: ['authorId', 'picture'] })
+ const articleData = data.get({ plain: true })
+ if (articleData.authorId === req.user.id) {
+ const destroyedArticle = await Articles.destroy({ where: { id: req.params.id } })
+ await removeArticlesView(req.params.id)
+ if (articleData.picture) await gcArticlesIMGRemover.remove(articleData.picture)
+ destroyedArticle > 0 ? res.send({ data: articleData }) : res.sendStatus(500)
+ } else {
+ res.sendStatus(403)
+ }
+ })
+)
+
+// Comments
+router.get(
+ '/:id/comments',
+ asyncHandler(as ync (req, res) => {
+ const comments = await getComments(req.params.id, +req.query.after)
+ res.send({ data: comments })
+ })
+)
+
+router.post(
+ '/:id/comments',
+ authCheck,
+ commentValidation,
+ asyncHandler(as ync (req, res) => {
+ req.body.authorId = req.user.id
+ req.body.articleId = +req.params.id
+ const newComment = await Comments.create(req.body)
+ const comment = newComment.get({ plain: true })
+ comment.author = req.user
+ // sockets
+ const io = req.app.get('socketio')
+ io.to(`room-${req.params.id}`).emit('comment', { action: 'create', data: { comment } })
+ res.send({ data: comment })
+ })
+)
+
+router.delete(
+ '/:articleId/comments/:id',
+ authCheck,
+ asyncHandler(as ync (req, res) => {
+ req.body.id = req.params.id
+ const comment = await Comments.findByPk(req.params.id)
+ if (comment) {
+ await comment.destroy()
+ const io = req.app.get('socketio')
+ io.to(`room-${req.params.articleId}`).emit('comment', { action: 'destroy', data: { comment } })
+ return res.sendStatus(200)
+ }
+ res.sendStatus(404)
+ })
+)
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/fees.js.html b/coverage/lcov-report/hw5/routes/fees.js.html
new file mode 100644
index 0000000..a65d701
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/fees.js.html
@@ -0,0 +1,246 @@
+
+
+
+ Code coverage report for hw5/routes/fees.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 44.44%
+ Statements
+ 12/27
+
+
+ 0%
+ Branches
+ 0/10
+
+
+ 0%
+ Functions
+ 0/2
+
+
+ 48%
+ Lines
+ 12/25
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+
+
+
+
+1x
+1x
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+ /*
+ GET /api/v1/fees - user fees
+ PUT /api/v1/fees - make a payment to reach a pro-account
+*/
+
+const express = require('express')
+const router = express.Router()
+const asyncHandler = require('express-async-handler')
+
+const authCheck = require('../services/middlewares/authCheck')
+const { createCharge, getChargesAmount } = require('../services/stripeService')
+const { sgMail } = require('../services/emailService')
+const emailTemplates = require('../db/constant')
+const totalBill = 100 // the sum needs to become a pro
+const cents = 100
+
+router.get(
+ '/',
+ authCheck,
+ asyncHandler(as ync (req, res) => {
+ const user = req.user.get({ plain: true })
+ if (user.is_pro) return res.send({ data: { amount: 0 } })
+ if (!user.stripe_customer_id) return res.send({ data: { amount: 100 } })
+ const total = await getChargesAmount(user.stripe_customer_id)
+ res.send({ data: { amount: totalBill - total } })
+ })
+)
+
+router.put(
+ '/',
+ authCheck,
+ asyncHandler(as ync (req, res) => {
+ const user = req.user.get({ plain: true })
+ const chargeReport = await createCharge(user.stripe_customer_id, user.stripe_card_id, req.body.amount * cents, user.email)
+ const total = await getChargesAmount(user.stripe_customer_id)
+ sgMail.send({
+ to: user.email,
+ from: 'internship@zazmic.com',
+ template_id: emailTemplates.paymentTemplate,
+ dynamic_template_data: {
+ chargeReport: chargeReport,
+ sum: req.body.amount,
+ rest: total < totalBill ? totalBill - total : 0
+ }
+ })
+ // if user reach a pro
+ if (!user.is_pro && total >= totalBill) {
+ await req.user.update({ is_pro: true })
+ sgMail.send({
+ to: user.email,
+ from: 'internship@zazmic.com',
+ template_id: emailTemplates.proAccountTemplate
+ })
+ }
+ res.send({ data: { amount: totalBill - total, user: user } })
+ })
+)
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/index.html b/coverage/lcov-report/hw5/routes/index.html
new file mode 100644
index 0000000..4ca77d6
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/index.html
@@ -0,0 +1,175 @@
+
+
+
+ Code coverage report for hw5/routes
+
+
+
+
+
+
+
+
+
+
+
+
+ 49%
+ Statements
+ 122/249
+
+
+ 6%
+ Branches
+ 3/50
+
+
+ 14.71%
+ Functions
+ 5/34
+
+
+ 51.71%
+ Lines
+ 121/234
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ auth.js
+
+ 66.07%
+ 37/56
+ 25%
+ 3/12
+ 45.45%
+ 5/11
+ 67.92%
+ 36/53
+
+
+
+ blogs.js
+
+ 27.03%
+ 20/74
+ 0%
+ 0/18
+ 0%
+ 0/8
+ 28.57%
+ 20/70
+
+
+
+ fees.js
+
+ 44.44%
+ 12/27
+ 0%
+ 0/10
+ 0%
+ 0/2
+ 48%
+ 12/25
+
+
+
+ index.js
+
+ 80.95%
+ 17/21
+ 100%
+ 0/0
+ 0%
+ 0/2
+ 85%
+ 17/20
+
+
+
+ oauth.js
+
+ 80%
+ 8/10
+ 100%
+ 0/0
+ 0%
+ 0/2
+ 80%
+ 8/10
+
+
+
+ profile.js
+
+ 45.45%
+ 15/33
+ 0%
+ 0/8
+ 0%
+ 0/4
+ 51.72%
+ 15/29
+
+
+
+ users.js
+
+ 46.43%
+ 13/28
+ 0%
+ 0/2
+ 0%
+ 0/5
+ 48.15%
+ 13/27
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/index.js.html b/coverage/lcov-report/hw5/routes/index.js.html
new file mode 100644
index 0000000..ab1dc84
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/index.js.html
@@ -0,0 +1,147 @@
+
+
+
+ Code coverage report for hw5/routes/index.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 80.95%
+ Statements
+ 17/21
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 0%
+ Functions
+ 0/2
+
+
+ 85%
+ Lines
+ 17/20
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27 1x
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+
+
+
+
+1x
+ const https = require('https')
+const router = require('express').Router()
+
+const auth = require('./auth')
+const oauth = require('./oauth')
+const blog = require('./blogs')
+const user = require('./users')
+const profile = require('./profile')
+const fees = require('./fees')
+
+const { mongooseLogger } = require('../services/logger')
+
+router.use('/api/v1/oauth', oauth)
+router.use('/api/v1', auth)
+router.use('/api/v1/profile', profile)
+router.use('/api/v1/users', user)
+router.use('/api/v1/blog', blog)
+router.use('/api/v1/fees', fees)
+
+router.get('*', (r eq, res) => {
+ https.get(process.env.FRONTEND_URL, re sponse => response.pipe(res))
+ const date = new Date()
+ mongooseLogger.info(`App: incoming ${req.method} request at ${date}`)
+})
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/oauth.js.html b/coverage/lcov-report/hw5/routes/oauth.js.html
new file mode 100644
index 0000000..4513b0d
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/oauth.js.html
@@ -0,0 +1,138 @@
+
+
+
+ Code coverage report for hw5/routes/oauth.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 80%
+ Statements
+ 8/10
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 0%
+ Functions
+ 0/2
+
+
+ 80%
+ Lines
+ 8/10
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+
+
+
+
+
+1x
+1x
+1x
+
+1x
+
+1x
+
+1x
+
+
+
+1x
+
+
+
+1x
+ /*
+ GET /api/v1/oauth/google
+ POST /api/v1/oauth/google/callback
+ GET /api/v1/oauth/facebook
+ POST /api/v1/oauth/facebook/callback
+*/
+const express = require('express')
+const router = express.Router()
+const passport = require('passport')
+
+router.get('/google', passport.authenticate('google', { scope: ['profile', 'email'] }))
+
+router.get('/facebook', passport.authenticate('facebook', { scope: ['email'] }))
+
+router.post('/google/callback', passport.authenticate('google'), (r eq, res) => {
+ res.send({ data: req.user })
+})
+
+router.post('/facebook/callback', passport.authenticate('facebook'), (r eq, res) => {
+ res.send({ data: req.user })
+})
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/profile.js.html b/coverage/lcov-report/hw5/routes/profile.js.html
new file mode 100644
index 0000000..4987dab
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/profile.js.html
@@ -0,0 +1,258 @@
+
+
+
+ Code coverage report for hw5/routes/profile.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 45.45%
+ Statements
+ 15/33
+
+
+ 0%
+ Branches
+ 0/8
+
+
+ 0%
+ Functions
+ 0/4
+
+
+ 51.72%
+ Lines
+ 15/29
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+
+
+
+
+
+1x
+1x
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+ /*
+ PUT /api/v1/profile - update user
+ DELETE /api/v1/profile - delete user
+ PUT /api/v1/picture - update or add users picture
+*/
+
+const express = require('express')
+const router = express.Router()
+const asyncHandler = require('express-async-handler')
+
+const { Users, Articles } = require('../db/models/index.js')
+const authCheck = require('../services/middlewares/authCheck')
+const { logOut } = require('../services/helpers')
+const { avatarMulter } = require('../services/multer')
+const { gcUserIMGRemover } = require('../services/gcRemovalService')
+const { editUserValidation } = require('../services/validationService')
+const { createCustomer } = require('../services/stripeService')
+
+router.put(
+ '/',
+ authCheck,
+ editUserValidation,
+ asyncHandler(as ync (req, res) => {
+ await req.user.update({ firstName: req.body.firstName, lastName: req.body.lastName })
+ res.send({ data: req.user })
+ })
+)
+
+router.delete(
+ '/',
+ authCheck,
+ asyncHandler(as ync (req, res) => {
+ const imgs = await Articles.findAll({ where: { authorId: req.user.id }, raw: true, attributes: ['picture'] })
+ if (req.user.picture) imgs.push({ picture: req.user.picture })
+ if (imgs.length) await gcUserIMGRemover.remove(imgs)
+ const destroyedUser = await Users.destroy({ where: { id: req.user.id } })
+ if (destroyedUser > 0) return logOut(req, res)
+ res.sendStatus(500)
+ })
+)
+
+router.put(
+ '/picture',
+ authCheck,
+ avatarMulter.single('picture'),
+ asyncHandler(as ync (req, res) => {
+ if (!req.file) return res.status(400).send('No file uploaded.')
+ await req.user.update({ picture: req.file.path })
+ res.send({ data: { picture: req.file.path } })
+ })
+)
+
+router.put(
+ '/card',
+ authCheck,
+ asyncHandler(as ync (req, res) => {
+ const user = req.user.get({ plain: true })
+ const updatedData = await createCustomer(req.body.token, user)
+ res.send({ data: { ...user, ...updatedData } })
+ })
+)
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/routes/users.js.html b/coverage/lcov-report/hw5/routes/users.js.html
new file mode 100644
index 0000000..35f7c88
--- /dev/null
+++ b/coverage/lcov-report/hw5/routes/users.js.html
@@ -0,0 +1,279 @@
+
+
+
+ Code coverage report for hw5/routes/users.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 46.43%
+ Statements
+ 13/28
+
+
+ 0%
+ Branches
+ 0/2
+
+
+ 0%
+ Functions
+ 0/5
+
+
+ 48.15%
+ Lines
+ 13/27
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+
+
+
+
+
+
+
+1x
+1x
+1x
+
+1x
+1x
+
+1x
+1x
+1x
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+ /*
+ GET /api/v1/users - get all users
+ POST /api/v1/users - add a new user
+ GET /api/v1/users/:id - get the user by id
+ PUT /api/v1/users/:id - update the user by id
+ DELETE /api/v1/users/:id - delete the user by id
+*/
+
+const express = require('express')
+const router = express.Router()
+const asyncHandler = require('express-async-handler')
+
+const { Users } = require('../db/models/index.js')
+const db = require('../db/dbConnection')
+
+const { getViews } = require('../mongodb/queries')
+const { combineArticles2Views } = require('../services/helpers')
+const authCheck = require('../services/middlewares/authCheck')
+const { getArticles } = require('../services/queryHelperService')
+
+router.get(
+ '/',
+ authCheck,
+ asyncHandler(as ync (req, res) => {
+ const users = await db.query(
+ `
+ SELECT
+ users.id,
+ users.email,
+ users.first_name AS firstName,
+ users.last_name AS lastName,
+ users.last_name AS lastName,
+ users.is_pro,
+ COUNT(articles.id) AS articlesCount
+ FROM users
+ LEFT JOIN articles ON articles.author_id = users.id
+ GROUP BY users.id`,
+ { type: db.QueryTypes.SELECT }
+ )
+ const views = await getViews()
+ users.forEach(it em => {
+ let viewsCount = 0
+ views.forEach(vi ew => {
+ if (item.id === view.authorId) viewsCount += view.views
+ })
+ item.viewsCount = viewsCount
+ })
+ res.send({ data: users })
+ })
+)
+
+router.get(
+ '/:id',
+ asyncHandler(as ync (req, res) => {
+ const user = await Users.findByPk(req.params.id)
+ res.send({ data: user })
+ })
+)
+
+router.get(
+ '/:id/blog',
+ asyncHandler(as ync (req, res) => {
+ const articles = await getArticles(req.query.after, req.params.id)
+ const views = await getViews(req.params.id)
+ combineArticles2Views(articles, views)
+ res.send({ data: articles })
+ })
+)
+
+module.exports = router
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/AuthService.js.html b/coverage/lcov-report/hw5/services/AuthService.js.html
new file mode 100644
index 0000000..9beabb6
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/AuthService.js.html
@@ -0,0 +1,171 @@
+
+
+
+ Code coverage report for hw5/services/AuthService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 15.79%
+ Statements
+ 3/19
+
+
+ 0%
+ Branches
+ 0/4
+
+
+ 0%
+ Functions
+ 0/3
+
+
+ 16.67%
+ Lines
+ 3/18
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35 1x
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+ const { errorLogger } = require('./logger')
+const { Users, Providers } = require('../db/models/index.js')
+
+class AuthService {
+ st atic async findOrCreateOauthProvider({ provider, email, firstName, lastName, providerUserId }) {
+ try {
+ const userData = await Users.findOne({ where: { email } })
+ if (userData) {
+ await userData.update({ isVerified: true })
+ const user = userData.get({ plain: true })
+ const hasAccount = await Providers.findOne({ where: { providerUserId } })
+ if (!hasAccount) await this.createOauthAccount(user.id, provider, providerUserId)
+ return user
+ } else {
+ const newUser = await this.createUser(firstName, lastName, email)
+ await newUser.update({ isVerified: true })
+ await this.createOauthAccount(newUser.dataValues.id, provider, providerUserId)
+ return newUser.get({ plain: true })
+ }
+ } catch (err) {
+ errorLogger.error(`An error on MySQL request`, { metadata: err })
+ }
+ }
+
+ st atic async createOauthAccount(userId, provider, providerUserId) {
+ await Providers.create({ userId, provider, providerUserId })
+ }
+
+ st atic async createUser(firstName, lastName, email) {
+ return await Users.create({ firstName, lastName, email, password: '123qwe' })
+ }
+}
+
+module.exports = { AuthService }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/emailService.js.html b/coverage/lcov-report/hw5/services/emailService.js.html
new file mode 100644
index 0000000..606a53c
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/emailService.js.html
@@ -0,0 +1,114 @@
+
+
+
+ Code coverage report for hw5/services/emailService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 75%
+ Statements
+ 3/4
+
+
+ 0%
+ Branches
+ 0/2
+
+
+ 0%
+ Functions
+ 0/1
+
+
+ 75%
+ Lines
+ 3/4
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16 1x
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+ const sgMail = require('@sendgrid/mail')
+sgMail.setApiKey(process.env.SENDGRID_API_KEY)
+
+class SendgridService {
+ st atic async sendEmail(to, from, templateId = '', dynamicData = {}) {
+ await sgMail.send({
+ to,
+ from,
+ template_id: templateId,
+ dynamic_template_data: dynamicData
+ })
+ }
+}
+
+module.exports = { sgMail, SendgridService }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/gcRemovalService.js.html b/coverage/lcov-report/hw5/services/gcRemovalService.js.html
new file mode 100644
index 0000000..621ff9c
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/gcRemovalService.js.html
@@ -0,0 +1,153 @@
+
+
+
+ Code coverage report for hw5/services/gcRemovalService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 46.67%
+ Statements
+ 7/15
+
+
+ 0%
+ Branches
+ 0/2
+
+
+ 16.67%
+ Functions
+ 1/6
+
+
+ 53.85%
+ Lines
+ 7/13
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29 1x
+1x
+
+
+
+2x
+2x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+1x
+
+1x
+ const { avatarStorage, articlesStorage } = require('./gcStorageService')
+const { errorLogger } = require('./logger')
+
+class GCRemoverTool {
+ constructor(storage, bucket) {
+ this.gcStorage = storage
+ this.gcsBucket = bucket
+ }
+ re move(data) {
+ Array.isArray(data) ? this.removeMany(data) : this.removeOne(data)
+ }
+
+ as ync removeMany(urls) {
+ await Promise.all(urls.map(ur l => this.removeOne(url.picture)) )
+ }
+
+ as ync removeOne(url) {
+ const filePath = new URL(url).pathname
+ const fileName = filePath.replace(new RegExp(`${this.gcsBucket.name}/`, 'g'), '')
+ const gcFile = this.gcsBucket.file(fileName.slice(1))
+ await gcFile.delete().catch(e => errorLogger.error(`Some problem with pictures removing`, { metadata: e }))
+ }
+}
+
+const gcUserIMGRemover = new GCRemoverTool(avatarStorage.gcStorage, avatarStorage.gcsBucket)
+const gcArticlesIMGRemover = new GCRemoverTool(articlesStorage.gcStorage, articlesStorage.gcsBucket)
+
+module.exports = { gcUserIMGRemover, gcArticlesIMGRemover }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/gcStorageService.js.html b/coverage/lcov-report/hw5/services/gcStorageService.js.html
new file mode 100644
index 0000000..e38db46
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/gcStorageService.js.html
@@ -0,0 +1,282 @@
+
+
+
+ Code coverage report for hw5/services/gcStorageService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 41.18%
+ Statements
+ 14/34
+
+
+ 42.86%
+ Branches
+ 6/14
+
+
+ 11.11%
+ Functions
+ 1/9
+
+
+ 46.67%
+ Lines
+ 14/30
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72 1x
+1x
+1x
+1x
+
+
+
+2x
+2x
+2x
+2x
+2x
+2x
+2x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+1x
+ const { Storage } = require('@google-cloud/storage')
+const path = require('path')
+const sharp = require('sharp')
+const { errorLogger } = require('./logger')
+
+class GCStorage {
+ constructor(opts) {
+ I if (!opts.bucket) throw new Error('You have to specify bucket for GCStorage.')
+ I if (!opts.keyFilename) throw new Error('You have to specify credentials key file for GCStorage.')
+ this.getDestination = opts.destination || this.getDestination
+ this.getFilename = opts.filename || this.getFilename
+ this.gcStorage = new Storage({ keyFilename: opts.keyFilename })
+ this.gcsBucket = this.gcStorage.bucket(opts.bucket)
+ this.options = opts
+ }
+
+ ge tDestination(req, file, cb) {
+ cb(null, `${this.options.prefix}/${this.options.size.width}x${this.options.size.height}/`)
+ }
+
+ ge tFilename(req, file, cb) {
+ const prefix = Date.now()
+ cb(null, `${prefix}-${file.originalname}`)
+ }
+
+ _h andleFile(req, file, cb) {
+ this.getDestination(req, file, (e rr, destination) => {
+ if (err) return cb(err)
+ this.getFilename(req, file, as ync (err, filename) => {
+ if (err) return cb(err)
+ const finalPath = path.join(destination, filename)
+ let gcFile = this.gcsBucket.file(finalPath)
+ const streamOpts = { predefinedAcl: this.options.acl || 'publicread' }
+ const sharpResizer = sharp().resize(this.options.size.width, this.options.size.height)
+ file.stream
+ .pipe(sharpResizer)
+ .pipe(gcFile.createWriteStream(streamOpts))
+ .on('error', er r => {
+ errorLogger.error(`Error while file uploading`, { metadata: err })
+ cb(err)
+ })
+ .on('finish', () => {
+ cb(null, {
+ path: `https://storage.googleapis.com/${this.options.bucket}/${finalPath}`,
+ filename: filename
+ })
+ })
+ })
+ })
+ }
+
+ _r emoveFile(req, file, cb) {
+ this.gcsBucket.file(file.filename).delete()
+ }
+}
+
+const avatarStorage = new GCStorage({
+ prefix: `denis/avatars`,
+ bucket: process.env.BUCKET_NAME,
+ keyFilename: path.join(__dirname, '../service-key.json'),
+ size: { width: 180, height: 180 }
+})
+
+const articlesStorage = new GCStorage({
+ prefix: `denis/articles`,
+ bucket: process.env.BUCKET_NAME,
+ keyFilename: path.join(__dirname, '../service-key.json'),
+ size: { width: 1200, height: 630 }
+})
+
+module.exports = { avatarStorage, articlesStorage }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/hashPsw.js.html b/coverage/lcov-report/hw5/services/hashPsw.js.html
new file mode 100644
index 0000000..561e09d
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/hashPsw.js.html
@@ -0,0 +1,120 @@
+
+
+
+ Code coverage report for hw5/services/hashPsw.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 81.82%
+ Statements
+ 9/11
+
+
+ 100%
+ Branches
+ 2/2
+
+
+ 50%
+ Functions
+ 1/2
+
+
+ 90%
+ Lines
+ 9/10
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18 1x
+1x
+1x
+
+1x
+2x
+2x
+1x
+
+
+
+
+
+
+1x
+
+1x
+ const bcrypt = require('bcrypt')
+const { errorLogger } = require('./logger')
+const saltRound = 10
+
+const hashPassword = async user => {
+ try {
+ if (user.changed('password')) {
+ user.password = await bcrypt.hash(user.password, saltRound)
+ }
+ } catch (err) {
+ errorLogger.error(`Some problem with passwords hashing`, { metadata: err })
+ }
+}
+
+const checkPsw = (p sw, hash) => bcrypt.compare(psw, hash)
+
+module.exports = { hashPassword, checkPsw }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/helpers.js.html b/coverage/lcov-report/hw5/services/helpers.js.html
new file mode 100644
index 0000000..d97f507
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/helpers.js.html
@@ -0,0 +1,126 @@
+
+
+
+ Code coverage report for hw5/services/helpers.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 69.23%
+ Statements
+ 9/13
+
+
+ 0%
+ Branches
+ 0/2
+
+
+ 40%
+ Functions
+ 2/5
+
+
+ 72.73%
+ Lines
+ 8/11
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20 1x
+
+1x
+
+
+
+
+
+
+
+1x
+1x
+1x
+1x
+
+
+1x
+
+1x
+ const url = require('url')
+
+const combineArticles2Views = (a rticles, views) => {
+ articles.forEach(it em => {
+ views.forEach(vi ew => {
+ if (item.dataValues.id === view.articleId) item.dataValues.views = view.views
+ })
+ })
+}
+
+const logOut = (req, res) => {
+ req.logout()
+ req.session.destroy()
+ res.send({})
+}
+
+const getFormattedUrl = req => url.format({ protocol: req.protocol, host: req.get('host') })
+
+module.exports = { combineArticles2Views, logOut, getFormattedUrl }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/index.html b/coverage/lcov-report/hw5/services/index.html
new file mode 100644
index 0000000..9f6f4ef
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/index.html
@@ -0,0 +1,279 @@
+
+
+
+ Code coverage report for hw5/services
+
+
+
+
+
+
+
+
+
+
+
+
+ 52.21%
+ Statements
+ 130/249
+
+
+ 21.15%
+ Branches
+ 11/52
+
+
+ 20%
+ Functions
+ 11/55
+
+
+ 56.64%
+ Lines
+ 128/226
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ AuthService.js
+
+ 15.79%
+ 3/19
+ 0%
+ 0/4
+ 0%
+ 0/3
+ 16.67%
+ 3/18
+
+
+
+ emailService.js
+
+ 75%
+ 3/4
+ 0%
+ 0/2
+ 0%
+ 0/1
+ 75%
+ 3/4
+
+
+
+ gcRemovalService.js
+
+ 46.67%
+ 7/15
+ 0%
+ 0/2
+ 16.67%
+ 1/6
+ 53.85%
+ 7/13
+
+
+
+ gcStorageService.js
+
+ 41.18%
+ 14/34
+ 42.86%
+ 6/14
+ 11.11%
+ 1/9
+ 46.67%
+ 14/30
+
+
+
+ hashPsw.js
+
+ 81.82%
+ 9/11
+ 100%
+ 2/2
+ 50%
+ 1/2
+ 90%
+ 9/10
+
+
+
+ helpers.js
+
+ 69.23%
+ 9/13
+ 0%
+ 0/2
+ 40%
+ 2/5
+ 72.73%
+ 8/11
+
+
+
+ logger.js
+
+ 78.57%
+ 11/14
+ 100%
+ 0/0
+ 0%
+ 0/2
+ 84.62%
+ 11/13
+
+
+
+ multer.js
+
+ 100%
+ 5/5
+ 100%
+ 0/0
+ 100%
+ 0/0
+ 100%
+ 5/5
+
+
+
+ passportService.js
+
+ 44.74%
+ 17/38
+ 0%
+ 0/4
+ 50%
+ 3/6
+ 45.71%
+ 16/35
+
+
+
+ queryHelperService.js
+
+ 35.71%
+ 5/14
+ 0%
+ 0/6
+ 0%
+ 0/2
+ 38.46%
+ 5/13
+
+
+
+ rateLimitService.js
+
+ 100%
+ 8/8
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 8/8
+
+
+
+ redisConnectService.js
+
+ 83.33%
+ 5/6
+ 100%
+ 0/0
+ 0%
+ 0/1
+ 83.33%
+ 5/6
+
+
+
+ socketService.js
+
+ 38.46%
+ 10/26
+ 0%
+ 0/4
+ 10%
+ 1/10
+ 43.48%
+ 10/23
+
+
+
+ stripeService.js
+
+ 41.18%
+ 7/17
+ 0%
+ 0/4
+ 0%
+ 0/4
+ 41.18%
+ 7/17
+
+
+
+ validationService.js
+
+ 68%
+ 17/25
+ 37.5%
+ 3/8
+ 33.33%
+ 1/3
+ 85%
+ 17/20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/logger.js.html b/coverage/lcov-report/hw5/services/logger.js.html
new file mode 100644
index 0000000..b739d86
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/logger.js.html
@@ -0,0 +1,303 @@
+
+
+
+ Code coverage report for hw5/services/logger.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 78.57%
+ Statements
+ 11/14
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 0%
+ Functions
+ 0/2
+
+
+ 84.62%
+ Lines
+ 11/13
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79 1x
+1x
+1x
+
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+1x
+1x
+
+1x
+
+
+
+
+ const winston = require('winston')
+require('winston-mongodb')
+require('../mongodb/mongoConnection')
+
+const { format, transports, createLogger } = winston
+
+const mongooseLogger = createLogger({
+ format: format.combine(format.splat(), format.simple()),
+ transports: [
+ new transports.MongoDB({
+ db: process.env.CONNECTION_STR,
+ collection: 'mongoose_logs',
+ decolorize: true,
+ options: {
+ useUnifiedTopology: true,
+ useNewUrlParser: true
+ }
+ }),
+ new transports.Console({
+ json: false,
+ colorize: true
+ })
+ ]
+})
+
+const errorLogger = createLogger({
+ transports: [
+ new transports.Console({
+ level: 'info',
+ format: format.combine(format.splat(), format.simple()),
+ colorize: true,
+ handleExceptions: true
+ }),
+ new transports.MongoDB({
+ level: 'error',
+ db: process.env.CONNECTION_STR,
+ collection: 'error_logs',
+ options: {
+ useUnifiedTopology: true,
+ useNewUrlParser: true
+ }
+ })
+ ]
+})
+
+const articlesLogger = createLogger({
+ transports: [
+ new transports.Console({
+ level: 'info',
+ format: format.combine(format.splat(), format.simple()),
+ colorize: true,
+ handleExceptions: true
+ }),
+ new transports.MongoDB({
+ level: 'info',
+ db: process.env.CONNECTION_STR,
+ collection: 'articles_logs',
+ options: {
+ useUnifiedTopology: true,
+ useNewUrlParser: true
+ }
+ })
+ ]
+})
+
+const exceptionLogger = er ror => {
+ errorLogger.error('Uncaught exception', { metadata: error })
+ errorLogger.end(() => process.exit(1))
+}
+
+process.on('uncaughtException', exceptionLogger)
+process.on('unhandledRejection', exceptionLogger)
+
+module.exports = {
+ mongooseLogger,
+ errorLogger,
+ articlesLogger
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/middlewares/authCheck.js.html b/coverage/lcov-report/hw5/services/middlewares/authCheck.js.html
new file mode 100644
index 0000000..3b266b5
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/middlewares/authCheck.js.html
@@ -0,0 +1,84 @@
+
+
+
+ Code coverage report for hw5/services/middlewares/authCheck.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 25%
+ Statements
+ 1/4
+
+
+ 0%
+ Branches
+ 0/2
+
+
+ 0%
+ Functions
+ 0/1
+
+
+ 33.33%
+ Lines
+ 1/3
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+1x
+
+
+
+ // route middleware to make sure a user is logged in
+module.exports = (r eq, res, next) => {
+ if (req.isAuthenticated()) return next()
+ res.status(401).send('You have to be authenticated.')
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/middlewares/index.html b/coverage/lcov-report/hw5/services/middlewares/index.html
new file mode 100644
index 0000000..1d241bc
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/middlewares/index.html
@@ -0,0 +1,110 @@
+
+
+
+ Code coverage report for hw5/services/middlewares
+
+
+
+
+
+
+
+
+
+
+ All files hw5/services/middlewares
+
+
+
+ 69.23%
+ Statements
+ 9/13
+
+
+ 25%
+ Branches
+ 1/4
+
+
+ 66.67%
+ Functions
+ 2/3
+
+
+ 81.82%
+ Lines
+ 9/11
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ authCheck.js
+
+ 25%
+ 1/4
+ 0%
+ 0/2
+ 0%
+ 0/1
+ 33.33%
+ 1/3
+
+
+
+ validation.js
+
+ 88.89%
+ 8/9
+ 50%
+ 1/2
+ 100%
+ 2/2
+ 100%
+ 8/8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/middlewares/validation.js.html b/coverage/lcov-report/hw5/services/middlewares/validation.js.html
new file mode 100644
index 0000000..f4863d3
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/middlewares/validation.js.html
@@ -0,0 +1,114 @@
+
+
+
+ Code coverage report for hw5/services/middlewares/validation.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 88.89%
+ Statements
+ 8/9
+
+
+ 50%
+ Branches
+ 1/2
+
+
+ 100%
+ Functions
+ 2/2
+
+
+ 100%
+ Lines
+ 8/8
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16 1x
+
+1x
+5x
+
+
+1x
+1x
+1x
+
+
+5x
+
+
+1x
+ const { validationResult } = require('express-validator')
+
+const validation = rules => {
+ const middlewares = [
+ ...rules,
+ (req, res, next) => {
+ const errors = validationResult(req)
+ I if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() })
+ next()
+ }
+ ]
+ return middlewares
+}
+
+module.exports = { validation }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/multer.js.html b/coverage/lcov-report/hw5/services/multer.js.html
new file mode 100644
index 0000000..df3cb73
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/multer.js.html
@@ -0,0 +1,126 @@
+
+
+
+ Code coverage report for hw5/services/multer.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 5/5
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 0/0
+
+
+ 100%
+ Lines
+ 5/5
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20 1x
+
+1x
+
+1x
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+1x
+ const Multer = require('multer')
+
+const { avatarStorage, articlesStorage } = require('./gcStorageService')
+
+const avatarMulter = Multer({
+ storage: avatarStorage,
+ limits: {
+ fileSize: 5 * 1024 * 1024
+ }
+})
+
+const articlesMulter = Multer({
+ storage: articlesStorage,
+ limits: {
+ fileSize: 5 * 1024 * 1024
+ }
+})
+
+module.exports = { avatarMulter, articlesMulter }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/passportService.js.html b/coverage/lcov-report/hw5/services/passportService.js.html
new file mode 100644
index 0000000..6a04165
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/passportService.js.html
@@ -0,0 +1,333 @@
+
+
+
+ Code coverage report for hw5/services/passportService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 44.74%
+ Statements
+ 17/38
+
+
+ 0%
+ Branches
+ 0/4
+
+
+ 50%
+ Functions
+ 3/6
+
+
+ 45.71%
+ Lines
+ 16/35
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89 1x
+1x
+1x
+
+1x
+1x
+1x
+1x
+
+1x
+1x
+
+1x
+1x
+1x
+1x
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ const LocalStrategy = require('passport-local').Strategy
+const GoogleStrategy = require('passport-google-oauth20')
+const FacebookStrategy = require('passport-facebook').Strategy
+
+const { errorLogger } = require('./logger')
+const { checkPsw } = require('./hashPsw')
+const { Users } = require('../db/models/index.js')
+const { AuthService } = require('./AuthService')
+
+module.exports = passport => {
+ passport.serializeUser((user, done) => done(null, user.id))
+
+ passport.deserializeUser(async (id, done) => {
+ try {
+ const user = await Users.findByPk(id)
+ return done(null, user)
+ } catch (err) {
+ done(err)
+ errorLogger.error(`An error on MySQL request`, { metadata: err })
+ }
+ })
+
+ passport.use(
+ new LocalStrategy({ usernameField: 'email', passwordField: 'password' }, as ync (email, password, done) => {
+ try {
+ const userData = await Users.unscoped().findOne({ where: { email: email } })
+ const user = userData.get({ plain: true })
+ if (!user.isVerified) done({ error: 'You should verify your account. Check your email.' })
+ const match = await checkPsw(password, user.password)
+ if (match) return done(null, user)
+ return done(null, {})
+ } catch (err) {
+ done(err)
+ errorLogger.error(`An error on MySQL request`, { metadata: err })
+ }
+ })
+ )
+
+ passport.use(
+ new GoogleStrategy(
+ {
+ clientID: process.env.GOOGLE_CLIENT_ID,
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
+ callbackURL: process.env.GOOGLE_CALLBACK_URL
+ },
+ as ync (accessToken, refreshToken, profile, done) => {
+ try {
+ const user = await AuthService.findOrCreateOauthProvider({
+ provider: 'google',
+ email: profile._json.email,
+ firstName: profile._json.given_name,
+ lastName: profile._json.family_name,
+ providerUserId: profile.id
+ })
+ done(null, user)
+ } catch (e) {
+ done(e)
+ }
+ }
+ )
+ )
+
+ passport.use(
+ 'facebook-strategy',
+ new FacebookStrategy(
+ {
+ clientID: process.env.FACEBOOK_CLIENT_ID,
+ clientSecret: process.env.FACEBOOK_CLIENT_SECRET,
+ callbackURL: process.env.FACEBOOK_CALLBACK_URL,
+ profileFields: ['id', 'email', 'first_name', 'last_name']
+ },
+ as ync (accessToken, refreshToken, profile, done) => {
+ try {
+ const user = await AuthService.findOrCreateOauthProvider({
+ provider: 'facebook',
+ email: profile._json.email,
+ firstName: profile.name.givenName,
+ lastName: profile.name.familyName,
+ providerUserId: profile.id
+ })
+ done(null, user)
+ } catch (error) {
+ done(error)
+ }
+ }
+ )
+ )
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/queryHelperService.js.html b/coverage/lcov-report/hw5/services/queryHelperService.js.html
new file mode 100644
index 0000000..4cca3e2
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/queryHelperService.js.html
@@ -0,0 +1,156 @@
+
+
+
+ Code coverage report for hw5/services/queryHelperService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 35.71%
+ Statements
+ 5/14
+
+
+ 0%
+ Branches
+ 0/6
+
+
+ 0%
+ Functions
+ 0/2
+
+
+ 38.46%
+ Lines
+ 5/13
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30 1x
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+ const Op = require('sequelize').Op
+const { Articles, Users, Comments } = require('../db/models/index')
+
+const getArticles = as ync (after, authorId) => {
+ let whereObj = {}
+ if (after) {
+ const [timestamp, id] = after.split('_')
+ whereObj = { id: { [Op.lte]: +id }, publishedAt: { [Op.lt]: timestamp } }
+ }
+ if (authorId) whereObj.authorId = authorId
+ return await Articles.findAll({
+ where: whereObj,
+ limit: 5,
+ order: [['publishedAt', 'DESC'], ['id', 'ASC']],
+ include: [{ model: Users, as: 'author' }]
+ })
+}
+
+const getComments = as ync (articleId, continuation) => {
+ let whereObj = !continuation ? { articleId } : { id: { [Op.lt]: continuation }, articleId }
+ return await Comments.findAll({
+ where: whereObj,
+ limit: 5,
+ order: [['id', 'DESC']],
+ include: [{ model: Users, as: 'author', attributes: ['id', 'firstName', 'lastName', 'picture'] }]
+ })
+}
+
+module.exports = { getArticles, getComments }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/rateLimitService.js.html b/coverage/lcov-report/hw5/services/rateLimitService.js.html
new file mode 100644
index 0000000..e379734
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/rateLimitService.js.html
@@ -0,0 +1,168 @@
+
+
+
+ Code coverage report for hw5/services/rateLimitService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 8/8
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 8/8
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34 1x
+1x
+1x
+
+1x
+1x
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+1x
+
+ const RateLimit = require('express-rate-limit')
+const RLimitStore = require('rate-limit-redis')
+const { RateLimiterRedis } = require('rate-limiter-flexible')
+
+module.exports = client => {
+ const limiter = new RateLimit({
+ store: new RLimitStore({
+ client: client,
+ prefix: 'denis:limits:'
+ }),
+ max: 200,
+ delayMs: 0
+ })
+
+ const loginLimiter = new RateLimit({
+ store: new RLimitStore({
+ client: client,
+ prefix: 'denis:loginLimits:'
+ }),
+ windowMs: 10 * 60 * 1000,
+ max: 20,
+ delayMs: 0
+ })
+
+ const wsLimiter = new RateLimiterRedis({
+ redis: client,
+ keyPrefix: 'denis:socket:rl:',
+ points: 15,
+ duration: 30
+ })
+
+ return { limiter, loginLimiter, wsLimiter }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/redisConnectService.js.html b/coverage/lcov-report/hw5/services/redisConnectService.js.html
new file mode 100644
index 0000000..8547445
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/redisConnectService.js.html
@@ -0,0 +1,96 @@
+
+
+
+ Code coverage report for hw5/services/redisConnectService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 83.33%
+ Statements
+ 5/6
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 0%
+ Functions
+ 0/1
+
+
+ 83.33%
+ Lines
+ 5/6
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10 1x
+1x
+1x
+
+1x
+
+
+
+1x
+ const R = require('ioredis')
+const client = new R(process.env.REDIS_URL)
+const { errorLogger } = require('./logger')
+
+client.on('error', er r => {
+ errorLogger.error(`An error on Redis`, { metadata: err })
+})
+
+module.exports = client
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/socketService.js.html b/coverage/lcov-report/hw5/services/socketService.js.html
new file mode 100644
index 0000000..12aa003
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/socketService.js.html
@@ -0,0 +1,186 @@
+
+
+
+ Code coverage report for hw5/services/socketService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 38.46%
+ Statements
+ 10/26
+
+
+ 0%
+ Branches
+ 0/4
+
+
+ 10%
+ Functions
+ 1/10
+
+
+ 43.48%
+ Lines
+ 10/23
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40 1x
+1x
+1x
+
+1x
+
+1x
+1x
+1x
+1x
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+ const socketio = require('socket.io')
+const passportSocketIo = require('passport.socketio')
+const adapter = require('socket.io-redis')
+
+const { errorLogger } = require('./logger')
+
+module.exports = (server, rStore, wsLimiter) => {
+ const io = socketio(server)
+ io.adapter(adapter(process.env.REDIS_URL))
+ io.use(
+ passportSocketIo.authorize({
+ secret: process.env.SESSION_SECRET,
+ store: rStore,
+ fail: (d ata, message, error, accept) => accept()
+ })
+ )
+
+ io.on('connection', fu nction(socket) {
+ io.of('/').adapter.clients((e rr, clients) => {
+ if (err) errorLogger.error(`Some problem with socket connection`, { metadata: err })
+ })
+ const ip = socket.request.connection.remoteAddress
+ socket.use((p acket, next) => {
+ wsLimiter
+ .consume(ip)
+ .then(co nsume => next())
+ .catch(co nsume => next(new Error('Rate limit error')))
+ })
+ if (socket.request.user.logged_in) {
+ socket.on('watch-comments', ar ticleId => socket.join(`room-${articleId}`))
+ socket.on('unwatch-comments', ar ticleId => socket.leave(`room-${articleId}`))
+
+ socket.on('comment-typing', ar ticleId => {
+ socket.to(`room-${articleId}`).emit('comment-typing', { action: 'typing' })
+ })
+ }
+ })
+ return io
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/stripeService.js.html b/coverage/lcov-report/hw5/services/stripeService.js.html
new file mode 100644
index 0000000..8c07c9a
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/stripeService.js.html
@@ -0,0 +1,171 @@
+
+
+
+ Code coverage report for hw5/services/stripeService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 41.18%
+ Statements
+ 7/17
+
+
+ 0%
+ Branches
+ 0/4
+
+
+ 0%
+ Functions
+ 0/4
+
+
+ 41.18%
+ Lines
+ 7/17
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35 1x
+1x
+1x
+
+1x
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+1x
+ const stripe = require('stripe')(process.env.STRIPE_SK)
+const asyncHandler = require('express-async-handler')
+const { Users } = require('../db/models/index')
+
+const createCustomer = asyncHandler(as ync (token, user) => {
+ const customer = await stripe.customers.create({ email: user.email, source: token })
+ const updated = await Users.update(
+ { stripe_customer_id: customer.id, stripe_card_id: customer.default_source },
+ { where: { id: user.id } }
+ )
+ return updated ? { stripe_customer_id: customer.id, stripe_card_id: customer.default_source } : null
+})
+
+const createCharge = asyncHandler(as ync (customerID, cardID, amount, email) => {
+ const charge = await stripe.charges.create({
+ customer: customerID,
+ amount: amount,
+ currency: 'usd',
+ description: `Charge Pro for ${email}`,
+ source: cardID
+ })
+ return charge ? charge.receipt_url : null
+})
+
+const getChargesAmount = asyncHandler(as ync customerID => {
+ const charges = await stripe.charges.list({ customer: customerID })
+ let sum = 0
+ charges.data.forEach(it em => {
+ sum += item.amount
+ })
+ return sum / 100
+})
+
+module.exports = { createCustomer, createCharge, getChargesAmount }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/services/validationService.js.html b/coverage/lcov-report/hw5/services/validationService.js.html
new file mode 100644
index 0000000..44a2302
--- /dev/null
+++ b/coverage/lcov-report/hw5/services/validationService.js.html
@@ -0,0 +1,324 @@
+
+
+
+ Code coverage report for hw5/services/validationService.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 68%
+ Statements
+ 17/25
+
+
+ 37.5%
+ Branches
+ 3/8
+
+
+ 33.33%
+ Functions
+ 1/3
+
+
+ 85%
+ Lines
+ 17/20
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86 1x
+
+1x
+
+1x
+1x
+1x
+1x
+1x
+1x
+1x
+
+
+1x
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+
+1x
+
+
+
+
+
+
+
+1x
+ const { body } = require('express-validator')
+
+const { validation } = require('../services/middlewares/validation')
+
+const isPass = value => {
+ const letters = /[a-zA-Z]/
+ const numbers = /[0-9]/
+ I if (value.length < 6) return false
+ I if (!letters.test(value)) return false
+ I if (!numbers.test(value)) return false
+ return true
+}
+
+const checkCommentLength = va lue => value.length >= 2
+
+const userCreationValidation = validation([
+ body('firstName')
+ .exists({ checkFalsy: true })
+ .withMessage('First name is required'),
+ body('lastName')
+ .exists({ checkFalsy: true })
+ .withMessage('Last name is required'),
+ body('email')
+ .exists({ checkFalsy: true })
+ .withMessage('Email is required')
+ .isEmail()
+ .withMessage('Should be an email'),
+ body('password')
+ .exists({ checkFalsy: true })
+ .withMessage('Password is required')
+ .custom(isPass)
+ .withMessage('Password must have at least 6 symbols and digits.')
+])
+
+const loginValidation = validation([
+ body('email')
+ .exists({ checkFalsy: true })
+ .withMessage('Email is required')
+ .isEmail()
+ .withMessage('Should be an email'),
+ body('password')
+ .exists({ checkFalsy: true })
+ .withMessage('Password is required')
+ .custom(isPass)
+ .withMessage('Password must have at least 6 symbols and digits.')
+])
+
+const isValidDate = va lue => {
+ const date = new Date(value)
+ if (date.getDate) return true
+ return false
+}
+
+const articleValidation = validation([
+ body('title')
+ .exists({ checkFalsy: true })
+ .withMessage('Title is required'),
+ body('content')
+ .exists({ checkFalsy: true })
+ .withMessage('Content is required'),
+ body('publishedAt')
+ .exists({ checkFalsy: true })
+ .withMessage('publishedAt is required')
+ .custom(isValidDate)
+ .withMessage('publishedAt must be valid')
+])
+
+const editUserValidation = validation([
+ body('firstName')
+ .exists({ checkFalsy: true })
+ .withMessage('First name is required'),
+ body('lastName')
+ .exists({ checkFalsy: true })
+ .withMessage('Last name is required')
+])
+
+const commentValidation = validation([
+ body('content')
+ .exists({ checkFalsy: true })
+ .withMessage('Content is required')
+ .custom(checkCommentLength)
+ .withMessage('Content must have at least 2 symbols')
+])
+
+module.exports = { userCreationValidation, articleValidation, loginValidation, editUserValidation, commentValidation }
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/tests/helpers.js.html b/coverage/lcov-report/hw5/tests/helpers.js.html
new file mode 100644
index 0000000..4c32126
--- /dev/null
+++ b/coverage/lcov-report/hw5/tests/helpers.js.html
@@ -0,0 +1,150 @@
+
+
+
+ Code coverage report for hw5/tests/helpers.js
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 19/19
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 19/19
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+1x
+1x
+1x
+1x
+1x
+
+1x
+
+1x
+1x
+1x
+1x
+1x
+
+1x
+1x
+1x
+1x
+
+1x
+1x
+1x
+
+1x
+
+
+ /* eslint-disable */
+const faker = require('faker')
+const supertest = require('supertest')
+const app = require('../index')
+const { SendgridService } = require('../services/emailService')
+const request = supertest(app)
+
+module.exports = {
+ registerUser: async () => {
+ const firstName = faker.name.firstName()
+ const lastName = faker.name.lastName()
+ const email = faker.internet.email()
+ const password = faker.internet.password()
+ const sendEmailSpy = jest.spyOn(SendgridService, 'sendEmail').mockImplementation()
+
+ await request.post('/api/v1/registration').send({ firstName, lastName, email, password })
+ const { verifyLink } = sendEmailSpy.mock.calls[0][3]
+ const token = verifyLink.split('token=').pop()
+ const response = await request.post('/api/v1/registration/verify').send({ token })
+
+ sendEmailSpy.mockReset()
+ const user = response.body.data
+ user.authCookie = response.headers['set-cookie'][0].split(';').shift()
+
+ return user
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/hw5/tests/index.html b/coverage/lcov-report/hw5/tests/index.html
new file mode 100644
index 0000000..54c4d05
--- /dev/null
+++ b/coverage/lcov-report/hw5/tests/index.html
@@ -0,0 +1,97 @@
+
+
+
+ Code coverage report for hw5/tests
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+ Statements
+ 19/19
+
+
+ 100%
+ Branches
+ 0/0
+
+
+ 100%
+ Functions
+ 1/1
+
+
+ 100%
+ Lines
+ 19/19
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ helpers.js
+
+ 100%
+ 19/19
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 19/19
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html
new file mode 100644
index 0000000..98fabee
--- /dev/null
+++ b/coverage/lcov-report/index.html
@@ -0,0 +1,201 @@
+
+
+
+ Code coverage report for All files
+
+
+
+
+
+
+
+
+
+
+ All files
+
+
+
+ 56.63%
+ Statements
+ 380/671
+
+
+ 15.18%
+ Branches
+ 17/112
+
+
+ 23.93%
+ Functions
+ 28/117
+
+
+ 59.94%
+ Lines
+ 377/629
+
+
+
+ Press n or j to go to the next uncovered block, b , p or k for the previous block.
+
+
+
+
+
+
+
+ File
+
+ Statements
+
+ Branches
+
+ Functions
+
+ Lines
+
+
+
+
+ hw5
+
+ 84.09%
+ 37/44
+ 25%
+ 1/4
+ 40%
+ 2/5
+ 86.05%
+ 37/43
+
+
+
+ hw5/db
+
+ 100%
+ 3/3
+ 100%
+ 0/0
+ 100%
+ 0/0
+ 100%
+ 3/3
+
+
+
+ hw5/db/models
+
+ 100%
+ 35/35
+ 50%
+ 1/2
+ 100%
+ 5/5
+ 100%
+ 35/35
+
+
+
+ hw5/mongodb
+
+ 36.84%
+ 14/38
+ 100%
+ 0/0
+ 28.57%
+ 2/7
+ 36.84%
+ 14/38
+
+
+
+ hw5/mongodb/models
+
+ 52.38%
+ 11/21
+ 100%
+ 0/0
+ 0%
+ 0/7
+ 55%
+ 11/20
+
+
+
+ hw5/routes
+
+ 49%
+ 122/249
+ 6%
+ 3/50
+ 14.71%
+ 5/34
+ 51.71%
+ 121/234
+
+
+
+ hw5/services
+
+ 52.21%
+ 130/249
+ 21.15%
+ 11/52
+ 20%
+ 11/55
+ 56.64%
+ 128/226
+
+
+
+ hw5/services/middlewares
+
+ 69.23%
+ 9/13
+ 25%
+ 1/4
+ 66.67%
+ 2/3
+ 81.82%
+ 9/11
+
+
+
+ hw5/tests
+
+ 100%
+ 19/19
+ 100%
+ 0/0
+ 100%
+ 1/1
+ 100%
+ 19/19
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css
new file mode 100644
index 0000000..b317a7c
--- /dev/null
+++ b/coverage/lcov-report/prettify.css
@@ -0,0 +1 @@
+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js
new file mode 100644
index 0000000..b322523
--- /dev/null
+++ b/coverage/lcov-report/prettify.js
@@ -0,0 +1,2 @@
+/* eslint-disable */
+window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^