abap-local-client 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/basic-auth.mjs CHANGED
@@ -46,7 +46,7 @@ export class BasicSession {
46
46
  'Authorization': `Basic ${this._basicAuth}`,
47
47
  },
48
48
  httpsAgent: new https.Agent({
49
- rejectUnauthorized: opts.rejectUnauthorized === true, // default false, like old client
49
+ rejectUnauthorized: opts.rejectUnauthorized !== undefined ? opts.rejectUnauthorized : false,
50
50
  keepAlive: true,
51
51
  }),
52
52
  });
@@ -144,30 +144,30 @@ export class BasicSession {
144
144
  });
145
145
  }
146
146
 
147
- /** POST request (auto-injects CSRF token). */
147
+ /** POST request. */
148
148
  async post(path, data, extraHeaders = {}) {
149
- if (!this.csrfToken) await this.refreshCsrf();
149
+ const contentType = (data !== null && typeof data === 'object' && !extraHeaders['Content-Type'] && !extraHeaders['content-type'])
150
+ ? 'application/json' : 'application/xml';
150
151
  return this._client({
151
152
  method: 'POST',
152
153
  url: path,
153
154
  headers: this._headers(path, {
154
- 'Content-Type': 'application/xml',
155
- 'X-CSRF-Token': this.csrfToken,
155
+ 'Content-Type': contentType,
156
156
  ...extraHeaders,
157
157
  }),
158
158
  data,
159
159
  });
160
160
  }
161
161
 
162
- /** PUT request (auto-injects CSRF token). */
162
+ /** PUT request. */
163
163
  async put(path, data, extraHeaders = {}) {
164
- if (!this.csrfToken) await this.refreshCsrf();
164
+ const contentType = (data !== null && typeof data === 'object' && !extraHeaders['Content-Type'] && !extraHeaders['content-type'])
165
+ ? 'application/json' : 'application/xml';
165
166
  return this._client({
166
167
  method: 'PUT',
167
168
  url: path,
168
169
  headers: this._headers(path, {
169
- 'Content-Type': 'application/xml',
170
- 'X-CSRF-Token': this.csrfToken,
170
+ 'Content-Type': contentType,
171
171
  ...extraHeaders,
172
172
  }),
173
173
  data,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abap-local-client",
3
- "version": "1.3.1",
3
+ "version": "1.4.1",
4
4
  "description": "SAP Local Client — WebSocket bridge with Basic, SPNEGO, X.509, SAML & SNC authentication",
5
5
  "main": "sso-sap-client.mjs",
6
6
  "type": "module",
package/sap-rfc-client.js CHANGED
@@ -677,15 +677,47 @@ export class SAPRFCClient {
677
677
  }
678
678
 
679
679
  /** Fetch a fresh CSRF token via GET /sap/bc/adt/discovery */
680
- async fetchCsrfToken() {
680
+ async fetchCsrfToken(httpSession) {
681
681
  console.log('[RFC] Fetching CSRF token...');
682
- const resp = await this.callADT('GET', '/sap/bc/adt/discovery', {
683
- 'X-CSRF-Token': 'Fetch',
684
- 'Accept': 'application/atomsvc+xml',
685
- }, null);
686
- if (resp.headers['x-csrf-token']) {
687
- this.csrfToken = resp.headers['x-csrf-token'];
688
- console.log(`[RFC] CSRF token: ${this.csrfToken.substring(0, 15)}...`);
682
+
683
+ if (httpSession && httpSession.csrfToken) {
684
+ this.csrfToken = httpSession.csrfToken;
685
+ console.log(`[RFC] CSRF token from existing HTTP session: ${this.csrfToken.substring(0, 15)}...`);
686
+ return;
687
+ }
688
+
689
+ if (httpSession && typeof httpSession.get === 'function') {
690
+ try {
691
+ const resp = await httpSession.get('/sap/bc/adt/discovery', {
692
+ 'X-CSRF-Token': 'Fetch',
693
+ 'Accept': 'application/atomsvc+xml',
694
+ });
695
+ if (resp.headers?.['x-csrf-token']) {
696
+ this.csrfToken = resp.headers['x-csrf-token'];
697
+ httpSession.csrfToken = this.csrfToken;
698
+ console.log(`[RFC] CSRF token via HTTP session: ${this.csrfToken.substring(0, 15)}...`);
699
+ return;
700
+ }
701
+ } catch (e) {
702
+ console.log(`[RFC] HTTP session CSRF fetch failed: ${e.message}, falling back to RFC`);
703
+ }
704
+ }
705
+
706
+ console.log('[RFC] Attempting CSRF fetch via RFC callADT...');
707
+ try {
708
+ const resp = await this.callADT('GET', '/sap/bc/adt/discovery', {
709
+ 'X-CSRF-Token': 'Fetch',
710
+ 'Accept': 'application/atomsvc+xml',
711
+ }, null);
712
+ console.log(`[RFC] callADT response: status=${resp.status}, headers=${JSON.stringify(resp.headers)}`);
713
+ if (resp.headers['x-csrf-token']) {
714
+ this.csrfToken = resp.headers['x-csrf-token'];
715
+ console.log(`[RFC] CSRF token: ${this.csrfToken.substring(0, 15)}...`);
716
+ } else {
717
+ console.log('[RFC] No x-csrf-token in response headers!');
718
+ }
719
+ } catch (e) {
720
+ console.log(`[RFC] callADT CSRF fetch failed: ${e.message}`);
689
721
  }
690
722
  }
691
723