cozy-client 27.17.0 → 27.18.0
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/CozyClient.js
CHANGED
|
@@ -2464,7 +2464,7 @@ var CozyClient = /*#__PURE__*/function () {
|
|
|
2464
2464
|
CozyClient.hooks = CozyClient.hooks || {};
|
|
2465
2465
|
CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
|
|
2466
2466
|
|
|
2467
|
-
CozyClient.version = "27.
|
|
2467
|
+
CozyClient.version = "27.18.0";
|
|
2468
2468
|
|
|
2469
2469
|
_microee.default.mixin(CozyClient);
|
|
2470
2470
|
|
|
@@ -13,6 +13,8 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
|
|
|
13
13
|
|
|
14
14
|
var _CozyClient = _interopRequireDefault(require("../CozyClient"));
|
|
15
15
|
|
|
16
|
+
var _logger = _interopRequireDefault(require("../logger"));
|
|
17
|
+
|
|
16
18
|
var _storeAttestation = require("./store-attestation");
|
|
17
19
|
|
|
18
20
|
/**
|
|
@@ -134,25 +136,38 @@ var certifyFlagship = /*#__PURE__*/function () {
|
|
|
134
136
|
throw new Error('[FLAGSHIP_CERTIFICATION] Certification configuration is not set');
|
|
135
137
|
|
|
136
138
|
case 2:
|
|
137
|
-
_context3.
|
|
139
|
+
_context3.prev = 2;
|
|
140
|
+
_context3.next = 5;
|
|
138
141
|
return getStackChallenge(client);
|
|
139
142
|
|
|
140
|
-
case
|
|
143
|
+
case 5:
|
|
141
144
|
stackChallengeNonce = _context3.sent;
|
|
142
|
-
_context3.next =
|
|
145
|
+
_context3.next = 8;
|
|
143
146
|
return (0, _storeAttestation.getAppAttestationFromStore)(stackChallengeNonce, certificationConfig);
|
|
144
147
|
|
|
145
|
-
case
|
|
148
|
+
case 8:
|
|
146
149
|
appAttestation = _context3.sent;
|
|
147
|
-
_context3.next =
|
|
150
|
+
_context3.next = 11;
|
|
148
151
|
return giveAppAttestationToStack(appAttestation, stackChallengeNonce, client);
|
|
149
152
|
|
|
150
|
-
case
|
|
153
|
+
case 11:
|
|
154
|
+
_context3.next = 17;
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
case 13:
|
|
158
|
+
_context3.prev = 13;
|
|
159
|
+
_context3.t0 = _context3["catch"](2);
|
|
160
|
+
|
|
161
|
+
_logger.default.warn('[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification');
|
|
162
|
+
|
|
163
|
+
_logger.default.warn(_context3.t0.message);
|
|
164
|
+
|
|
165
|
+
case 17:
|
|
151
166
|
case "end":
|
|
152
167
|
return _context3.stop();
|
|
153
168
|
}
|
|
154
169
|
}
|
|
155
|
-
}, _callee3);
|
|
170
|
+
}, _callee3, null, [[2, 13]]);
|
|
156
171
|
}));
|
|
157
172
|
|
|
158
173
|
return function certifyFlagship(_x5, _x6) {
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { certifyFlagship } from './flagship-certification'
|
|
2
|
+
import { createMockClient } from '../mock'
|
|
3
|
+
|
|
4
|
+
import { getAppAttestationFromStore } from './store-attestation'
|
|
5
|
+
import logger from '../logger'
|
|
6
|
+
|
|
7
|
+
jest.mock('./store-attestation', () => ({
|
|
8
|
+
getAppAttestationFromStore: jest.fn()
|
|
9
|
+
}))
|
|
10
|
+
|
|
11
|
+
jest.mock('../logger', () => ({
|
|
12
|
+
warn: jest.fn()
|
|
13
|
+
}))
|
|
14
|
+
|
|
15
|
+
const getClientMock = () => {
|
|
16
|
+
const client = createMockClient({
|
|
17
|
+
clientOptions: {
|
|
18
|
+
oauth: {}
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
client.stackClient.oauthOptions = {
|
|
23
|
+
clientID: 'SOME_CLIENT_ID',
|
|
24
|
+
registrationAccessToken: 'SOME_REGISTRATION_ACCESS_TOKEN'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return client
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const mockCorrectChallengeRequest = client => {
|
|
31
|
+
client.stackClient.fetchJSON.mockResolvedValueOnce({
|
|
32
|
+
nonce: 'SOME_NONCE'
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const mockCorrectStoreApiRequest = () => {
|
|
37
|
+
getAppAttestationFromStore.mockResolvedValueOnce({
|
|
38
|
+
platform: 'android',
|
|
39
|
+
attestation: 'SOME_STORE_ATTESTATION',
|
|
40
|
+
keyId: 'SOME_KEY_ID'
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const mockCorrectCertificationConfig = () => {
|
|
45
|
+
return {
|
|
46
|
+
androidSafetyNetApiKey: 'SOME_ANDROID_SAFETY_NET_API_KEY'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const getFetchJsonPostParams = (url, body = null) => {
|
|
51
|
+
return [
|
|
52
|
+
'POST',
|
|
53
|
+
url,
|
|
54
|
+
body,
|
|
55
|
+
{
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: 'Bearer SOME_REGISTRATION_ACCESS_TOKEN'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('certifyFlagship', () => {
|
|
64
|
+
afterEach(() => {
|
|
65
|
+
jest.restoreAllMocks()
|
|
66
|
+
getAppAttestationFromStore.mockReset()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('should ask challenge to cozy-stack, call the store API and then send the result to the stack', async () => {
|
|
70
|
+
const client = getClientMock()
|
|
71
|
+
|
|
72
|
+
const certificationConfig = mockCorrectCertificationConfig()
|
|
73
|
+
|
|
74
|
+
mockCorrectChallengeRequest(client)
|
|
75
|
+
|
|
76
|
+
mockCorrectStoreApiRequest()
|
|
77
|
+
|
|
78
|
+
await certifyFlagship(certificationConfig, client)
|
|
79
|
+
|
|
80
|
+
expect(client.stackClient.fetchJSON).toHaveBeenCalledWith(
|
|
81
|
+
...getFetchJsonPostParams(`/auth/clients/SOME_CLIENT_ID/challenge`)
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
expect(getAppAttestationFromStore).toHaveBeenCalledWith('SOME_NONCE', {
|
|
85
|
+
androidSafetyNetApiKey: 'SOME_ANDROID_SAFETY_NET_API_KEY'
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
expect(client.stackClient.fetchJSON).toHaveBeenCalledWith(
|
|
89
|
+
...getFetchJsonPostParams(`/auth/clients/SOME_CLIENT_ID/attestation`, {
|
|
90
|
+
platform: 'android',
|
|
91
|
+
attestation: 'SOME_STORE_ATTESTATION',
|
|
92
|
+
challenge: 'SOME_NONCE',
|
|
93
|
+
keyId: 'SOME_KEY_ID'
|
|
94
|
+
})
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('should throw if no certification config is provided', async () => {
|
|
99
|
+
const client = getClientMock()
|
|
100
|
+
|
|
101
|
+
const certificationConfig = undefined
|
|
102
|
+
|
|
103
|
+
mockCorrectChallengeRequest(client)
|
|
104
|
+
|
|
105
|
+
client.stackClient.fetchJSON.mockImplementationOnce(() => {
|
|
106
|
+
throw Error('SOME_STACK_CERTIFICATION_ERROR')
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
mockCorrectStoreApiRequest()
|
|
110
|
+
|
|
111
|
+
await expect(certifyFlagship(certificationConfig, client)).rejects.toEqual(
|
|
112
|
+
new Error(
|
|
113
|
+
'[FLAGSHIP_CERTIFICATION] Certification configuration is not set'
|
|
114
|
+
)
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
expect(client.stackClient.fetchJSON).not.toHaveBeenCalled()
|
|
118
|
+
expect(getAppAttestationFromStore).not.toHaveBeenCalled()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should ask challenge to cozy-stack and then handle challenge query failure', async () => {
|
|
122
|
+
const client = getClientMock()
|
|
123
|
+
|
|
124
|
+
const certificationConfig = mockCorrectCertificationConfig()
|
|
125
|
+
|
|
126
|
+
// Mock errored stack challenge request
|
|
127
|
+
client.stackClient.fetchJSON.mockImplementation(() => {
|
|
128
|
+
throw Error('SOME_STACK_CHALLENGE_ERROR')
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
mockCorrectStoreApiRequest()
|
|
132
|
+
|
|
133
|
+
await certifyFlagship(certificationConfig, client)
|
|
134
|
+
|
|
135
|
+
expect(client.stackClient.fetchJSON).toHaveBeenCalledWith(
|
|
136
|
+
...getFetchJsonPostParams(`/auth/clients/SOME_CLIENT_ID/challenge`)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
140
|
+
'[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification'
|
|
141
|
+
)
|
|
142
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
143
|
+
'[FLAGSHIP_CERTIFICATION] Something went wrong while requesting a challenge from CozyStack:\nSOME_STACK_CHALLENGE_ERROR'
|
|
144
|
+
)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('should ask challenge to cozy-stack, call the store API and then handle store API failure', async () => {
|
|
148
|
+
const client = getClientMock()
|
|
149
|
+
|
|
150
|
+
const certificationConfig = mockCorrectCertificationConfig()
|
|
151
|
+
|
|
152
|
+
mockCorrectChallengeRequest(client)
|
|
153
|
+
|
|
154
|
+
// Mock errored store API
|
|
155
|
+
getAppAttestationFromStore.mockImplementationOnce(() => {
|
|
156
|
+
throw Error('SOME_STORE_API_ERROR')
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
await certifyFlagship(certificationConfig, client)
|
|
160
|
+
|
|
161
|
+
expect(client.stackClient.fetchJSON).toHaveBeenCalledWith(
|
|
162
|
+
...getFetchJsonPostParams(`/auth/clients/SOME_CLIENT_ID/challenge`)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
expect(getAppAttestationFromStore).toHaveBeenCalledWith('SOME_NONCE', {
|
|
166
|
+
androidSafetyNetApiKey: 'SOME_ANDROID_SAFETY_NET_API_KEY'
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
170
|
+
'[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification'
|
|
171
|
+
)
|
|
172
|
+
expect(logger.warn).toHaveBeenCalledWith('SOME_STORE_API_ERROR')
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
it('should ask challenge to cozy-stack, call the store API, send the result to the stack and then handle cozy-stack certification failure', async () => {
|
|
176
|
+
const client = getClientMock()
|
|
177
|
+
|
|
178
|
+
const certificationConfig = mockCorrectCertificationConfig()
|
|
179
|
+
|
|
180
|
+
mockCorrectChallengeRequest(client)
|
|
181
|
+
|
|
182
|
+
// Mock errored stack certification request
|
|
183
|
+
client.stackClient.fetchJSON.mockImplementationOnce(() => {
|
|
184
|
+
throw Error('SOME_STACK_CERTIFICATION_ERROR')
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
mockCorrectStoreApiRequest()
|
|
188
|
+
|
|
189
|
+
await certifyFlagship(certificationConfig, client)
|
|
190
|
+
|
|
191
|
+
expect(client.stackClient.fetchJSON).toHaveBeenCalledWith(
|
|
192
|
+
...getFetchJsonPostParams(`/auth/clients/SOME_CLIENT_ID/challenge`)
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
expect(getAppAttestationFromStore).toHaveBeenCalledWith('SOME_NONCE', {
|
|
196
|
+
androidSafetyNetApiKey: 'SOME_ANDROID_SAFETY_NET_API_KEY'
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
expect(client.stackClient.fetchJSON).toHaveBeenCalledWith(
|
|
200
|
+
...getFetchJsonPostParams(`/auth/clients/SOME_CLIENT_ID/attestation`, {
|
|
201
|
+
platform: 'android',
|
|
202
|
+
attestation: 'SOME_STORE_ATTESTATION',
|
|
203
|
+
challenge: 'SOME_NONCE',
|
|
204
|
+
keyId: 'SOME_KEY_ID'
|
|
205
|
+
})
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
209
|
+
'[FLAGSHIP_CERTIFICATION] Certification failed but the cozy-stack will continue with 2FA certification'
|
|
210
|
+
)
|
|
211
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
212
|
+
'[FLAGSHIP_CERTIFICATION] Something went wrong while giving attestation to CozyStack:\nSOME_STACK_CERTIFICATION_ERROR'
|
|
213
|
+
)
|
|
214
|
+
})
|
|
215
|
+
})
|
|
@@ -25,7 +25,7 @@ var validateAppMock = /*#__PURE__*/function () {
|
|
|
25
25
|
while (1) {
|
|
26
26
|
switch (_context.prev = _context.next) {
|
|
27
27
|
case 0:
|
|
28
|
-
throw new Error("
|
|
28
|
+
throw new Error("getAppAttestationFromStore can only be called from a React Native container");
|
|
29
29
|
|
|
30
30
|
case 1:
|
|
31
31
|
case "end":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-client",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.18.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.node.js",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"react-native-ios11-devicecheck": "https://github.com/cozy/react-native-devicecheck#app-attest-v0.1"
|
|
72
72
|
},
|
|
73
73
|
"sideEffects": false,
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "df36e3ca46da4adab20629f869296d20942fbc75"
|
|
75
75
|
}
|