Skip to content

Commit

Permalink
Merge pull request #769 from wazo-platform/saml-support
Browse files Browse the repository at this point in the history
[WDA-2366] [WDA-2367] SAML support
  • Loading branch information
bogue authored May 28, 2024
2 parents 605e29e + 64deb55 commit a84340a
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 21 deletions.
53 changes: 32 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ Wazo's Javascript SDK allows you to use these features :
+ [Authentication with the simple API](#authentication-with-the-simple-api)
- [Initializing](#initializing)
- [Setting the engine host](#setting-the-engine-host)
- [Authenticating an user](#authenticating-an-user)
- [Authenticating a user](#authenticating-a-user)
- [Authenticating a user with SAML](#authenticating-a-user-with-SAML)
- [Validating a token](#validating-a-token)
- [Setting a callback when a new token is refreshed](#setting-a-callback-when-a-new-token-is-refreshed)
- [Loggin out](#loggin-out)
- [Logging out](#logging-out)
+ [Conference](#conference)
- [Joining a room](#joining-a-room)
- [Sending a chat message in the room](#sending-a-chat-message-in-the-room)
Expand All @@ -51,7 +52,7 @@ Wazo's Javascript SDK allows you to use these features :
- [Merging sessions in one conference](#merging-sessions-in-one-conference)
- [Add a session to a conference](#add-a-call-to-a-conference)
- [Remove a session from a conference](#remove-a-call-from-a-conference)
- [Unmerge a sessions from a conference](#terminating-a-conference)
- [Terminating a conference](#terminating-a-conference)
+ [Accessing the current WebRtc phone](#accessing-the-current-webrtc-phone)
+ [Domains](#domains)
- [Participant](#participant)
Expand Down Expand Up @@ -87,7 +88,7 @@ Wazo's Javascript SDK allows you to use these features :
- [WebRTCClient Configuration](#webrtcclient-configuration)
- [Basic client features](#basic-client-features)
- [Calling a number](#calling-a-number)
- [Be notified to a phone call](#be-notified-to-a-phone-call)
- [Be notified of a phone call](#be-notified-of-a-phone-call)
- [Answering a call](#answering-a-call)
- [Hangup a call](#hangup-a-call)
- [Rejecting a call](#rejecting-a-call)
Expand Down Expand Up @@ -138,7 +139,7 @@ Wazo's Javascript SDK allows you to use these features :
- [Sending a SIP message](#sending-a-sip-message)
- [Closing the phone](#closing-the-phone)
- [Starting heartbeat](#starting-heartbeat)
- [Stopping heatbeat](#stopping-heatbeat)
- [Stopping heartbeat](#stopping-heartbeat)
+ [WebSocketClient](#wazo-websocket)
- [Web Socket features](#web-socket-features)
- [Opening the socket](#opening-the-socket)
Expand Down Expand Up @@ -223,7 +224,7 @@ Wazo.Auth.fetchOptions({
- `options`: Object
- Options passed to all the `fetch` requests of the SDK.

### Authenticating an user
#### Authenticating a user
```js
const session = await Wazo.Auth.logIn(username, password, backend, tenantId);
```
Expand All @@ -244,6 +245,16 @@ Returns as `Wazo.domain.Session`. This object contains, among other information,

Note: you need to set `clientId` in your WazoAPIClient in order to get a refresh token in the returned `Session`.

#### Authenticating a user with SAML
```js
const session = await Wazo.Auth.samlLogIn(samlSessionId);
```

- `samlSessionId`: string
- samlSessionId generated by wazo-auth

Returns as `Wazo.domain.Session`. This object contains, among other information, the user's token.

#### Validating a token

```js
Expand Down Expand Up @@ -272,7 +283,7 @@ Wazo.Auth.setOnRefreshToken(token => { /* Do something with the new token */ });
- `callback`: Function(token: string)
- A function that is triggered when the user's token will soon expire.

#### Loggin out
#### Logging out

Destroys user's token and refreshToken.

Expand Down Expand Up @@ -427,11 +438,11 @@ Triggered when screensharing is stopped.
room.on(room.ON_TALKING, (channel, participant) => {});
```

Triggered when a participant is talking, or stops talking.
Triggered when a participant is talking or stops talking.

- `channel`: Object containing information about the event.
- `participant`: `Wazo.RemoteParticipant` or `Wazo.LocalParticipant`.
The participant instance, your can access the `participant.isTalking` attribute to know the status.
The participant instance, you can access the `participant.isTalking` attribute to know the status.

### Ad hoc Conference features
**`Voice`** **`Video`**
Expand All @@ -456,7 +467,7 @@ adHocConference.removeParticipant(callSession: CallSession);
```

#### Terminating a conference
Use this method to remove a single participant from a conference.
Use this method to terminate a conference.
```js
adHocConference.hangup();
```
Expand Down Expand Up @@ -579,11 +590,11 @@ Triggered when the participant is sharing his screen.
participant.on(participant.ON_STOP_SCREENSHARING, () => {});
```

Triggered when the participant stop sharing his screen.
Triggered when the participant stops sharing his screen.

#### Stream

`Wazo.Stream` helps attaching or detaching streams to html elements:
`Wazo.Stream` helps attach or detach streams to HTML elements:

`stream.attach(htmlEmelent)`

Expand Down Expand Up @@ -704,7 +715,7 @@ client.setOnRefreshToken((newToken, newSession) => {
});
```

Note: you need to set `clientId` in your WazoAPIClient in order to refresh token.
Note: you need to set `clientId` in your WazoAPIClient to refresh a token.

#### Log Out
**`Voice`** **`Video`** **`Chat`** **`Fax`** **`Status`** **`Config`** **`Misc`**
Expand Down Expand Up @@ -741,7 +752,7 @@ client.auth.createPolicy(name, description, acl);
client.auth.listPolicies();
```

### Sending logs to fluentd via a http endpoint
### Sending logs to fluentd via a HTTP endpoint

#### Logger
**`Log`**
Expand Down Expand Up @@ -793,7 +804,7 @@ client.application.playCall(applicationUuid, callId, language, uri); // play a s
**`Voice`** **`Video`** **`Chat`** **`Fax`** **`Status`**

Use Calld to directly control interactions.
(Please note, ctidNg endpoint is deprecated but continue to work with old version. **Please update your code**.)
(Please note, ctidNg endpoint is deprecated but continues to work with old versions. **Please update your code**.)

```js
client.calld.getConferenceParticipantsAsUser(conferenceId); // List participants of a conference the user is part of
Expand Down Expand Up @@ -996,7 +1007,7 @@ Use this method to dial a number.
client.call(number: string);
```
##### Be notified to a phone call
##### Be notified of a phone call
Use this method to be notified of an incoming call.
```js
client.on('invite', (sipSession: SipSession) => {
Expand Down Expand Up @@ -1390,14 +1401,14 @@ See webrtcClient's `heartbeatDelay`, `heartbeatTimeout`, `maxHeartbeats`, [confi
phone.startHeartbeat();
```
##### Stopping heatbeat
##### Stopping heartbeat
```js
phone.stopHeartbeat();
```
### Wazo WebSocket
You can use the Wazo WebSocket to listen for real time events (eg: receiving a chat message, a presential update ...)
You can use the Wazo WebSocket to listen for real-time events (eg: receiving a chat message, a presential update...)
#### Web Socket features
**`Voice`** **`Video`** **`Chat`** **`Fax`** **`Status`**
Expand Down Expand Up @@ -1451,15 +1462,15 @@ ws.close();
```
# Usage with webpack 5
# Usage with Webpack 5
As webpack 5 dropped some polyfill, you have to add them:
As Webpack 5 dropped some polyfills, you have to add them manually:
```sh
yarn add -D assert buffer https-browserify url stream-http stream-browserify browserify-zlib process
```
If you have used `create-react-app` to create your app, you can customize the webpack configuration with `react-app-rewired` :
If you have used `create-react-app` to create your app, you can customize the Webpack configuration with `react-app-rewired` :
```sh
yarn add -D react-app-rewired
Expand Down
21 changes: 21 additions & 0 deletions src/__tests__/api-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,27 @@ describe('With correct API results', () => {
});
});

describe('samlLogIn test', () => {
it('should retrieve user token', async () => {
const samlSessionId = 'a1b2C3d4';
const result = await client.auth.samlLogIn(samlSessionId);

expect(result).toBeInstanceOf(Session);
expect(result?.token).toBe(1);
expect(global.fetch).toBeCalledWith(`https://${server}/api/auth/${authVersion}/token`, {
method: 'post',
body: JSON.stringify({ saml_session_id: samlSessionId }),
signal: expect.any(Object),
headers: {
'X-Auth-Token': token,
'Content-Type': 'application/json',
Accept: 'application/json',
},
agent: null,
});
});
});

describe('logOut test', () => {
it('should delete the specified token', async () => {
const oldToken = 123;
Expand Down
8 changes: 8 additions & 0 deletions src/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface AuthD {
authenticate: (token: Token) => Promise<Session | null | undefined>;
logIn(params: LoginParams): Promise<Session | null | undefined> ;
logOut: (token: Token) => Promise<LogoutResponse>;
samlLogIn: (samlSessionId: string) => Promise<Session | null | undefined>;
refreshToken: (refreshToken: string, backend: string, expiration: number, isMobile?: boolean, tenantId?: string, domainName?: string) => Promise<Session | null | undefined>;
deleteRefreshToken: (clientId: string) => Promise<boolean>;
updatePassword: (userUuid: UUID, oldPassword: string, newPassword: string) => Promise<boolean>;
Expand Down Expand Up @@ -108,6 +109,13 @@ export default ((client: ApiRequester, baseUrl: string): AuthD => ({
},

logOut: (token: Token): Promise<LogoutResponse> => client.delete(`${baseUrl}/token/${token}`, null, {}, ApiRequester.successResponseParser),
samlLogIn: async (samlSessionId: string): Promise<Session | null | undefined> => {
const body = {
saml_session_id: samlSessionId,
};

return client.post(`${baseUrl}/token`, body).then(Session.parse);
},
refreshToken: (refreshToken: string, backend: string, expiration: number, isMobile?: boolean, tenantId?: string, domainName?: string): Promise<Session | null | undefined> => {
const body: Record<string, any> = {
backend: backend || DEFAULT_BACKEND_USER,
Expand Down
5 changes: 5 additions & 0 deletions src/simple/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ export class Auth {
return this._onAuthenticated(rawSession as Session);
}

async samlLogIn(samlSessionId: string): Promise<Session | null> {
const rawSession = await getApiClient().auth.samlLogIn(samlSessionId);
return this._onAuthenticated(rawSession as Session);
}

async logInViaRefreshToken(refreshToken: string): Promise<Session | null> {
const rawSession = await getApiClient().auth.refreshToken(refreshToken, '', this.expiration, this.mobile);
return this._onAuthenticated(rawSession as Session);
Expand Down

0 comments on commit a84340a

Please sign in to comment.