Skip to content

Commit 4c4d036

Browse files
feat(providers): add NetSuite OAuth Provider (#8865)
Co-authored-by: Nico Domino <[email protected]>
1 parent 73c4dac commit 4c4d036

File tree

4 files changed

+454
-0
lines changed

4 files changed

+454
-0
lines changed

.github/ISSUE_TEMPLATE/2_bug_provider.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ body:
6363
- "Medium"
6464
- "Naver"
6565
- "Netlify"
66+
- "NetSuite"
6667
- "Notion"
6768
- "Okta"
6869
- "OneLogin"
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
import { Callout } from "nextra/components"
2+
import { Code } from "@/components/Code"
3+
4+
<img align="right" src="/img/providers/netsuite.svg" height="64" width="64" />
5+
6+
# NetSuite
7+
8+
## Resources
9+
10+
- [NetSuite - Creating an Integration Record (OAuth 2.0)](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157771733782.html#Related-Topics)
11+
- [NetSuite - Authorizing OAuth Requests](https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps)
12+
- [NetSuite - Configure OAuth Roles](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157771510070.html#Set-Up-OAuth-2.0-Roles)
13+
- [Learn more about NetSuite OAuth 2.0](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_157769826287.html#OAuth-2.0)
14+
15+
## Setup
16+
17+
### Callback URL
18+
19+
<Callout>
20+
NetSuite does not support http. When testing locally, you can use a service
21+
like [ngrok](https://ngrok.com) to get a local https URL.
22+
</Callout>
23+
24+
<Code>
25+
<Code.Next>
26+
27+
```bash
28+
https://example.com/api/auth/callback/netsuite
29+
```
30+
31+
</Code.Next>
32+
<Code.Svelte>
33+
34+
```bash
35+
https://example.com/auth/callback/netsuite
36+
```
37+
38+
</Code.Svelte>
39+
</Code>
40+
41+
### Userinfo RESTlet
42+
43+
Our `userinfo` URL needs to be a suitelet or RESTLet URL that gives us the
44+
information about the user. The best bet is to use the `N/runtime` module to
45+
get the basics first. - Here is an example of a RESTlet below. Be sure to
46+
deploy and enable access to "All Roles".
47+
48+
### Example RESTLet Callback Handler
49+
50+
Be sure to deploy and use the **external** RESTLet url of any usage of the URIs.
51+
52+
```js
53+
/**
54+
* @NApiVersion 2.1
55+
* @NScriptType Restlet
56+
*/
57+
define(["N/runtime"],
58+
@param{runtime} runtimee
59+
(runtime) => {
60+
/**
61+
* Defines the function that is executed when a GET request is sent to a RESTlet.
62+
* @param {Object} requestParams - Parameters from HTTP request URL; parameters passed as an Object (for all supported
63+
* content types)
64+
* @returns {string | Object} HTTP response body; returns a string when request Content-Type is 'text/plain'; returns an
65+
* Object when request Content-Type is 'application/json' or 'application/xml'
66+
* @since 2015.2
67+
*\/
68+
const get = (requestParams) => {
69+
let userObject = runtime.getCurrentUser();
70+
71+
try {
72+
log.debug({ title: "Payload received:", details: requestParams });
73+
74+
const { id, name, role, location, email, contact } = userObject;
75+
76+
log.audit({ title: "Current User Ran", details: name });
77+
78+
let user = {
79+
id,
80+
name,
81+
role,
82+
location,
83+
email,
84+
contact,
85+
};
86+
87+
log.debug({ title: "Returning user", details: user });
88+
89+
return JSON.stringify(user);
90+
} catch (e) {
91+
log.error({ title: "Error grabbing current user:", details: e });
92+
}
93+
};
94+
95+
return {
96+
get,
97+
};
98+
);
99+
```
100+
101+
Above is an example of returning the basic runtime information. Be sure to create a new script record and deployment record. When you save the deployment record, you will get the URLs for your RESTlet, which we will use as the `userinfo` URL.
102+
103+
### Environment Variables
104+
105+
```
106+
AUTH_NETSUITE_ID
107+
AUTH_NETSUITE_SECRET
108+
```
109+
110+
### Configuration
111+
112+
Before setting up the provider, you will need to ensure the following is setup.
113+
114+
- [Create an Integration Record](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157771733782.html#procedure_157838925981)
115+
- Uncheck the TBA Auth Flow checkbox.
116+
- Check OAuth 2.0 Auth Flow checkbox.
117+
- Copy and paste the `Callback URL` below into the `Redirect URI` field.
118+
- Then select the scope(s) you want to use.
119+
- **REST Web Services** (`rest_webservices`) - Access to REST Web Services.
120+
- **RESTlets**(`restlets`) - Access to RESTLets.
121+
- **SuiteAnalytics Connect** (`suiteanalytics_connect`) - Access to SuiteAnalytics Connect.
122+
- Add any policies you want to use.
123+
- Application Logo (_Optional_) (Shown to users when they are asked to grant access to your application). - Consent Screen
124+
- Application Terms of Use (_Optional_) - A PDF file that contains the terms of use for your application. - Consent Screen
125+
- Application Privacy Policy (_Optional_) - A PDF file that contains the privacy policy for your application. - Consent Screen
126+
- OAuth 2.0 Consent Policy Preference - This setting determines whether the user is asked to grant access to your application **every time** they sign in or only the **first time** they sign in or **never**.
127+
- **Save** the Integration record.
128+
- The Integration record will be used to generate the `clientId` and `clientSecret` for the provider. **Save the generated values for later**
129+
130+
<Code>
131+
<Code.Next>
132+
133+
```ts filename="/auth.ts"
134+
import NextAuth from "next-auth"
135+
import NetSuite from "next-auth/providers/netsuite"
136+
137+
export const { handlers, auth, signIn, signOut } = NextAuth({
138+
providers: [
139+
NetSuite({
140+
clientId: AUTH_NETSUITE_ID,
141+
clientSecret: AUTH_NETSUITE_SECRET,
142+
issuer: AUTH_NETSUITE_ACCOUNT_ID, // EX: TSTDRV1234567 or 81555 for prod, and 1234567-SB1 for Sandbox accounts not "_" use "-".
143+
// Returns the current user using the N/runtime module. This url can be a suitelet or RESTlet (Recommended)
144+
// Using getCurrentUser(); So we match this schema returned from this RESTlet in the profile callback. (Required)
145+
userinfo:
146+
"https://1234567.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=123&deploy=1",
147+
// Optional
148+
prompt: "login", // Required if you want to force the user to login every time.
149+
scope: "restlets", // Optional defaults to "restlets rest_webservices". Enter the scope(s) you want to use followed by spaces.
150+
}),
151+
],
152+
})
153+
```
154+
155+
</Code.Next>
156+
<Code.Svelte>
157+
158+
```ts filename="/src/auth.ts"
159+
import { SvelteKitAuth } from "@auth/sveltekit"
160+
import NetSuite from "@auth/sveltekit/providers/netsuite"
161+
162+
export const { handle, signIn, signOut } = SvelteKitAuth({
163+
providers: [
164+
NetSuite({
165+
clientId: AUTH_NETSUITE_ID,
166+
clientSecret: AUTH_NETSUITE_SECRET,
167+
issuer: AUTH_NETSUITE_ACCOUNT_ID, // EX: TSTDRV1234567 or 81555 for prod, and 1234567-SB1 for Sandbox accounts not "_" use "-".
168+
// Returns the current user using the N/runtime module. This url can be a suitelet or RESTlet (Recommended)
169+
// Using getCurrentUser(); So we match this schema returned from this RESTlet in the profile callback. (Required)
170+
userinfo:
171+
"https://1234567.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=123&deploy=1",
172+
// Optional
173+
prompt: "login", // Required if you want to force the user to login every time.
174+
scope: "restlets", // Optional defaults to "restlets rest_webservices". Enter the scope(s) you want to use followed by spaces.
175+
}),
176+
],
177+
})
178+
```
179+
180+
</Code.Svelte>
181+
<Code.Express>
182+
183+
```ts filename="/src/app.ts"
184+
import { ExpressAuth } from "@auth/express"
185+
import NetSuite from "@auth/express/providers/netsuite"
186+
187+
app.use(
188+
"/auth/*",
189+
ExpressAuth({
190+
providers: [
191+
NetSuite({
192+
clientId: AUTH_NETSUITE_ID,
193+
clientSecret: AUTH_NETSUITE_SECRET,
194+
issuer: AUTH_NETSUITE_ACCOUNT_ID, // EX: TSTDRV1234567 or 81555 for prod, and 1234567-SB1 for Sandbox accounts not "_" use "-".
195+
// Returns the current user using the N/runtime module. This url can be a suitelet or RESTlet (Recommended)
196+
// Using getCurrentUser(); So we match this schema returned from this RESTlet in the profile callback. (Required)
197+
userinfo:
198+
"https://1234567.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=123&deploy=1",
199+
// Optional
200+
prompt: "login", // Required if you want to force the user to login every time.
201+
scope: "restlets", // Optional defaults to "restlets rest_webservices". Enter the scope(s) you want to use followed by spaces.
202+
}),
203+
],
204+
})
205+
)
206+
```
207+
208+
</Code.Express>
209+
</Code>
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)