@bitfinex/bfx-facs-auth-google 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/migrations.js ADDED
@@ -0,0 +1,63 @@
1
+ 'use strict'
2
+
3
+ const tableName = 'admin_users'
4
+
5
+ const migrations = [
6
+ (_this, cb) => {
7
+ _this.db.all(`PRAGMA table_info(${tableName})`, [], (err, rows) => {
8
+ if (err) return cb(err)
9
+ if (rows?.find(row => row.name === 'manageAdminsPrivilege')) return cb()
10
+
11
+ _this.db.run(`
12
+ ALTER TABLE ${tableName}
13
+ ADD manageAdminsPrivilege TINYINTEGER
14
+ `, cb)
15
+ })
16
+ },
17
+ (_this, cb) => {
18
+ _this.db.all(`PRAGMA table_info(${tableName})`, [], (err, rows) => {
19
+ if (err) return cb(err)
20
+ if (rows?.find(row => row.name === 'forms')) return cb()
21
+
22
+ _this.db.run(`
23
+ ALTER TABLE ${tableName}
24
+ ADD forms TEXT
25
+ `, cb)
26
+ })
27
+ },
28
+ (_this, cb) => {
29
+ _this.db.all(`PRAGMA table_info(${tableName})`, [], (err, rows) => {
30
+ if (err) return cb(err)
31
+ if (rows?.find(row => row.name === 'passwordResetSentAt')) return cb()
32
+
33
+ _this.db.run(`
34
+ ALTER TABLE ${tableName}
35
+ ADD passwordResetSentAt DATETIME
36
+ `, cb)
37
+ })
38
+ },
39
+ (_this, cb) => {
40
+ _this.db.all(`PRAGMA table_info(${tableName})`, [], (err, rows) => {
41
+ if (err) return cb(err)
42
+ if (rows?.find(row => row.name === 'passwordResetToken')) return cb()
43
+
44
+ _this.db.run(`
45
+ ALTER TABLE ${tableName}
46
+ ADD passwordResetToken TEXT
47
+ `, cb)
48
+ })
49
+ },
50
+ (_this, cb) => {
51
+ _this.db.all(`PRAGMA table_info(${tableName})`, [], (err, rows) => {
52
+ if (err) return cb(err)
53
+ if (rows?.find(row => row.name === 'fetchMotivationsPrivilege')) return cb()
54
+
55
+ _this.db.run(`
56
+ ALTER TABLE ${tableName}
57
+ ADD fetchMotivationsPrivilege BOOLEAN
58
+ `, cb)
59
+ })
60
+ }
61
+ ]
62
+
63
+ module.exports = migrations
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@bitfinex/bfx-facs-auth-google",
3
+ "version": "1.2.3",
4
+ "private": false,
5
+ "description": "Bitfinex Google Oauth Facility",
6
+ "author": {
7
+ "name": "face",
8
+ "email": "rama@bitfinex.com"
9
+ },
10
+ "keywords": [
11
+ "bitfinex",
12
+ "oath"
13
+ ],
14
+ "dependencies": {
15
+ "@bitfinex/bfx-facs-base": "git+https://github.com/bitfinexcom/bfx-facs-base.git",
16
+ "@bitfinex/bfx-facs-db-sqlite": "git+https://github.com/bitfinexcom/bfx-facs-db-sqlite.git",
17
+ "@bitfinexcom/lib-js-util-base": "git+https://github.com/bitfinexcom/lib-js-util-base.git",
18
+ "async": "^2.6.4",
19
+ "googleapis": "^68.0.0",
20
+ "lodash": "^4.17.21",
21
+ "uuid": "^3.2.1"
22
+ },
23
+ "engines": {
24
+ "node": ">=16.0"
25
+ },
26
+ "main": "index.js",
27
+ "license": "Apache-2.0",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/bitfinexcom/bfx-facs-auth-google.git"
31
+ },
32
+ "homepage": "https://github.com/bitfinexcom/bfx-facs-auth-google",
33
+ "maintainers": [
34
+ {
35
+ "name": "face",
36
+ "email": "<rama@bitfinex.com>"
37
+ },
38
+ {
39
+ "name": "Ezequiel Wernicke",
40
+ "email": "<ezequiel.wernicke@bitfinex.com>"
41
+ },
42
+ {
43
+ "name": "prdn",
44
+ "email": "paolo@bitfinex.com"
45
+ }
46
+ ],
47
+ "scripts": {
48
+ "test": "npm run lint && npm run unit",
49
+ "unit": "mocha",
50
+ "lint": "standard",
51
+ "lintFix": "standard --fix index.js",
52
+ "startSimulatedEnviroment": "node test/simulate/simulate-enviroment.js"
53
+ },
54
+ "devDependencies": {
55
+ "mocha": "^10.2.0",
56
+ "standard": "^17.1.0"
57
+ }
58
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "google" : {
3
+ "clientId": "test-client-id",
4
+ "clientSecret": "test-client-secret"
5
+ },
6
+ "ADM_USERS" : [
7
+ {
8
+ "email": "adm1@bitfinex.com",
9
+ "password": "example123",
10
+ "level": 0
11
+ },
12
+ {
13
+ "email": "adm2@bitfinex.com",
14
+ "password": "example123",
15
+ "level": 0
16
+ },
17
+ {
18
+ "email": "adm3@bitfinex.com",
19
+ "password": "example123",
20
+ "level": 0
21
+ },
22
+ {
23
+ "email": "adm4@bitfinex.com",
24
+ "password": "example123",
25
+ "level": 0
26
+ },
27
+ {
28
+ "email": "admL0@bitfinex.com",
29
+ "password": "example123",
30
+ "level": 0
31
+ },
32
+ {
33
+ "email": "admL1@bitfinex.com",
34
+ "password": "example123",
35
+ "level": 1
36
+ },
37
+ {
38
+ "email": "admL2@bitfinex.com",
39
+ "password": "example123",
40
+ "level": 2
41
+ },
42
+ {
43
+ "email": "google@bitfinex.com",
44
+ "password": false,
45
+ "level": 0
46
+ }
47
+ ],
48
+ "useDB": true
49
+ }
package/test/unit.js ADDED
@@ -0,0 +1,200 @@
1
+ /* eslint-env mocha */
2
+
3
+ 'use strict'
4
+
5
+ const assert = require('assert')
6
+ const fs = require('fs')
7
+ const path = require('path')
8
+
9
+ const conf = require('./config/facs/auth-google.config')
10
+
11
+ const AuthGoogle = require('../')
12
+ const { omit } = require('@bitfinexcom/lib-js-util-base')
13
+
14
+ const dbPath = path.join(__dirname, './db/')
15
+ const ctx = { root: './test' }
16
+ const caller = { ctx }
17
+ const authGoogle = new AuthGoogle(caller, { conf }, ctx)
18
+
19
+ const cleanup = () => {
20
+ if (fs.existsSync(dbPath)) {
21
+ fs.rmSync(dbPath, { recursive: true, force: true })
22
+ }
23
+ }
24
+
25
+ const testForms = ['passport', 'bank_statement', 'merchant']
26
+ const testAdminEmail = 'testForms@admin.com'
27
+ const testAdminWithForms = {
28
+ email: testAdminEmail,
29
+ password: 'test123',
30
+ level: 0,
31
+ forms: testForms
32
+ }
33
+
34
+ describe('forms field', () => {
35
+ beforeEach(async () => {
36
+ cleanup()
37
+ await new Promise((resolve) => authGoogle.start(resolve))
38
+ })
39
+
40
+ afterEach(async () => {
41
+ await new Promise((resolve) => authGoogle.stop(resolve))
42
+ })
43
+
44
+ it('should add admin and stringify forms field', async () => {
45
+ await authGoogle.addAdmin(testAdminWithForms)
46
+
47
+ await new Promise((resolve) => authGoogle.db.get('SELECT * FROM admin_users WHERE email=?', [testAdminEmail], (err, row) => {
48
+ if (err) throw err
49
+ assert.equal(row.forms, JSON.stringify(testForms))
50
+ resolve()
51
+ }))
52
+ })
53
+
54
+ it('should return admin and with parsed form fields', async () => {
55
+ await authGoogle.addAdmin(testAdminWithForms)
56
+
57
+ const res = await authGoogle.getAdmin(testAdminEmail)
58
+
59
+ assert.deepEqual(res.forms, testForms)
60
+ })
61
+
62
+ describe('getAdmin', () => {
63
+ const adminPayload = {
64
+ email: testAdminEmail,
65
+ password: 'test123',
66
+ level: 0
67
+ }
68
+
69
+ const hasJustBeenCreated = payload => assert.ok(Date.now() - new Date(payload.timestamp) < 1000)
70
+
71
+ const assertions = (getAdminResult, expectedActive = true) => {
72
+ assert.equal(getAdminResult.email, adminPayload.email)
73
+ assert.equal(getAdminResult.level, adminPayload.level)
74
+ assert.equal(getAdminResult.active, expectedActive)
75
+ hasJustBeenCreated(getAdminResult)
76
+ }
77
+
78
+ it('should get active admin', async () => {
79
+ await authGoogle.addAdmin(adminPayload)
80
+
81
+ const getAdminResult = await authGoogle.getAdmin(adminPayload.email)
82
+
83
+ assertions(getAdminResult)
84
+ })
85
+
86
+ it('should not get inactive admin', async () => {
87
+ await authGoogle.addAdmin(adminPayload)
88
+ await authGoogle.updateAdmin(adminPayload.email, { active: false })
89
+
90
+ const getAdminResult = await authGoogle.getAdmin(adminPayload.email)
91
+
92
+ assert.equal(getAdminResult, undefined)
93
+ })
94
+
95
+ it('should get inactive admin', async () => {
96
+ await authGoogle.addAdmin(adminPayload)
97
+ await authGoogle.updateAdmin(adminPayload.email, { active: false })
98
+
99
+ const getAdminResult = await authGoogle.getAdmin(adminPayload.email, false)
100
+
101
+ assertions(getAdminResult, false)
102
+ })
103
+
104
+ it('should get admin using uppercased email', async () => {
105
+ await authGoogle.addAdmin(adminPayload)
106
+
107
+ const getAdminResult = await authGoogle.getAdmin(adminPayload.email.toUpperCase())
108
+
109
+ assertions(getAdminResult)
110
+ })
111
+
112
+ it('should get admin using id', async () => {
113
+ const adminCreationResult = await authGoogle.addAdmin(adminPayload)
114
+
115
+ const getAdminResult = await authGoogle.getAdmin(adminCreationResult.id, true, true)
116
+
117
+ assertions(getAdminResult)
118
+ })
119
+ })
120
+
121
+ describe('fetchMotivationsPrivilege permission', () => {
122
+ it('should add admin successfully with fetchMotivationsPrivilege', async () => {
123
+ await authGoogle.addAdmin({
124
+ ...testAdminWithForms,
125
+ fetchMotivationsPrivilege: true
126
+ })
127
+
128
+ const res = await authGoogle.getAdmin(testAdminEmail)
129
+
130
+ assert.strictEqual(res.fetchMotivationsPrivilege, 1)
131
+ })
132
+
133
+ it('should throw error when adding admin with fetchMotivationsPrivilege not being boolean', async () => {
134
+ try {
135
+ await authGoogle.addAdmin({
136
+ ...testAdminWithForms,
137
+ fetchMotivationsPrivilege: 'not boolean'
138
+ })
139
+ throw new Error('SHOULD_NOT_REACH_HERE')
140
+ } catch (e) {
141
+ assert.ok(e instanceof assert.AssertionError)
142
+ assert.strictEqual(e.message, 'fetchMotivationsPrivilege should be a boolean')
143
+ }
144
+ })
145
+
146
+ it('should edit admin successfully with fetchMotivationsPrivilege', async () => {
147
+ await authGoogle.addAdmin(testAdminWithForms)
148
+ const adminBeforeUpdate = await authGoogle.getAdmin(testAdminEmail)
149
+ assert.ok(!adminBeforeUpdate.fetchMotivationsPrivilege)
150
+
151
+ await authGoogle.updateAdmin(testAdminEmail, {
152
+ ...omit(testAdminWithForms, ['email', 'password', 'forms']),
153
+ fetchMotivationsPrivilege: true
154
+ })
155
+ const adminAfterUpdate = await authGoogle.getAdmin(testAdminEmail)
156
+ assert.strictEqual(adminAfterUpdate.fetchMotivationsPrivilege, 1)
157
+ })
158
+
159
+ it('should throw error when editing admin with fetchMotivationsPrivilege not being boolean', async () => {
160
+ await authGoogle.addAdmin(testAdminWithForms)
161
+ const adminBeforeUpdate = await authGoogle.getAdmin(testAdminEmail)
162
+ assert.ok(!adminBeforeUpdate.fetchMotivationsPrivilege)
163
+
164
+ try {
165
+ await authGoogle.updateAdmin(testAdminEmail, {
166
+ ...omit(testAdminWithForms, ['email', 'password', 'forms']),
167
+ fetchMotivationsPrivilege: 'not boolean'
168
+ })
169
+ throw new Error('SHOULD_NOT_REACH_HERE')
170
+ } catch (e) {
171
+ assert.ok(e instanceof assert.AssertionError)
172
+ assert.strictEqual(e.message, 'fetchMotivationsPrivilege should be a boolean')
173
+ }
174
+ })
175
+
176
+ it('should return true when admin has fetch motivations privilege', async () => {
177
+ await authGoogle.addAdmin({
178
+ ...testAdminWithForms,
179
+ level: 1,
180
+ fetchMotivationsPrivilege: true
181
+ })
182
+
183
+ const res = await authGoogle.checkAdmHasFetchMotivationsPrivilege(testAdminEmail)
184
+
185
+ assert.ok(res)
186
+ })
187
+
188
+ it('should return false when admin does not have fetch motivations privilege', async () => {
189
+ await authGoogle.addAdmin({
190
+ ...testAdminWithForms,
191
+ level: 1,
192
+ fetchMotivationsPrivilege: false
193
+ })
194
+
195
+ const res = await authGoogle.checkAdmHasFetchMotivationsPrivilege(testAdminEmail)
196
+
197
+ assert.ok(!res)
198
+ })
199
+ })
200
+ })
@@ -0,0 +1,2 @@
1
+ git fetch upstream
2
+ git merge upstream/master