@questwork/q-utilities 0.1.1 → 0.1.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/dist/index.min.cjs +978 -0
- package/dist/index.min.js +964 -0
- package/package.json +33 -17
- package/index.js +0 -3
- package/lib/authenticator/authenticator.js +0 -56
- package/lib/authenticator/clientApp.js +0 -46
- package/lib/authenticator/index.js +0 -5
- package/lib/convertString/convertString.js +0 -20
- package/lib/convertString/index.js +0 -1
- package/lib/cryptoHelper/cryptoHelper.js +0 -93
- package/lib/cryptoHelper/index.js +0 -5
- package/lib/getValidation/getValidation.js +0 -115
- package/lib/getValidation/index.js +0 -1
- package/lib/getValueByKeys/getValueByKeys.js +0 -20
- package/lib/getValueByKeys/index.js +0 -1
- package/lib/index.js +0 -14
- package/lib/jwtHelper/index.js +0 -5
- package/lib/jwtHelper/jwtHelper.js +0 -254
- package/lib/keyValueObject/index.js +0 -1
- package/lib/keyValueObject/keyValueObject.js +0 -163
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
// 'use strict'
|
|
2
|
-
|
|
3
|
-
/* eslint-disable new-cap */
|
|
4
|
-
/* eslint-disable camelcase */
|
|
5
|
-
/* eslint-disable no-mixed-operators */
|
|
6
|
-
/* eslint-disable no-useless-escape */
|
|
7
|
-
/* eslint-disable no-param-reassign */
|
|
8
|
-
|
|
9
|
-
/* eslint func-names: 0 */
|
|
10
|
-
|
|
11
|
-
const Buffer = require('buffer/').Buffer
|
|
12
|
-
|
|
13
|
-
const EXPIRY = 3600 // in second
|
|
14
|
-
const ALGORITHM = 'HS256'
|
|
15
|
-
const SECRET = 'ab1234cd'
|
|
16
|
-
|
|
17
|
-
const jwtHelper = {
|
|
18
|
-
create(obj, { secret, algorithm, expiry } = {}) {
|
|
19
|
-
const sAlgorithm = algorithm || ALGORITHM
|
|
20
|
-
const sSecret = secret || SECRET
|
|
21
|
-
const exp = expiry || getTimeInSecond() + EXPIRY
|
|
22
|
-
const payload = {
|
|
23
|
-
...obj,
|
|
24
|
-
exp
|
|
25
|
-
}
|
|
26
|
-
return encode(payload, sSecret, sAlgorithm)
|
|
27
|
-
},
|
|
28
|
-
createByUser(loginAccount) {
|
|
29
|
-
const exp = getTimeInSecond() + EXPIRY
|
|
30
|
-
const payload = {
|
|
31
|
-
loginAccount,
|
|
32
|
-
exp
|
|
33
|
-
}
|
|
34
|
-
return this.encode(payload)
|
|
35
|
-
},
|
|
36
|
-
encode(payload, algorithm) {
|
|
37
|
-
return encode(payload, SECRET, algorithm)
|
|
38
|
-
},
|
|
39
|
-
decode(token, algorithm) {
|
|
40
|
-
const noVerify = !this.verify(token)
|
|
41
|
-
return decode(token, SECRET, noVerify, algorithm) // if noVerify = true, may skip verification
|
|
42
|
-
},
|
|
43
|
-
getPayload(token) {
|
|
44
|
-
const payload = getPayload(token)
|
|
45
|
-
return {
|
|
46
|
-
payload
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
getPayloadIdByKey(token, key) {
|
|
50
|
-
const payload = getPayload(token)
|
|
51
|
-
const id = payload[key] ? payload[key].id : null
|
|
52
|
-
return {
|
|
53
|
-
id,
|
|
54
|
-
jwtToken: token
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
resolve(token, secret, algorithm) {
|
|
58
|
-
const sSecret = secret || SECRET
|
|
59
|
-
return decode(token, sSecret, false, algorithm) // need verification
|
|
60
|
-
},
|
|
61
|
-
verify(token) {
|
|
62
|
-
const payload = getPayload(token)
|
|
63
|
-
const today = getTimeInSecond()
|
|
64
|
-
return (payload.exp && (today <= payload.exp)) || false
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Private functions
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
const getPayload = (token) => decode(token, SECRET, true)
|
|
73
|
-
|
|
74
|
-
const getTimeInSecond = () => Math.floor(Date.now() / 1000)
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Private functions, based on jwt-simple 0.2.0
|
|
78
|
-
*/
|
|
79
|
-
|
|
80
|
-
const { cryptoHelper } = require('../cryptoHelper')
|
|
81
|
-
|
|
82
|
-
const algorithmMap = {
|
|
83
|
-
HS256: 'sha256',
|
|
84
|
-
HS384: 'sha384',
|
|
85
|
-
HS512: 'sha512',
|
|
86
|
-
RS256: 'RSA-SHA256'
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const typeMap = {
|
|
90
|
-
HS256: 'hmac',
|
|
91
|
-
HS384: 'hmac',
|
|
92
|
-
HS512: 'hmac',
|
|
93
|
-
RS256: 'sign'
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Decode jwt
|
|
99
|
-
*
|
|
100
|
-
* @param {Object} token
|
|
101
|
-
* @param {String} key
|
|
102
|
-
* @param {Boolean} noVerify
|
|
103
|
-
* @param {String} algorithm
|
|
104
|
-
* @return {Object} payload
|
|
105
|
-
* @api public
|
|
106
|
-
*/
|
|
107
|
-
const decode = function jwt_decode(token, key, noVerify, algorithm) {
|
|
108
|
-
// check token
|
|
109
|
-
if (!token) {
|
|
110
|
-
throw new Error('No token supplied')
|
|
111
|
-
}
|
|
112
|
-
// check segments
|
|
113
|
-
const segments = token.split('.')
|
|
114
|
-
if (segments.length !== 3) {
|
|
115
|
-
throw new Error('Not enough or too many segments')
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// All segment should be base64
|
|
119
|
-
const headerSeg = segments[0]
|
|
120
|
-
const payloadSeg = segments[1]
|
|
121
|
-
const signatureSeg = segments[2]
|
|
122
|
-
|
|
123
|
-
// base64 decode and parse JSON
|
|
124
|
-
const header = JSON.parse(base64urlDecode(headerSeg))
|
|
125
|
-
|
|
126
|
-
const payload = JSON.parse(base64urlDecode(payloadSeg))
|
|
127
|
-
|
|
128
|
-
if (!noVerify) {
|
|
129
|
-
const signingMethod = algorithmMap[algorithm || header.alg]
|
|
130
|
-
const signingType = typeMap[algorithm || header.alg]
|
|
131
|
-
if (!signingMethod || !signingType) {
|
|
132
|
-
throw new Error('Algorithm not supported')
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// verify signature. `sign` will return base64 string.
|
|
136
|
-
const signingInput = [headerSeg, payloadSeg].join('.')
|
|
137
|
-
if (!verify(signingInput, key, signingMethod, signingType, signatureSeg)) {
|
|
138
|
-
throw new Error('Signature verification failed')
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return payload
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Encode jwt
|
|
148
|
-
*
|
|
149
|
-
* @param {Object} payload
|
|
150
|
-
* @param {String} key
|
|
151
|
-
* @param {String} algorithm
|
|
152
|
-
* @return {String} token
|
|
153
|
-
* @api public
|
|
154
|
-
*/
|
|
155
|
-
const encode = function jwt_encode(payload, key, algorithm) {
|
|
156
|
-
// Check key
|
|
157
|
-
if (!key) {
|
|
158
|
-
throw new Error('Require key')
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Check algorithm, default is HS256
|
|
162
|
-
if (!algorithm) {
|
|
163
|
-
algorithm = ALGORITHM
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const signingMethod = algorithmMap[algorithm]
|
|
167
|
-
const signingType = typeMap[algorithm]
|
|
168
|
-
if (!signingMethod || !signingType) {
|
|
169
|
-
throw new Error('Algorithm not supported')
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// header, typ is fixed value.
|
|
173
|
-
const header = { typ: 'JWT', alg: algorithm }
|
|
174
|
-
|
|
175
|
-
// create segments, all segments should be base64 string
|
|
176
|
-
const segments = []
|
|
177
|
-
segments.push(base64urlEncode(JSON.stringify(header)))
|
|
178
|
-
segments.push(base64urlEncode(JSON.stringify(payload)))
|
|
179
|
-
segments.push(sign(segments.join('.'), key, signingMethod, signingType))
|
|
180
|
-
|
|
181
|
-
return segments.join('.')
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* private util functions
|
|
187
|
-
*/
|
|
188
|
-
|
|
189
|
-
function verify(input, key, method, type, signature) {
|
|
190
|
-
if (type === 'hmac') {
|
|
191
|
-
return (signature === sign(input, key, method, type))
|
|
192
|
-
} else if (type === 'sign') {
|
|
193
|
-
try {
|
|
194
|
-
return cryptoHelper.createStringVerify({
|
|
195
|
-
algorithm: method,
|
|
196
|
-
data: input,
|
|
197
|
-
object: key,
|
|
198
|
-
signature: base64urlUnescape(signature),
|
|
199
|
-
signatureEncoding: 'base64'
|
|
200
|
-
})
|
|
201
|
-
} catch (error) {
|
|
202
|
-
throw new Error('createStringVerify failed')
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
throw new Error('Algorithm type not recognized')
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function sign(input, key, method, type) {
|
|
209
|
-
let base64str
|
|
210
|
-
if (type === 'hmac') {
|
|
211
|
-
base64str = cryptoHelper.createStringHmac({
|
|
212
|
-
algorithm: method,
|
|
213
|
-
key,
|
|
214
|
-
data: input,
|
|
215
|
-
outputEncoding: 'base64'
|
|
216
|
-
})
|
|
217
|
-
} else if (type === 'sign') {
|
|
218
|
-
try {
|
|
219
|
-
base64str = cryptoHelper.createSignature({
|
|
220
|
-
algorithm: method,
|
|
221
|
-
data: input,
|
|
222
|
-
privateKey: key,
|
|
223
|
-
outputEncoding: 'base64'
|
|
224
|
-
})
|
|
225
|
-
} catch (error) {
|
|
226
|
-
throw new Error('createSignature failed')
|
|
227
|
-
}
|
|
228
|
-
} else {
|
|
229
|
-
throw new Error('Algorithm type not recognized')
|
|
230
|
-
}
|
|
231
|
-
return base64urlEscape(base64str)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
function base64urlDecode(str) {
|
|
235
|
-
// fixed bug if decode string is incorrect
|
|
236
|
-
return (new Buffer.from(base64urlUnescape(str), 'base64')).toString() || '{}'
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
function base64urlUnescape(str) {
|
|
240
|
-
str += new Array(5 - str.length % 4).join('=')
|
|
241
|
-
return str.replace(/\-/g, '+').replace(/_/g, '/')
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function base64urlEncode(str) {
|
|
245
|
-
return base64urlEscape(new Buffer.from((str)).toString('base64'))
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function base64urlEscape(str) {
|
|
249
|
-
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
module.exports = {
|
|
253
|
-
jwtHelper
|
|
254
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { KeyValueObject } from './keyValueObject'
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
class KeyValueObject {
|
|
4
|
-
constructor(options = {}) {
|
|
5
|
-
options = options || {}
|
|
6
|
-
this.key = options.key || null
|
|
7
|
-
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// Class methods
|
|
11
|
-
|
|
12
|
-
static addItem(arr, key, value) {
|
|
13
|
-
arr.push(
|
|
14
|
-
{ key, value }
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
static addRecord(arr = [], key, value) {
|
|
18
|
-
const self = this
|
|
19
|
-
if (!KeyValueObject.hasKeyValue(arr, key, value)) {
|
|
20
|
-
arr.push(self.init({ key, value }))
|
|
21
|
-
}
|
|
22
|
-
return arr
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
static fromObject(options = {}) {
|
|
26
|
-
const self = this
|
|
27
|
-
return Object.keys(options).reduce((acc, key) => {
|
|
28
|
-
acc.push(self.init({ key, value: options[key] }))
|
|
29
|
-
return acc
|
|
30
|
-
}, [])
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static removeByKey(arr, key) {
|
|
34
|
-
return arr.reduce((acc, item) => {
|
|
35
|
-
if (item.key !== key) {
|
|
36
|
-
acc.push(item)
|
|
37
|
-
}
|
|
38
|
-
return acc
|
|
39
|
-
}, [])
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
static getValuesByKey(arr = [], key) {
|
|
43
|
-
return arr.reduce((acc, item) => {
|
|
44
|
-
if (item.key === key) {
|
|
45
|
-
acc.push(item.value)
|
|
46
|
-
}
|
|
47
|
-
return acc
|
|
48
|
-
}, [])
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
static hasKeyValue(arr = [], key, value) {
|
|
52
|
-
if (typeof value === 'undefined') {
|
|
53
|
-
return arr.filter((item) => item.key === key).length > 0
|
|
54
|
-
}
|
|
55
|
-
return arr.filter((item) => (item.key === key && item.value === value)).length > 0
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static init(options = {}) {
|
|
59
|
-
if (options instanceof KeyValueObject) {
|
|
60
|
-
return options
|
|
61
|
-
}
|
|
62
|
-
const kvObject = new KeyValueObject(options)
|
|
63
|
-
return kvObject.isValid ? kvObject : null
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
static initFromArray(arr = []) {
|
|
67
|
-
const self = this
|
|
68
|
-
if (Array.isArray(arr)) {
|
|
69
|
-
return arr.map(self.init)
|
|
70
|
-
}
|
|
71
|
-
return []
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
static initOnlyValidFromArray(arr = []) {
|
|
75
|
-
return this.initFromArray(arr).filter((i) => i)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
static keys(arr = []) {
|
|
79
|
-
if (Array.isArray(arr)) {
|
|
80
|
-
return arr.reduce((acc, item) => {
|
|
81
|
-
acc.push(item.key)
|
|
82
|
-
return acc
|
|
83
|
-
}, [])
|
|
84
|
-
}
|
|
85
|
-
return []
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
static toObject(arr = []) {
|
|
89
|
-
if (Array.isArray(arr)) {
|
|
90
|
-
return arr.reduce((acc, item) => {
|
|
91
|
-
acc[item.key] = item.value
|
|
92
|
-
return acc
|
|
93
|
-
}, {})
|
|
94
|
-
}
|
|
95
|
-
return {}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
static toString(arr = [], delimiter = '; ') {
|
|
99
|
-
if (Array.isArray(arr)) {
|
|
100
|
-
return arr.reduce((acc, item) => {
|
|
101
|
-
acc.push(`${item.key}: ${item.value}`)
|
|
102
|
-
return acc
|
|
103
|
-
}, []).join(delimiter)
|
|
104
|
-
}
|
|
105
|
-
return ''
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
static updateRecord(arr = [], key, value) {
|
|
109
|
-
return arr.map((item) => {
|
|
110
|
-
if (item.key === key) {
|
|
111
|
-
item.value = value
|
|
112
|
-
}
|
|
113
|
-
return item
|
|
114
|
-
})
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
static updateOrInsertRecord(arr = [], key, value) {
|
|
118
|
-
const self = this
|
|
119
|
-
let copy = [...arr]
|
|
120
|
-
if (!self.hasKeyValue(arr, key)) {
|
|
121
|
-
copy.push(self.init({ key, value }))
|
|
122
|
-
} else {
|
|
123
|
-
copy = self.updateRecord(arr, key, value)
|
|
124
|
-
}
|
|
125
|
-
return copy
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
static updateRecordsFromArray(arr = [], updateArr = []) {
|
|
129
|
-
if (Array.isArray(arr) && Array.isArray(updateArr)) {
|
|
130
|
-
const obj1 = KeyValueObject.toObject(arr)
|
|
131
|
-
const obj2 = KeyValueObject.toObject(updateArr)
|
|
132
|
-
return KeyValueObject.fromObject(Object.assign({}, obj1, obj2))
|
|
133
|
-
}
|
|
134
|
-
return []
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
static values(arr = []) {
|
|
138
|
-
if (Array.isArray(arr)) {
|
|
139
|
-
return arr.reduce((acc, item) => {
|
|
140
|
-
acc.push(item.value)
|
|
141
|
-
return acc
|
|
142
|
-
}, [])
|
|
143
|
-
}
|
|
144
|
-
return []
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// getters
|
|
148
|
-
get isValid() {
|
|
149
|
-
return !!this.key
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
get toObject() {
|
|
153
|
-
const obj = {}
|
|
154
|
-
if (this.isValid) {
|
|
155
|
-
obj[this.key] = this.value
|
|
156
|
-
}
|
|
157
|
-
return obj
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export {
|
|
162
|
-
KeyValueObject
|
|
163
|
-
}
|