netsuiteoauth2
v3.0.0
Published
An easy-to-use OAuth2 authentication for NetSuite.
Maintainers
Readme
NetSuite OAuth2
A small, zero-dependency Node.js library for NetSuite's OAuth 2.0 Authorization Code Grant with PKCE. It gets, refreshes and revokes tokens for RESTlets, REST Web Services and SuiteAnalytics Connect.
It never opens a browser or starts a server: it builds URLs and calls NetSuite's token endpoints. You handle the redirect, so it works the same in a web app, a CLI, a server or CI.
npm install netsuiteoauth2How it works
1. getAuthorizationUrl() → url, codeVerifier, state
2. User logs in at `url` → NetSuite redirects to redirectUrl?code=…&state=…&company=…
3. exchangeAuthorizationCode() → access_token + refresh_token
4. refreshAccessToken() → new access_token when the old one expires
5. revokeRefreshToken() → invalidate the refresh tokenAccess tokens are short-lived (about 60 min). The refresh token lasts much longer, so you authorize once, store the refresh token, and get new access tokens from it as needed.
Setup
Create an integration record in NetSuite with Authorization Code Grant enabled, then:
import { NSOAuth2, Scope, OAuth2TokenDTO } from 'netsuiteoauth2';
const client = new NSOAuth2({
clientId: process.env.NS_CLIENT_ID!,
clientSecret: process.env.NS_CLIENT_SECRET!,
redirectUrl: 'https://example.com/callback', // must match the integration record
scopes: [Scope.RESTLETS, Scope.REST_WEB_SERVICES], // also: Scope.SUITE_ANALYTICS_CONNECT
accountId: '1234567', // optional, see below
});accountId is optional. If you set it, users log in at that account's URL. If you leave it out, they log in at
system.netsuite.com and choose an account. The account they choose comes back as the company query param.
Usage
Authorize (once per user/account)
// Build the login URL and keep codeVerifier and state (for example, in the session).
const { url, codeVerifier, state } = client.getAuthorizationUrl();
// Redirect the user to `url`.
// In your redirectUrl handler, reject the request if req.query.state !== state, then:
const token: OAuth2TokenDTO = await client.exchangeAuthorizationCode(company, code, codeVerifier);Refresh
// From a stored refresh token (for example, a CI secret). No user interaction.
const token = await client.accessTokenFromRefreshToken(accountId, refreshToken);
// Or renew an existing token. This updates it in place and returns it.
await client.refreshAccessToken(token);Call NetSuite
fetch(`https://${token.account}.suitetalk.api.netsuite.com/services/rest/record/v1/customer/1`, {
headers: { Authorization: `Bearer ${token.access_token}` },
});Revoke
await client.revokeRefreshToken(token);Token
| Field | Description |
|-----------------|-------------------------------------------|
| account | NetSuite account id |
| access_token | Bearer token for API calls |
| refresh_token | Used to get new access tokens |
| expires_in | Access token lifetime, in seconds |
| issued_at | When the token was issued (ms since epoch) |
To check whether a token has expired: Date.now() > issued_at + expires_in * 1000.
Security
Keep clientSecret and refresh tokens out of source control. Use environment variables or a secrets manager.
