Configure authentication for the Scheduler Editor Component
The Scheduler Editor Component uses the Hosted authentication details in nylasSessionsConfig
to interact with the Nylas APIs. Instead of using nylasSessionsConfig
, you can use nylasApiRequest
property in the either of the following situations:
- You're already using Nylas Hosted auth in your application.
- You want to use Custom auth or a different HTTP client library for authentication.
Download Nylas identity package
To use nylasApiRequest
, you first need to download the Nylas identity package:
npm i @nylas/identity@latest
Use existing Nylas Hosted authentication
If you're already using Nylas Hosted auth in your application, you can use nylasApiRequest
with NylasIdentityRequestWrapper
.
✨ You can also check the complete code in GitHub.
<html class="h-full bg-white" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nylas Scheduler Editor with auth using NylasIdentityRequestWrapper</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
rel="stylesheet"
/>
<style type="text/css">
body {
font-family: "Inter", sans-serif;
}
</style>
</head>
<body class="h-full">
<div class="grid h-full place-items-center">
<!-- Add the Nylas Scheduler Editor component -->
<nylas-scheduler-editor />
</div>
<!-- Configure the Nylas Scheduler Editor component -->
<script type="module">
import { defineCustomElement } from "https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/cdn/nylas-scheduler-editor/nylas-scheduler-editor.es.js";
import { NylasSessions } from 'https://cdn.jsdelivr.net/npm/@nylas/identity@latest/dist/nylas-identity.es.js';
import { NylasIdentityRequestWrapper } from 'https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/esm/index.js';
defineCustomElement();
// Specify settings for Nylas identity management
const config = {
clientId: '<NYLAS_CLIENT_ID>',
redirectUri: `${window.location.origin}/login`,
domain: 'https://api.us.nylas.com/v3', // or 'https://api.eu.nylas.com/v3' for th E.U. region
hosted: false,
accessType: "offline",
};
const identity = new NylasSessions(config);
async function checkLoggedIn() {
const loggedIn = await identity.isLoggedIn();
return loggedIn;
}
// Create a new nylasApiRequest instance
const nylasApiRequest = new NylasIdentityRequestWrapper(identity);
// Specify Scheduler Editor Component details
const schedulerEditor = document.querySelector("nylas-scheduler-editor");
schedulerEditor.nylasApiRequest = nylasApiRequest;
schedulerEditor.schedulerPreviewLink = `${window.location.origin}/?config_id={config.id}`;
schedulerEditor.eventOverrides = {
// The default behavior of the close button is to log out the user, so redirect to the login page
schedulerConfigCloseClicked: async (e) => {
setTimeout(async () => {
window.location.href = `${window.location.origin}/login`;
}, 3000);
},
}
schedulerEditor.defaultSchedulerConfigState = {
selectedConfiguration: {
requires_session_auth: false, // Create a public configuration which doesn't require a session
},
};
// Redirect to the login page if the user is not logged in
checkLoggedIn().then((loggedIn) => {
if (!loggedIn) {
window.location.href = `${window.location.origin}/login`;
}
});
</script>
</body>
</html>
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { NylasSchedulerEditor, NylasScheduling } from "@nylas/react";
import LoginComp from '@nylas/login-component';
import "./App.css";
import { NylasSessions } from '@nylas/identity';
import { NylasIdentityRequestWrapper } from '@nylas/react';
function App() {
// Get the configuration ID from the URL query string
const urlParams = new URLSearchParams(window.location.search);
const clientId = '<NYLAS_APP_CLIENT_ID>';
const configId = urlParams.get("config_id") || "";
const componentSettings = {
// Adjust the scopes as needed
authSettings: {
scopes: {
google: [
'openid',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/contacts',
'https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/directory.readonly',
],
microsoft: ['Calendars.ReadWrite', 'Mail.ReadWrite', 'Contacts.ReadWrite', 'User.Read', 'offline_access'],
},
},
};
const identitySettings = {
clientId: clientId,
redirectUri: `${window.location.origin}/nylas-auth/scheduler-editor`,
domain: 'https://api.us.nylas.com/v3', // or 'https://api.eu.nylas.com/v3' for the E.U. data region
hosted: true,
accessType: 'offline',
};
const identity = new NylasSessions(identitySettings);
const nylasApiRequest = new NylasIdentityRequestWrapper(identity);
return (
<BrowserRouter>
<Routes>
<Route path="/meet" element={
<div>
<a href="/scheduler-editor" className="button">View Scheduler Editor</a>
<NylasScheduling
configurationId={configId}
schedulerApiUrl="https://api.us.nylas.com" // or 'https://api.eu.nylas.com' for the E.U. data region
/>
</div>
} />
<Route path="/login" element={
<div>
<LoginComp
clientId={clientId}
redirectUri={`${window.location.origin}/nylas-auth/scheduler-editor`}
config={componentSettings}
identity={identity} popup={false} hosted={false} />
</div>
} />
<Route path="/nylas-auth/scheduler-editor" element={
<div>
<NylasSchedulerEditor
schedulerPreviewLink={`${window.location.origin}/meet?config_id={config.id}`}
nylasApiRequest={nylasApiRequest}
defaultSchedulerConfigState={{
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
}
}}
/>
</div>
} />
</Routes>
</BrowserRouter>
);
}
export default App;
Use Custom authentication
If you want to use Custom auth or a different HTTP client library for authentication, you can define a custom wrapper (CustomIdentityRequestWrapper
) which implements nylasApiRequest
, and set the nylasApiRequest
property with CustomIdentityRequestWrapper
.
The Scheduler Editor Component and CustomIdentityRequestWrapper
require an access token from the same origin. To get the access token:
- Add a callback URI.
- Make an authorization request to retrieve a code.
- Exchange the code for an access token.
Add a callback URI
- In your Nylas application, click Hosted Authentication in the left navigation, and click Callback URIs.
- Click Add a callback URI.
- Select the JavaScript platform.
- For URL, enter
https://127.0.0.1:3000/scheduler-editor
.
This assumes you host the Scheduler Editor onlocalhost:3000
. The URL will vary based on your hosting choice. - For Origin, enter
https://127.0.0.1:3000
. - Click Add callback URI.
Make an authorization request
Make a GET /v3/connect/auth
request to retrieve an authorization code
that you can exchange for an access token.
/v3/connect/auth?
client_id=<NYLAS_CLIENT_ID>
&redirect_uri=https://127.0.0.1:3000/scheduler-editor
&response_type=code
&provider=google
&access_type=offline
Exchange the code for an access token
Using the code
from your authorization request, make a POST /v3/connect/token
request to get the access token.
curl --request POST \
--url 'https://api.us.nylas.com/v3/connect/token' \
--header 'Content-Type: application/json' \
--header 'Origin: 'https://127.0.0.1:3000' \
--data '{
"code": "<AUTHORIZATION_CODE>",
"client_id": "<NYLAS_CLIENT_ID>",
"client_secret": "<NYLAS_API_KEY>",
"redirect_uri": "https://127.0.0.1:3000/scheduler-editor",
"grant_type": "authorization_code"
}'
You can then use the access token in CustomIdentityRequestWrapper
and the Scheduler Editor Component. Make sure that CustomIdentityRequestWrapper
has a currentUser
function that returns the same email address that is associated with the access token.
Example: CustomIdentityRequestWrapper
and the Scheduler Editor Component
✨ You can also check the complete code in GitHub.
export class CustomIdentityRequestWrapper {
private accessToken: string;
constructor(accessToken: string) {
// Initialize the class
this.accessToken = accessToken;
}
async request<T = any>(args: any): Promise<T> {
try {
const response = await fetch(`https://api.us.nylas.com/v3/grants/me/${args.path}`, {
method: args.method,
body: JSON.stringify(args.body),
headers: {
...args.headers,
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
});
// Check if the response is not okay (e.g., 404, 500)
if (!response.ok) {
console.error(`Error: ${response.status} ${response.statusText}`);
return { error: `Error: ${response.status} ${response.statusText}` } as any;
}
// Parse the response
const data = await response.json();
return [data, null] as any;
} catch (error) {
console.error('Fetch error:', error);
return { error: "Error" } as any;
}
}
/**
* This method returns the current user's information.
*/
async currentUser() {
// IMPLEMENT: Get the logged in user's ID token and return the user information. For example,
return {
id: 'idToken.sub',
email: 'j.doe@example.com',
name: 'John Doe',
provider: 'google',
};
}
/**
* This method sets the default authentication arguments to use when authenticating the user.
*/
async setDefaultAuthArgs(authArgs: any) {
// Set the default authentication arguments
return authArgs;
};
/**
* This method returns the URL to redirect the user to for authentication.
*/
async authenticationUrl(): Promise<string | undefined> {
// IMPLEMENT: Return the URL to redirect the user to for authentication. For example,
return 'https://example.com/auth';
}
}
<html class="h-full bg-white" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Nylas Scheduler Editor Component</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
rel="stylesheet"
/>
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/css">
body {
font-family: "Inter", sans-serif;
}
</style>
</head>
<body class="h-full">
<div class="grid h-full place-items-center">
<!-- Add the Nylas Scheduler Editor component -->
<nylas-scheduler-editor />
</div>
<!-- Configure the Nylas Scheduler Editor component -->
<script type="module">
import { defineCustomElement } from "https://cdn.jsdelivr.net/npm/@nylas/web-elements@latest/dist/cdn/nylas-scheduler-editor/nylas-scheduler-editor.es.js";
import { CustomIdentityRequestWrapper } from './custom.js';
defineCustomElement();
const schedulerEditor = document.querySelector("nylas-scheduler-editor");
schedulerEditor.schedulerPreviewLink = `${window.location.origin}/?config_id={config.id}`;
const accessToken = 'NYLAS_ACCESS_TOKEN';
const domain ='https://api.us.nylas.com/v3'; // or 'https://api.eu.nylas.com/v3' for th E.U. region
// Create an instance of the CustomIdentityRequestWrapper class defined above
const nylasApiRequest = new CustomIdentityRequestWrapper(accessToken, domain);
schedulerEditor.nylasApiRequest = nylasApiRequest
schedulerEditor.defaultSchedulerConfigState = {
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
},
};
</script>
</body>
</html>
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { NylasSchedulerEditor, NylasScheduling } from "@nylas/react";
import { CustomIdentityRequestWrapper } from './custom';
import "./App.css";
function App() {
const accessToken = 'NYLAS_ACCESS_TOKEN';
const domain ='https://api.us.nylas.com/v3'; // or 'https://api.eu.nylas.com/v3' for the E.U. region
// Get the configuration ID from the URL query string
const urlParams = new URLSearchParams(window.location.search);
const configId = urlParams.get("config_id") || "";
const nylasApiRequest = new CustomIdentityRequestWrapper(accessToken, domain);
return (
<BrowserRouter>
<Routes>
<Route path="/meet" element={
<div>
<a href="/scheduler-editor" className="button">View Scheduler Editor</a>
<NylasScheduling
configurationId={configId}
schedulerApiUrl="https://api.us.nylas.com" // or 'https://api.eu.nylas.com' for the E.U. region
/>
</div>
} />
<Route path="/custom-auth/scheduler-editor" element={
<div>
<NylasSchedulerEditor
schedulerPreviewLink={`${window.location.origin}/meet?config_id={config.id}`}
nylasApiRequest={nylasApiRequest}
defaultSchedulerConfigState={{
selectedConfiguration: {
requires_session_auth: false, // Creates a public configuration which doesn't require a session
}
}}
/>
</div>
} />
</Routes>
</BrowserRouter>
);
}
export default App;