@datenkraft/meetingroom-js-api-client
v1.0.21
Published
API client to consume the Meeting Room API
Downloads
20
Readme
Meetingroom API Client - Javascript/Typescript
Usage
Compiled JS sources are available inside the ./dist folder with the matching typescript definition files.
Example
// in this example we use a runtime storage object for the data the api client needs to persist.
// in a browser setting this could be stored in localStorage.
let storage: StorageData = {};
const configParams: ApiClientConfigurationParameters = {
// basePath: "https://api.meetingroom.datenkraft.cloud:30100/api/v1", // optional, the production server will be used if omitted
// fetchApi: window.fetch.bind(window), // node-fetch is used by default, but any other Fetch compatible implementation like window.fetch can be passed
storagePersistence: {
save(data: StorageData) {
// implement some logic to persist the needed data
// if necessary, use i.e. JSON.stringify(data) to convert to a string
storage = data;
},
load(): StorageData {
// implement logic to return the previously saved StorageData object
// if necessary, use return JSON.parse(storage) to convert back from a string
return storage;
}
}
};
// configuration
const apiClientConfiguration = new ApiClientConfiguration(configParams);
// the API is split into logical groups of endpoints (e.g. Calendar, Accounts, Buildings, ...)
// those service objects should only be created via the ApiClientFactory
const apiClientFactory = new ApiClientFactory(apiClientConfiguration);
// to reuse the API service objects, a repository is provided
const apiClientRepository = new ApiClientRepository(apiClientFactory);
(async () => {
try {
// to follow the authentication flow of the Meetingroom API, a helper is provided.
// this is only needed if no apiKey was previously stored or 401/403 errors occur.
// details are in the README.md under "Details about the authentication workflow".
const redirectUrl = "https://localhost:30000/consent";
const authHelper = new ApiClientAuthorizationHelper(apiClientRepository.get(AccountsApi), redirectUrl);
// step 1 - get the url to the consent screen the user should be redirected to
const consentScreenUrl = await authHelper.generateConsentScreenUrl();
// step 2 - let the helper handle the callback url coming back from the consent screen
// urls look might look like this: https://localhost:30000/consent?code=4/0AY0e-asdfasdfasdf&scope=https://www.googleapis.com/auth/calendar
await authHelper.handleConsentScreenCallback(new URL("https://localhost:30000/consent?code=4/0AY0e-asdfasdfasdf&scope=https://www.googleapis.com/auth/calendar"))
// if successful, the client has retrieved the apiKey and persisted it via the provided storagePersistence implementation in the configParams above
// authenticated endpoints may now be reached
// the apiKey can be accessed by apiClientRepository.get(AccountsApi).storage.apiKey
// some example calls
const calendarsApi = apiClientRepository.get(CalendarsApi);
const responseAllCalendars = await apiClientRepository.get(CalendarsApi).getCalendars({filterType: GetCalendarsFilterTypeEnum.Resource});
const responseCalendarEvents = await calendarsApi.getEventsByCalendarId({
calendarId: "[email protected]",
filterStartTime: new Date("2021-01-29 14:10:00 GMT+1"),
filterEndTime: new Date("2021-01-29 22:10:00 GMT+1")
});
const responseCreate = await calendarsApi.createEvent({
calendarId: "[email protected]",
createEventRequest: {
calendarId: "[email protected]",
startTime: new Date("2021-01-29 20:10:00 GMT+1"),
endTime: new Date("2021-01-29 20:15:30 GMT+1"),
title: "TestEvent MR ApiClient"
}
});
} catch (e) {
// if the client received a response from the api backend which is not in the 200 http status range, the Fetch response object is thrown.
}
})();
Development
Start the docker container
This will also execute npm install
.
docker-compose up
Enter into an interactive shell to execute node/npm commands
docker exec -it meetingroom-js-api-client sh
Generate the client files
(Because Openapi Generator is used, this command requires the Java interpreter (tested with OpenJDK8). If not run inside the docker container, java needs to be available in the PATH.)
npm run generate
Build the dist
directory.
npm run build
Build alternative: Start the tsc compiler in watch mode.
npm run watch-build
Publish the package
Before publishing the package, please ensure that:
- You are logged to an account wth the required permissions (
npm login
) - You have updated the version in
package.json
correctly
npm publish --access public
The npm commands can be run with docker-compose exec node npm ...
as well.
Details about the authentication workflow
- Frontend client calls /api/v1/accounts/authlink with "redirectUrl" in the JSON request body.
- Backend contacts Google API to generate the Google auth link and returns it to the the frontend via "authLink" in the JSON response body. The backend defines via this url which permissions (= scopes) it requires.
- Frontend clients redirects to the received auth link to a Google sign in/account chooser page.
- User selects their account and accepts that our application may access the requested resources.
- Google redirects the user back to the "redirectUrl" generated by the frontend client, appended with an "code" GET parameter.
- The frontend client passes this auth code to the backend /api/v1/accounts/access_token via "authCode" in the JSON request body.
- The backend validates this auth code via the Google API which generates an accessToken. This accessToken is base64 encoded and returned to the frontend client via "accessToken" in the JSON response body.
- The frontend stores the "accessToken" and passes it with every subsequent call to protected endpoints via the "X-Google-AccessToken" HTTP header.
- The backend validates the given "accessToken" and returns the appropriate response. Should the accessToken expire, the backend returns inside the "meta" field in the JSON response body the new accessToken, generated via the available refresh token. This refresh token is returned by the Google API when trading in the authCode for the Google AccessToken.