Skip to content

Commit

Permalink
[main] add withCredentials config (#2373)
Browse files Browse the repository at this point in the history
  • Loading branch information
siyuniu-ms committed Jul 12, 2024
1 parent c80706d commit 8d6686c
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 5 deletions.
17 changes: 17 additions & 0 deletions channels/1ds-post-js/src/DataModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,23 @@ export interface IChannelConfiguration {
* @since 4.1.0
*/
excludeCsMetaData?: boolean;

/**
* [Optional] Specify whether cross-site Access-Control fetch requests should include credentials such as cookies,
* authentication headers, or TLS client certificates.
*
* Possible values:
* - "omit": never send credentials in the request or include credentials in the response.
* - "include": always include credentials, even cross-origin.
* - "same-origin": only send and include credentials for same-origin requests.
*
* If not set, the default value will be "include".
*
* For more information, refer to:
* - [Fetch API - Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials)
* @since 3.3.1
*/
fetchCredentials?: RequestCredentials;
}

/**
Expand Down
9 changes: 7 additions & 2 deletions channels/1ds-post-js/src/HttpManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export class HttpManager {
let _timeoutWrapper: ITimeoutOverrideWrapper;
let _excludeCsMetaData: boolean;
let _sendPostMgr: SenderPostManager;
let _fetchCredentials: RequestCredentials;

dynamicProto(HttpManager, this, (_self) => {
_initDefaults();
Expand Down Expand Up @@ -238,7 +239,9 @@ export class HttpManager {
if (!isNullOrUndefined(channelConfig.useSendBeacon)) {
_useBeacons = !!channelConfig.useSendBeacon;
}

if (channelConfig.fetchCredentials){
_fetchCredentials= channelConfig.fetchCredentials;
}
let sendPostConfig = _getSendPostMgrConfig();
// only init it once
if (!_sendPostMgr) {
Expand Down Expand Up @@ -411,7 +414,7 @@ export class HttpManager {
}

_self["_getDbgPlgTargets"] = () => {
return [_sendInterfaces[EventSendType.Batched], _killSwitch, _serializer, _sendInterfaces];
return [_sendInterfaces[EventSendType.Batched], _killSwitch, _serializer, _sendInterfaces, _getSendPostMgrConfig()];
};

function _getSendPostMgrConfig(): _ISendPostMgrConfig {
Expand All @@ -422,10 +425,12 @@ export class HttpManager {
xhrOnComplete: _xhrOnComplete,
beaconOnRetry: _onBeaconRetry
} as _ISenderOnComplete;

let config = {
enableSendPromise: false,
isOneDs: true,
disableCredentials: !_sendCredentials,
fetchCredentials: _fetchCredentials,
disableXhr: false,
disableBeacon: !_useBeacons,
disableBeaconSync: !_useBeacons,
Expand Down
1 change: 1 addition & 0 deletions channels/1ds-post-js/src/PostChannel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const defaultPostChannelConfig: IConfigDefaults<IChannelConfiguration> = objDeep
stringifyObjects: undefValue,
enableCompoundKey: undefValue,
disableOptimizeObj: false,
fetchCredentials: undefValue,
// disableCacheHeader: undefValue, // See Task #7178858 - Collector requires a change to support this
transports: undefValue,
unloadTransports: undefValue,
Expand Down
17 changes: 17 additions & 0 deletions channels/1ds-post-js/test/Unit/src/HttpManagerTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,23 @@ export class HttpManagerTest extends AITestClass {
}
});

this.testCase({
name: "Fetch Credentials config could be set from post channel and pass into sendPostManager",
useFakeTimers: true,
test: () => {
var manager: HttpManager = new HttpManager(500, 2, 1, {
requeue: _requeueNotification,
send: _sendNotification,
sent: _sentNotification,
drop: _dropNotification
});
this.core.config.extensionConfig![this.postManager.identifier].fetchCredentials = "omit";
this.core.config.endpointUrl = "testEndpoint";
this.core.config.extensionConfig![this.postManager.identifier].alwaysUseXhrOverride = false;
manager.initialize(this.core.config, this.core, this.postManager);
QUnit.assert.equal(manager["_getDbgPlgTargets"]()[4].fetchCredentials, "omit", "Fetch credentials should be set to omit");
}
});
this.testCase({
name: "Validate synchronous event with zero response - Default Send Type (Synchronous)",
useFakeTimers: true,
Expand Down
26 changes: 26 additions & 0 deletions channels/1ds-post-js/test/Unit/src/PostChannelTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export class PostChannelTest extends AITestClass {
xhrTimeout: undefValue,
disableXhrSync: undefValue,
alwaysUseXhrOverride: false,
fetchCredentials: undefValue,
maxEventRetryAttempts: 6,
maxUnloadEventRetryAttempts: 2,
addNoResponse: undefValue,
Expand Down Expand Up @@ -197,6 +198,31 @@ export class PostChannelTest extends AITestClass {
}
});


this.testCase({
name: "Fetch Credentials config default to be null, and support dynamic change",
useFakeTimers: true,
test: () => {
let config = this.config;
let core = this.core;
let postChannel = this.postChannel;
core.initialize(config, [postChannel]);
let actaulConfig = postChannel["_getDbgPlgTargets"]()[1];
QUnit.assert.deepEqual(actaulConfig["fetchCredentials"], undefined, "fetchCredentials was undefined if not set");
let httpManager = postChannel["_getDbgPlgTargets"]()[0];
QUnit.assert.deepEqual(httpManager["_getDbgPlgTargets"]()[4].fetchCredentials, undefined, "fetchCredentials was undefined if not set");
if (core.config.extensionConfig){
core.config.extensionConfig[postChannel.identifier].fetchCredentials = "omit";
}
this.clock.tick(1);
actaulConfig = postChannel["_getDbgPlgTargets"]()[1];
QUnit.assert.deepEqual(actaulConfig["fetchCredentials"], "omit", "post channel fetchCredentials was set to omit");
httpManager = postChannel["_getDbgPlgTargets"]()[0];
console.log("get", JSON.stringify(httpManager["_getDbgPlgTargets"]()[4]));
QUnit.assert.deepEqual(httpManager["_getDbgPlgTargets"]()[4].fetchCredentials, "omit", "http manager fetchCredentials was set to omit");
}
});

this.testCase({
name: "Post Channel: dynamic config changes",
useFakeTimers: true,
Expand Down
10 changes: 8 additions & 2 deletions channels/offline-channel-js/src/Sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class Sender {
let _isOneDs: boolean;
let _sendPostMgr: SenderPostManager;
let _disableCredentials: boolean;
let _fetchCredentials: RequestCredentials;


dynamicProto(Sender, this, (_self, _base) => {
Expand Down Expand Up @@ -83,14 +84,18 @@ export class Sender {
utlSetStoragePrefix(config.storagePrefix);
}
let ctx = createProcessTelemetryContext(null, config, core);

let offlineCfg = ctx.getExtCfg(DefaultOfflineIdentifier) as IOfflineChannelConfiguration;
_onlineChannelId = channelId || BreezeChannelIdentifier;
let senderConfig = ctx.getExtCfg(_onlineChannelId, {}) as any;
let offlineSenderCfg = offlineCfg.senderCfg || {} as IOfflineSenderConfig;

_fetchCredentials = null;
if (_onlineChannelId == PostChannelId) {
_isOneDs = true;
let channelConfig = ctx.getExtCfg(PostChannelId);
if (channelConfig && channelConfig["fetchCredentials"]) {
_fetchCredentials = channelConfig["fetchCredentials"];
}
}

_alwaysUseCustomSend = offlineSenderCfg.alwaysUseXhrOverride;
Expand Down Expand Up @@ -163,6 +168,7 @@ export class Sender {
enableSendPromise: _enableSendPromise,
isOneDs: _isOneDs,
disableCredentials: _disableCredentials,
fetchCredentials: _fetchCredentials,
senderOnCompleteCallBack: _getOnCompleteFuncs()
} as _ISendPostMgrConfig;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,23 @@ export interface _ISendPostMgrConfig {
*/
addNoResponse?: boolean;

/**
* [Optional] Specify whether cross-site Access-Control fetch requests should include credentials such as cookies,
* authentication headers, or TLS client certificates.
*
* Possible values:
* - "omit": never send credentials in the request or include credentials in the response.
* - "include": always include credentials, even cross-origin.
* - "same-origin": only send and include credentials for same-origin requests.
*
* If not set, the default value will be "include".
*
* For more information, refer to:
* - [Fetch API - Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#including_credentials)
* @since version after 3.3.1
*/
fetchCredentials?: RequestCredentials;

}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export class SenderPostManager {
let _isOneDs: boolean;
let _onCompleteFuncs: _ISenderOnComplete;
let _disableCredentials: boolean;
let _fetchCredentials: RequestCredentials;
let _fallbackInst: IXHROverride;
let _disableXhr: boolean;
let _disableBeacon: boolean;
Expand Down Expand Up @@ -83,6 +84,7 @@ export class SenderPostManager {
try {
_onCompleteFuncs = config.senderOnCompleteCallBack || {};
_disableCredentials = !!config.disableCredentials;
_fetchCredentials = config.fetchCredentials;
_isOneDs = !!config.isOneDs;
_enableSendPromise = !!config.enableSendPromise;
_disableXhr = !! config.disableXhr;
Expand Down Expand Up @@ -379,7 +381,9 @@ export class SenderPostManager {
}


if (_sendCredentials && _isOneDs) {
if (_fetchCredentials) { // if user passed in this value via post channel (1ds), then use it
init.credentials = _fetchCredentials;
} else if (_sendCredentials && _isOneDs) {
// for 1ds, Don't send credentials when URL is file://
init.credentials = "include";
}
Expand Down Expand Up @@ -607,6 +611,7 @@ export class SenderPostManager {
_isOneDs = null;
_onCompleteFuncs = null;
_disableCredentials = null;
_fetchCredentials = null;
_fallbackInst = null;
_disableXhr = false;
_disableBeacon = false;
Expand Down

0 comments on commit 8d6686c

Please sign in to comment.