@wazo/sdk 0.43.0 → 0.43.2
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/wazo-sdk.js +11 -11
- package/esm/__tests__/api-client.test.js +20 -0
- package/esm/api/auth.js +11 -0
- package/esm/index.js +1 -0
- package/esm/simple/Auth.js +20 -0
- package/esm/simple/__tests__/Auth.test.js +65 -0
- package/esm/simple/index.js +2 -1
- package/esm/types/api/auth.d.ts +1 -0
- package/esm/types/api/auth.d.ts.map +1 -1
- package/esm/types/index.d.ts +1 -0
- package/esm/types/index.d.ts.map +1 -1
- package/esm/types/simple/Auth.d.ts +6 -0
- package/esm/types/simple/Auth.d.ts.map +1 -1
- package/esm/types/simple/index.d.ts +2 -1
- package/esm/types/simple/index.d.ts.map +1 -1
- package/lib/__tests__/api-client.test.js +20 -0
- package/lib/api/auth.js +11 -0
- package/lib/index.js +1 -0
- package/lib/simple/Auth.js +24 -1
- package/lib/simple/__tests__/Auth.test.js +65 -0
- package/lib/simple/index.js +1 -0
- package/lib/types/api/auth.d.ts +1 -0
- package/lib/types/api/auth.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/simple/Auth.d.ts +6 -0
- package/lib/types/simple/Auth.d.ts.map +1 -1
- package/lib/types/simple/index.d.ts +2 -1
- package/lib/types/simple/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/api-client.test.ts +22 -0
- package/src/api/auth.ts +14 -0
- package/src/index.ts +1 -0
- package/src/simple/Auth.ts +22 -0
- package/src/simple/__tests__/Auth.test.ts +91 -0
- package/src/simple/index.ts +2 -1
|
@@ -155,6 +155,28 @@ describe('With correct API results', () => {
|
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
describe('initiateIdpAuthentication', () => {
|
|
159
|
+
it('should make a request to obtain an identity provider URL to redirect to', async () => {
|
|
160
|
+
const domain = 'example.com';
|
|
161
|
+
const redirectUrl = 'https://myapp.xyz';
|
|
162
|
+
|
|
163
|
+
await client.auth.initiateIdpAuthentication(domain, redirectUrl);
|
|
164
|
+
expect(global.fetch).toBeCalledWith(`https://${server}/api/auth/${authVersion}/saml/sso`, {
|
|
165
|
+
method: 'post',
|
|
166
|
+
body: JSON.stringify({
|
|
167
|
+
domain,
|
|
168
|
+
redirect_url: redirectUrl,
|
|
169
|
+
}),
|
|
170
|
+
signal: expect.any(Object),
|
|
171
|
+
headers: {
|
|
172
|
+
'Content-Type': 'application/json',
|
|
173
|
+
Accept: 'application/json',
|
|
174
|
+
},
|
|
175
|
+
agent: null,
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
158
180
|
describe('With unAuthorized API results', () => {
|
|
159
181
|
beforeEach(() => {
|
|
160
182
|
jest.resetModules();
|
package/src/api/auth.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface AuthD {
|
|
|
27
27
|
logIn(params: LoginParams): Promise<Session | null | undefined> ;
|
|
28
28
|
logOut: (token: Token) => Promise<LogoutResponse>;
|
|
29
29
|
samlLogIn: (samlSessionId: string) => Promise<Session | null | undefined>;
|
|
30
|
+
initiateIdpAuthentication(domain: string, redirectUrl: string): Promise<any>;
|
|
30
31
|
refreshToken: (refreshToken: string, backend: string, expiration: number, isMobile?: boolean, tenantId?: string, domainName?: string) => Promise<Session | null | undefined>;
|
|
31
32
|
deleteRefreshToken: (clientId: string) => Promise<boolean>;
|
|
32
33
|
updatePassword: (userUuid: UUID, oldPassword: string, newPassword: string) => Promise<boolean>;
|
|
@@ -116,6 +117,19 @@ export default ((client: ApiRequester, baseUrl: string): AuthD => ({
|
|
|
116
117
|
|
|
117
118
|
return client.post(`${baseUrl}/token`, body).then(Session.parse);
|
|
118
119
|
},
|
|
120
|
+
initiateIdpAuthentication: async (domain: string, redirectUrl: string) => {
|
|
121
|
+
const body = {
|
|
122
|
+
domain,
|
|
123
|
+
redirect_url: redirectUrl,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const headers = {
|
|
127
|
+
Accept: 'application/json',
|
|
128
|
+
'Content-Type': 'application/json',
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return client.post(`${baseUrl}/saml/sso`, body, headers, (response: any) => response);
|
|
132
|
+
},
|
|
119
133
|
refreshToken: (refreshToken: string, backend: string, expiration: number, isMobile?: boolean, tenantId?: string, domainName?: string): Promise<Session | null | undefined> => {
|
|
120
134
|
const body: Record<string, any> = {
|
|
121
135
|
backend: backend || DEFAULT_BACKEND_USER,
|
package/src/index.ts
CHANGED
|
@@ -53,6 +53,7 @@ export { default as ExternalApp } from './domain/ExternalApp';
|
|
|
53
53
|
export { default as SessionDescriptionHandler } from './lib/WazoSessionDescriptionHandler';
|
|
54
54
|
export * from './types/WebSocketMessage';
|
|
55
55
|
export * from './utils/PhoneNumberUtil';
|
|
56
|
+
export * from './utils/string';
|
|
56
57
|
export * from './domain/types';
|
|
57
58
|
|
|
58
59
|
export default Wazo;
|
package/src/simple/Auth.ts
CHANGED
|
@@ -24,6 +24,7 @@ export class InvalidSubscription extends Error {}
|
|
|
24
24
|
export class InvalidAuthorization extends Error {}
|
|
25
25
|
export class NoTenantIdError extends Error {}
|
|
26
26
|
export class NoDomainNameError extends Error {}
|
|
27
|
+
export class NoSamlRouteError extends Error {}
|
|
27
28
|
|
|
28
29
|
const logger = IssueReporter.loggerFor('simple-auth');
|
|
29
30
|
|
|
@@ -165,6 +166,27 @@ export class Auth {
|
|
|
165
166
|
return this._onAuthenticated(rawSession as Session);
|
|
166
167
|
}
|
|
167
168
|
|
|
169
|
+
async initiateIdpAuthentication(domain: string, redirectUrl: string): Promise<{ location: string, saml_session_id: string } | undefined> {
|
|
170
|
+
let response;
|
|
171
|
+
try {
|
|
172
|
+
response = await getApiClient().auth.initiateIdpAuthentication(domain, redirectUrl);
|
|
173
|
+
} catch (e: any) {
|
|
174
|
+
logger.error('Error during IdP authentication initiation:', e.message);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
if (response.status === 404) {
|
|
180
|
+
throw new NoSamlRouteError('No route found for saml sso');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const error = await response.json();
|
|
184
|
+
throw new Error(error.message || error.reason);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return response.json();
|
|
188
|
+
}
|
|
189
|
+
|
|
168
190
|
async logInViaRefreshToken(refreshToken: string): Promise<Session | null> {
|
|
169
191
|
const rawSession = await getApiClient().auth.refreshToken(refreshToken, '', this.expiration, this.mobile);
|
|
170
192
|
return this._onAuthenticated(rawSession as Session);
|
|
@@ -120,4 +120,95 @@ describe('simple/Auth', () => {
|
|
|
120
120
|
expect(Auth.onSetUsingEdgeServer).toHaveBeenCalledWith(false);
|
|
121
121
|
});
|
|
122
122
|
});
|
|
123
|
+
|
|
124
|
+
describe('initiateIdpAuthentication', () => {
|
|
125
|
+
const validResponse = { location: 'idp.com/auth', saml_session_id: 'a1b2C3d4' };
|
|
126
|
+
|
|
127
|
+
it('should return a `location` and `saml_session_id` if the response is ok', async () => {
|
|
128
|
+
const initiateIdpAuthentication = jest.fn(() =>
|
|
129
|
+
Promise.resolve({
|
|
130
|
+
ok: true,
|
|
131
|
+
status: 303,
|
|
132
|
+
json: () => Promise.resolve(validResponse),
|
|
133
|
+
}));
|
|
134
|
+
|
|
135
|
+
(getApiClient as any).mockImplementation(() => ({
|
|
136
|
+
auth: {
|
|
137
|
+
initiateIdpAuthentication,
|
|
138
|
+
},
|
|
139
|
+
}));
|
|
140
|
+
|
|
141
|
+
const response = await Auth.initiateIdpAuthentication('example.com', 'https://myapp.xyz');
|
|
142
|
+
expect(response).toBe(validResponse);
|
|
143
|
+
});
|
|
144
|
+
it('should return a `NoSamlRouteError` if the response is a 404', async () => {
|
|
145
|
+
const initiateIdpAuthentication = jest.fn(() =>
|
|
146
|
+
Promise.resolve({
|
|
147
|
+
ok: false,
|
|
148
|
+
status: 404,
|
|
149
|
+
}));
|
|
150
|
+
|
|
151
|
+
(getApiClient as any).mockImplementation(() => ({
|
|
152
|
+
auth: {
|
|
153
|
+
initiateIdpAuthentication,
|
|
154
|
+
},
|
|
155
|
+
}));
|
|
156
|
+
|
|
157
|
+
await expect(Auth.initiateIdpAuthentication('example.com', 'https://myapp.xyz')).rejects.toThrow(
|
|
158
|
+
'No route found for saml sso',
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should return an error `message` if the response is NOT ok', async () => {
|
|
163
|
+
const initiateIdpAuthentication = jest.fn(() =>
|
|
164
|
+
Promise.resolve({
|
|
165
|
+
ok: false,
|
|
166
|
+
json: () => Promise.resolve({ message: 'an error message', reason: 'an error reason' }),
|
|
167
|
+
}));
|
|
168
|
+
|
|
169
|
+
(getApiClient as any).mockImplementation(() => ({
|
|
170
|
+
auth: {
|
|
171
|
+
initiateIdpAuthentication,
|
|
172
|
+
},
|
|
173
|
+
}));
|
|
174
|
+
|
|
175
|
+
await expect(Auth.initiateIdpAuthentication('example.com', 'https://myapp.xyz')).rejects.toThrow(
|
|
176
|
+
'an error message',
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should return an error `reason` if there is no `message` and the response is NOT ok', async () => {
|
|
181
|
+
const initiateIdpAuthentication = jest.fn(() =>
|
|
182
|
+
Promise.resolve({
|
|
183
|
+
ok: false,
|
|
184
|
+
json: () => Promise.resolve({ reason: 'an error reason' }),
|
|
185
|
+
}));
|
|
186
|
+
|
|
187
|
+
(getApiClient as any).mockImplementation(() => ({
|
|
188
|
+
auth: {
|
|
189
|
+
initiateIdpAuthentication,
|
|
190
|
+
},
|
|
191
|
+
}));
|
|
192
|
+
|
|
193
|
+
await expect(Auth.initiateIdpAuthentication('example.com', 'https://myapp.xyz')).rejects.toThrow(
|
|
194
|
+
'an error reason',
|
|
195
|
+
);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should return an error with a null message if there is no `message` and `reason`', async () => {
|
|
199
|
+
const initiateIdpAuthentication = jest.fn(() =>
|
|
200
|
+
Promise.resolve({
|
|
201
|
+
ok: false,
|
|
202
|
+
json: () => Promise.resolve({}),
|
|
203
|
+
}));
|
|
204
|
+
|
|
205
|
+
(getApiClient as any).mockImplementation(() => ({
|
|
206
|
+
auth: {
|
|
207
|
+
initiateIdpAuthentication,
|
|
208
|
+
},
|
|
209
|
+
}));
|
|
210
|
+
|
|
211
|
+
await expect(Auth.initiateIdpAuthentication('example.com', 'https://myapp.xyz')).rejects.toThrow('');
|
|
212
|
+
});
|
|
213
|
+
});
|
|
123
214
|
});
|
package/src/simple/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable import/no-named-as-default */
|
|
2
2
|
/* global window */
|
|
3
|
-
import Auth, { InvalidSubscription, InvalidAuthorization, NoTenantIdError, NoDomainNameError } from './Auth';
|
|
3
|
+
import Auth, { InvalidSubscription, InvalidAuthorization, NoTenantIdError, NoDomainNameError, NoSamlRouteError } from './Auth';
|
|
4
4
|
import Phone from './Phone';
|
|
5
5
|
import Websocket from './Websocket';
|
|
6
6
|
import Room from './room/Room';
|
|
@@ -138,6 +138,7 @@ const Wazo = {
|
|
|
138
138
|
SFUNotAvailableError,
|
|
139
139
|
NoTenantIdError,
|
|
140
140
|
NoDomainNameError,
|
|
141
|
+
NoSamlRouteError,
|
|
141
142
|
};
|
|
142
143
|
|
|
143
144
|
if (typeof window !== 'undefined') {
|