Skip to main content

OAuth

Registering your app

OAuth requires for developers to register their apps with Neurosity. To register you app, please email support@neurosity.co.

During the registration process, you'll be asked to specify which scopes you'll like to have access to.

Example Project

The quickest way to implement OAuth is to fork the example project.

OAuth Scopes

The following individual scopes will allow your app to access certain Neurosity resources.

ScopeDescription
read:accelerometerLive Accelerometer
write:brainwave-markersAdd Brainwave Markers
read:brainwavesLive Brainwaves
write:brainwavesRecord Brainwaves
read:memories:brainwavesRead Brainwave Datasets
read:calmLive Calm
read:memories:calmHistorical Calm
read:focusLive Focus
read:memories:focusHistorical Focus
read:devices-infoLive Device(s) Info
write:hapticsActivate Haptics
read:kinesisLive Kinesis
write:kinesisCreate Kinesis Trainings
read:devices-settingsRead Device(s) Settings
read:signal-qualityLive Signal Quality
read:statusLive Device(s) Status

Only request scopes that you inted to use in your app.

Redirect URIs

Another part of the registration process involves specifying one or more reidrect URIs. The Redirect URI(s) validate the URI the OAuth workflow will use to redirect back to your app after the user has granted or denied OAuth access.

Some examples:

https://yourwebapp.com/
http://localhost:3000

Implement Cloud Functions

Implementing OAuth requires two server-side (node.js) enpoints to be implemented. Make sure you have the following environment variables available at runtime for both cloud functions.

NEUROSITY_OAUTH_CLIENT_ID=<your client id>
NEUROSITY_OAUTH_CLIENT_SECRET=<your client secret>
NEUROSITY_OAUTH_CLIENT_REDIRECT_URI=http://localhost:3000

First Cloud Function: createOAuthURL

The first function wraps the createOAuthURL SDK method. This method creates client-specific OAuth URL. This is the first step of the OAuth workflow. Use this function to create a URL you can use to redirect users to the Neurosity sign-in page.

The following cloud function example was designed to work with Netlify. Let's name this function get-neurosity-oauth-url.

const { Neurosity } = require("@neurosity/sdk");

const neurosity = new Neurosity({
autoSelectDevice: false
});

exports.handler = async function (event) {
return neurosity
.createOAuthURL({
clientId: process.env.NEUROSITY_OAUTH_CLIENT_ID,
clientSecret: process.env.NEUROSITY_OAUTH_CLIENT_SECRET,
redirectUri: process.env.NEUROSITY_OAUTH_CLIENT_REDIRECT_URI,
responseType: "token",
state: Math.random().toString().split(".")[1], // A random string is required for security reasons
scope: [
"read:devices-info",
"read:devices-status",
"read:signal-quality",
"read:brainwaves"
]
})
.then((url) => ({
statusCode: 200,
body: JSON.stringify({ url })
}))
.catch((error) => ({
statusCode: 400,
body: JSON.stringify(error.response.data)
}));
};

Second Cloud Function: getOAuthToken

The getOAuthToken method retreives the client-specific OAuth token for a given userId.

Here's an example of a cloud function that receives a userId via query params and loads the client id and client secret securely via environment variables.

Let's name this function get-neurosity-custom-token.

const { Neurosity } = require("@neurosity/sdk");

const neurosity = new Neurosity({
autoSelectDevice: false
});

exports.handler = async function (event) {
const userId = event.queryStringParameters?.userId;

return neurosity
.getOAuthToken({
clientId: process.env.NEUROSITY_OAUTH_CLIENT_ID,
clientSecret: process.env.NEUROSITY_OAUTH_CLIENT_SECRET,
userId
})
.then((token) => ({
statusCode: 200,
body: JSON.stringify(token)
}))
.catch((error) => ({
statusCode: 200,
body: JSON.stringify(error.response.data)
}));
};

Integrate to your User Interface

Now that your app is registered and the 2 cloud functions are implemented, the last step is to integrate OAuth to your user interface. In this section, the code examples will be using React.

Add "Connect Neurosity Account" Component

import React from "react";

export function ConnectNeurosityAccountButton() {
function connectNeurosityAccount() {
fetch(`/functions/get-neurosity-oauth-url`)
.then(({ data }) => {
if ("url" in data) {
// Takes the url returned by the cloud function and redirects the browser to the Neurosity OAuth sign-in page
window.location.href = data.url;
} else {
console.error(`Error: Did not receive url`);
}
})
.catch((error) => {
console.error(error.message);
});
}

return (
<button onClick={connectNeurosityAccount}>Connect Neurosity Account</button>
);
}

Manage the Auth state

We'll import and create a new instance of the Neurosity SDK. Then, add a hook for Neurosity auth state management.

import { Neurosity } from "@neurosity/sdk";
import { useState, useEffect } from "react";

const neurosity = new Neurosity({
autoSelectDevice: false
});

const initialState = {
loading: true,
user: null,
error: null
};

export function useNeurosity() {
const [state, setState] = useState(initialState);
const { customToken } = useOAuthResult();

// Fires everytime an uth session starts or ends
useEffect(() => {
const subscription = neurosity.onAuthStateChanged().subscribe((user) => {
setState((prevState) => ({
...prevState,
loading: false,
user
}));
});

return () => {
subscription.unsubscribe();
};
}, []);

// Calls the Neurosity login with the custom token received via url parameter
useEffect(() => {
if (customToken) {
neurosity.login({ customToken }).catch((error) => {
setState((prevState) => ({
...prevState,
error: error?.message
}));
});
}
}, [customToken]);

return state;
}

function useOAuthResult() {
const paramsString = window.location.hash.replace("#", "");

return {
state: searchParams.get("state"),
error: searchParams.get("error"),
customToken: searchParams.get("access_token")
};
}

Removing Access

After a user has granted your app access to their Neurosity account, it is good practice to give them the option to remove the access. For that, we'll use the SDK removeOAuthAccess method on the client or server side.

The following example removes client-specific OAuth token for a given userId. This method requires the SDK to be signed in with OAuth custom token.

import React from "react";

export function RemoveNeurosityAccessButton() {
async function removeNeurosityAccess() {
await neurosity.removeOAuthAccess().catch((error) => {
// handle error here...
});
}

return <button onClick={removeNeurosityAccess}>Remove Access</button>;
}

Authenticating the Neurosity App

It is possible to authenticate the Neurosity mobile app with an OAuth token. To do this, simply add a deep link navigation to your mobile app containing using the following URI scheme:

neurosity://oauth/YOUR_OAUTH_TOKEN_HERE