11import { type NextRequest , NextResponse } from 'next/server'
22import { getSession } from '@/lib/auth'
3- import { env } from '@/lib/core/config/env'
43import { getBaseUrl } from '@/lib/core/utils/urls'
54import { createLogger } from '@/lib/logs/console/logger'
65
@@ -38,17 +37,13 @@ export async function GET(request: NextRequest) {
3837 return NextResponse . json ( { error : 'Unauthorized' } , { status : 401 } )
3938 }
4039
41- const clientId = env . SERVICENOW_CLIENT_ID
42-
43- if ( ! clientId ) {
44- logger . error ( 'SERVICENOW_CLIENT_ID not configured' )
45- return NextResponse . json ( { error : 'ServiceNow client ID not configured' } , { status : 500 } )
46- }
47-
4840 const instanceUrl = request . nextUrl . searchParams . get ( 'instanceUrl' )
41+ const clientId = request . nextUrl . searchParams . get ( 'clientId' )
42+ const clientSecret = request . nextUrl . searchParams . get ( 'clientSecret' )
4943 const returnUrl = request . nextUrl . searchParams . get ( 'returnUrl' )
5044
51- if ( ! instanceUrl ) {
45+ // If any required parameter is missing, show the form
46+ if ( ! instanceUrl || ! clientId || ! clientSecret ) {
5247 const returnUrlParam = returnUrl ? encodeURIComponent ( returnUrl ) : ''
5348 return new NextResponse (
5449 `<!DOCTYPE html>
@@ -63,9 +58,11 @@ export async function GET(request: NextRequest) {
6358 display: flex;
6459 align-items: center;
6560 justify-content: center;
66- height: 100vh;
61+ min- height: 100vh;
6762 margin: 0;
6863 background: linear-gradient(135deg, #81B5A1 0%, #5A8A75 100%);
64+ padding: 20px;
65+ box-sizing: border-box;
6966 }
7067 .container {
7168 background: white;
@@ -74,7 +71,7 @@ export async function GET(request: NextRequest) {
7471 box-shadow: 0 10px 40px rgba(0,0,0,0.1);
7572 text-align: center;
7673 max-width: 450px;
77- width: 90 %;
74+ width: 100 %;
7875 }
7976 h2 {
8077 color: #111827;
@@ -84,13 +81,23 @@ export async function GET(request: NextRequest) {
8481 color: #6b7280;
8582 margin: 0 0 1.5rem 0;
8683 }
84+ .form-group {
85+ text-align: left;
86+ margin-bottom: 1rem;
87+ }
88+ label {
89+ display: block;
90+ font-size: 0.875rem;
91+ font-weight: 500;
92+ color: #374151;
93+ margin-bottom: 0.25rem;
94+ }
8795 input {
8896 width: 100%;
8997 padding: 0.75rem;
9098 border: 1px solid #d1d5db;
9199 border-radius: 8px;
92100 font-size: 1rem;
93- margin-bottom: 1rem;
94101 box-sizing: border-box;
95102 }
96103 input:focus {
@@ -108,14 +115,15 @@ export async function GET(request: NextRequest) {
108115 font-size: 1rem;
109116 cursor: pointer;
110117 font-weight: 500;
118+ margin-top: 0.5rem;
111119 }
112120 button:hover {
113121 background: #6A9A87;
114122 }
115123 .help {
116- font-size: 0.875rem ;
124+ font-size: 0.75rem ;
117125 color: #9ca3af;
118- margin-top: 1rem ;
126+ margin-top: 0.25rem ;
119127 }
120128 .error {
121129 color: #dc2626;
@@ -128,18 +136,41 @@ export async function GET(request: NextRequest) {
128136 <body>
129137 <div class="container">
130138 <h2>Connect Your ServiceNow Instance</h2>
131- <p>Enter your ServiceNow instance URL to continue</p>
139+ <p>Enter your ServiceNow credentials to continue</p>
132140 <div id="error" class="error"></div>
133141 <form onsubmit="handleSubmit(event)">
134- <input
135- type="text"
136- id="instanceUrl"
137- placeholder="https://mycompany.service-now.com"
138- required
139- />
142+ <div class="form-group">
143+ <label for="instanceUrl">Instance URL</label>
144+ <input
145+ type="text"
146+ id="instanceUrl"
147+ placeholder="https://mycompany.service-now.com"
148+ required
149+ />
150+ <p class="help">Your ServiceNow instance URL (e.g., https://yourcompany.service-now.com)</p>
151+ </div>
152+ <div class="form-group">
153+ <label for="clientId">Client ID</label>
154+ <input
155+ type="text"
156+ id="clientId"
157+ placeholder="Enter your OAuth Client ID"
158+ required
159+ />
160+ <p class="help">OAuth Client ID from your ServiceNow Application Registry</p>
161+ </div>
162+ <div class="form-group">
163+ <label for="clientSecret">Client Secret</label>
164+ <input
165+ type="password"
166+ id="clientSecret"
167+ placeholder="Enter your OAuth Client Secret"
168+ required
169+ />
170+ <p class="help">OAuth Client Secret from your ServiceNow Application Registry</p>
171+ </div>
140172 <button type="submit">Connect Instance</button>
141173 </form>
142- <p class="help">Your instance URL looks like: https://yourcompany.service-now.com</p>
143174 </div>
144175
145176 <script>
@@ -148,6 +179,8 @@ export async function GET(request: NextRequest) {
148179 e.preventDefault();
149180 const errorEl = document.getElementById('error');
150181 let instanceUrl = document.getElementById('instanceUrl').value.trim();
182+ const clientId = document.getElementById('clientId').value.trim();
183+ const clientSecret = document.getElementById('clientSecret').value.trim();
151184
152185 // Ensure https:// prefix
153186 if (!instanceUrl.startsWith('https://') && !instanceUrl.startsWith('http://')) {
@@ -170,7 +203,21 @@ export async function GET(request: NextRequest) {
170203 return;
171204 }
172205
206+ if (!clientId) {
207+ errorEl.textContent = 'Please enter your Client ID';
208+ errorEl.style.display = 'block';
209+ return;
210+ }
211+
212+ if (!clientSecret) {
213+ errorEl.textContent = 'Please enter your Client Secret';
214+ errorEl.style.display = 'block';
215+ return;
216+ }
217+
173218 let url = window.location.pathname + '?instanceUrl=' + encodeURIComponent(instanceUrl);
219+ url += '&clientId=' + encodeURIComponent(clientId);
220+ url += '&clientSecret=' + encodeURIComponent(clientSecret);
174221 if (returnUrl) {
175222 url += '&returnUrl=' + returnUrl;
176223 }
@@ -229,7 +276,7 @@ export async function GET(request: NextRequest) {
229276
230277 const response = NextResponse . redirect ( oauthUrl )
231278
232- // Store state and instance URL in cookies for validation in callback
279+ // Store state, instance URL, and credentials in cookies for validation in callback
233280 response . cookies . set ( 'servicenow_oauth_state' , state , {
234281 httpOnly : true ,
235282 secure : process . env . NODE_ENV === 'production' ,
@@ -246,6 +293,23 @@ export async function GET(request: NextRequest) {
246293 path : '/' ,
247294 } )
248295
296+ // Store client credentials in cookies for the callback to use
297+ response . cookies . set ( 'servicenow_client_id' , clientId , {
298+ httpOnly : true ,
299+ secure : process . env . NODE_ENV === 'production' ,
300+ sameSite : 'lax' ,
301+ maxAge : 60 * 10 ,
302+ path : '/' ,
303+ } )
304+
305+ response . cookies . set ( 'servicenow_client_secret' , clientSecret , {
306+ httpOnly : true ,
307+ secure : process . env . NODE_ENV === 'production' ,
308+ sameSite : 'lax' ,
309+ maxAge : 60 * 10 ,
310+ path : '/' ,
311+ } )
312+
249313 if ( returnUrl ) {
250314 response . cookies . set ( 'servicenow_return_url' , returnUrl , {
251315 httpOnly : true ,
0 commit comments