@experteam-mx/ngx-services 20.10.4 → 20.10.5-dev1.0

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.
@@ -5225,6 +5225,10 @@ class ApiServicesService {
5225
5225
  return this.http.post(`${this.url}/adyen/aborts`, body)
5226
5226
  .pipe(map(({ data }) => data));
5227
5227
  }
5228
+ postAdyenRefunds(body) {
5229
+ return this.http.post(`${this.url}/adyen/refunds`, body)
5230
+ .pipe(map(({ data }) => data));
5231
+ }
5228
5232
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: ApiServicesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5229
5233
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: ApiServicesService, providedIn: 'root' });
5230
5234
  }
@@ -6013,16 +6017,80 @@ var CustomerRoleType;
6013
6017
  CustomerRoleType["EXPORTER"] = "EP";
6014
6018
  })(CustomerRoleType || (CustomerRoleType = {}));
6015
6019
 
6020
+ const SOCKETS_AUTH_PATH = '/sockets/auth';
6016
6021
  class WebSocketsService {
6017
- pusher;
6022
+ pusher = null;
6023
+ appKey = null;
6024
+ connectPromise = null;
6018
6025
  environments = inject(ENVIRONMENT_TOKEN);
6019
- constructor() {
6020
- this.pusher = null;
6021
- this.connect()
6022
- .then((pusher) => {
6023
- if (!pusher)
6024
- return;
6026
+ getAuthToken = null;
6027
+ channelAuthHeaders = {};
6028
+ /**
6029
+ * Stores the Pusher/Soketi application key without opening a connection.
6030
+ * The first `channelSub` / `eventBind` opens Pusher via `ensureConnected`.
6031
+ *
6032
+ * @param {string} appKey - The Pusher/Soketi application key.
6033
+ */
6034
+ setAppKey(appKey) {
6035
+ this.appKey = appKey;
6036
+ }
6037
+ /**
6038
+ * Registers a live token provider used when authorizing private/presence channels.
6039
+ * The provider is called at subscribe/authorize time; the token is not snapshotted here.
6040
+ *
6041
+ * @param {() => string | null} getToken - Returns the current session token, or null.
6042
+ */
6043
+ setAuthTokenProvider(getToken) {
6044
+ this.getAuthToken = getToken;
6045
+ }
6046
+ /**
6047
+ * Connects to Pusher using the given app key and env `sockets` url/port/debug.
6048
+ * No-ops if already connected with the same key; reconnects if the key changed.
6049
+ * Resolves false when `sockets` is missing from the environment.
6050
+ * Apps should store the key with `setAppKey` and let subscribe open the client.
6051
+ *
6052
+ * @param {string} appKey - The Pusher/Soketi application key.
6053
+ * @return {Promise<Pusher | false>} The Pusher instance, or false when sockets are not configured.
6054
+ */
6055
+ connect(appKey) {
6056
+ this.setAppKey(appKey);
6057
+ return new Promise((resolve) => {
6058
+ if (this.pusher && this.appKey === appKey) {
6059
+ return resolve(this.pusher);
6060
+ }
6061
+ const { sockets } = this.environments;
6062
+ if (!sockets)
6063
+ return resolve(false);
6064
+ if (this.pusher) {
6065
+ this.pusher.disconnect();
6066
+ this.pusher = null;
6067
+ }
6068
+ const options = {
6069
+ wsHost: sockets.url,
6070
+ wsPort: sockets.port,
6071
+ enabledTransports: ['wss', 'ws'],
6072
+ forceTLS: false,
6073
+ enableStats: false,
6074
+ };
6075
+ const { apiSecurityUrl } = this.environments;
6076
+ if (apiSecurityUrl) {
6077
+ this.refreshChannelAuthHeader();
6078
+ options.channelAuthorization = {
6079
+ transport: 'ajax',
6080
+ endpoint: `${apiSecurityUrl}${SOCKETS_AUTH_PATH}`,
6081
+ headers: this.channelAuthHeaders,
6082
+ headersProvider: () => {
6083
+ this.refreshChannelAuthHeader();
6084
+ return this.channelAuthHeaders;
6085
+ },
6086
+ };
6087
+ }
6088
+ const pusher = new Pusher(appKey, options);
6089
+ if (sockets.debug) {
6090
+ Pusher.logToConsole = true;
6091
+ }
6025
6092
  this.pusher = pusher;
6093
+ return resolve(pusher);
6026
6094
  });
6027
6095
  }
6028
6096
  /**
@@ -6038,25 +6106,40 @@ class WebSocketsService {
6038
6106
  return channel.trigger(`client-${eventName}`, data);
6039
6107
  }
6040
6108
  /**
6041
- * Subscribes to a specified channel, retrying multiple times upon failure.
6109
+ * Subscribes to a specified channel and resolves when Pusher reports success.
6042
6110
  *
6043
6111
  * @param {string} channelName - The name of the channel to be subscribed to.
6044
6112
  * @return {Promise<Channel>} A promise that resolves to the subscribed channel object if successful.
6045
- * @throws {Error} If the subscription fails after the maximum number of retry attempts.
6113
+ * @throws {Error} If the subscription fails.
6046
6114
  */
6047
6115
  async channelSub(channelName) {
6048
- const attempts = 3;
6049
- for (let attempt = 0; attempt <= attempts; attempt++) {
6050
- const channel = this.pusher?.channel(channelName);
6051
- if (channel?.subscribed) {
6052
- return channel;
6053
- }
6054
- this.pusher?.subscribe(channelName);
6055
- if (attempt < attempts) {
6056
- await this.wait();
6057
- }
6116
+ const pusher = await this.ensureConnected();
6117
+ this.refreshChannelAuthHeader();
6118
+ const existing = pusher.channel(channelName);
6119
+ if (existing?.subscribed) {
6120
+ return existing;
6121
+ }
6122
+ const channel = pusher.subscribe(channelName);
6123
+ if (channel.subscribed) {
6124
+ return channel;
6058
6125
  }
6059
- throw new Error(`Failed to subscribe to channel "${channelName}" after ${attempts} attempts.`);
6126
+ await new Promise((resolve, reject) => {
6127
+ const onSuccess = () => {
6128
+ cleanup();
6129
+ resolve();
6130
+ };
6131
+ const onError = () => {
6132
+ cleanup();
6133
+ reject(new Error(`Failed to subscribe to channel "${channelName}".`));
6134
+ };
6135
+ const cleanup = () => {
6136
+ channel.unbind('pusher:subscription_succeeded', onSuccess);
6137
+ channel.unbind('pusher:subscription_error', onError);
6138
+ };
6139
+ channel.bind('pusher:subscription_succeeded', onSuccess);
6140
+ channel.bind('pusher:subscription_error', onError);
6141
+ });
6142
+ return channel;
6060
6143
  }
6061
6144
  /**
6062
6145
  * Binds an event listener to a specified event on a given channel using Pusher or a Channel object,
@@ -6070,11 +6153,19 @@ class WebSocketsService {
6070
6153
  return new Observable((subscriber) => {
6071
6154
  if (channel?.name) {
6072
6155
  channel.bind(event, (data) => subscriber.next(data));
6156
+ return;
6073
6157
  }
6074
- else {
6075
- this.pusher?.subscribe(channel)
6076
- .bind(event, (data) => subscriber.next(data));
6077
- }
6158
+ void (async () => {
6159
+ try {
6160
+ const pusher = await this.ensureConnected();
6161
+ this.refreshChannelAuthHeader();
6162
+ pusher.subscribe(channel)
6163
+ .bind(event, (data) => subscriber.next(data));
6164
+ }
6165
+ catch (error) {
6166
+ subscriber.error(error);
6167
+ }
6168
+ })();
6078
6169
  });
6079
6170
  }
6080
6171
  /**
@@ -6088,27 +6179,41 @@ class WebSocketsService {
6088
6179
  eventUnbind(channel, event) {
6089
6180
  return new Observable((subscriber) => channel.unbind(event, (data) => subscriber.next(data)));
6090
6181
  }
6091
- connect() {
6092
- return new Promise((resolve) => {
6093
- const { sockets } = this.environments;
6094
- if (!sockets)
6095
- return resolve(false);
6096
- const pusher = new Pusher(sockets.app_key, {
6097
- wsHost: sockets.url,
6098
- wsPort: sockets.port,
6099
- enabledTransports: ['wss', 'ws'],
6100
- forceTLS: false,
6101
- enableStats: false,
6102
- });
6103
- if (sockets.debug) {
6104
- Pusher.logToConsole = true;
6182
+ /**
6183
+ * Unsubscribes from a channel by name.
6184
+ *
6185
+ * @param {string} channelName - The channel name previously passed to subscribe.
6186
+ */
6187
+ unsubscribe(channelName) {
6188
+ this.pusher?.unsubscribe(channelName);
6189
+ }
6190
+ async ensureConnected() {
6191
+ if (this.pusher)
6192
+ return this.pusher;
6193
+ if (!this.appKey) {
6194
+ throw new Error('The sockets connection is not established.');
6195
+ }
6196
+ this.connectPromise ??= this.connect(this.appKey);
6197
+ try {
6198
+ const pusher = await this.connectPromise;
6199
+ if (!pusher) {
6200
+ throw new Error('The sockets connection is not established.');
6105
6201
  }
6106
- return resolve(pusher);
6107
- });
6202
+ return pusher;
6203
+ }
6204
+ catch (error) {
6205
+ this.connectPromise = null;
6206
+ throw error;
6207
+ }
6108
6208
  }
6109
- async wait() {
6110
- const waitTime = 3 * 1000;
6111
- return new Promise((resolve) => setTimeout(resolve, waitTime));
6209
+ refreshChannelAuthHeader() {
6210
+ const token = this.getAuthToken?.() ?? null;
6211
+ if (token) {
6212
+ this.channelAuthHeaders['Authorization'] = `Bearer ${token}`;
6213
+ }
6214
+ else {
6215
+ delete this.channelAuthHeaders['Authorization'];
6216
+ }
6112
6217
  }
6113
6218
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: WebSocketsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6114
6219
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.27", ngImport: i0, type: WebSocketsService, providedIn: 'root' });
@@ -6118,13 +6223,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.27", ngImpo
6118
6223
  args: [{
6119
6224
  providedIn: 'root',
6120
6225
  }]
6121
- }], ctorParameters: () => [] });
6226
+ }] });
6122
6227
 
6123
6228
  const AES_KEY_USAGES = ['encrypt', 'decrypt'];
6124
6229
  class CryptoService {
6125
- environments = inject(ENVIRONMENT_TOKEN);
6126
- async encryptAES(plaintext) {
6127
- const cryptoKey = await this.loadKey();
6230
+ async encryptAES(plaintext, secretKey) {
6231
+ const cryptoKey = await this.loadKey(secretKey);
6128
6232
  // Convert the plaintext in Uint8Array
6129
6233
  const encoder = new TextEncoder();
6130
6234
  const encoded = encoder.encode(plaintext);
@@ -6137,13 +6241,13 @@ class CryptoService {
6137
6241
  }, cryptoKey, encoded);
6138
6242
  return `${this.uint8ArrayToBase64(iv)}:${this.arrayBufferToBase64(ciphertext)}`;
6139
6243
  }
6140
- async decryptAES(payload) {
6244
+ async decryptAES(payload, secretKey) {
6141
6245
  // Extract the Initialization Vector (IV), and the cypher text
6142
6246
  const [base64IV, base64Ciphertext] = payload.split(':');
6143
6247
  if (!base64IV || !base64Ciphertext) {
6144
6248
  throw new Error('The payload must contain the IV and the cipher text.');
6145
6249
  }
6146
- const cryptoKey = await this.loadKey();
6250
+ const cryptoKey = await this.loadKey(secretKey);
6147
6251
  const iv = this.base64ToUint8Array(base64IV);
6148
6252
  const cipherText = this.base64ToArrayBuffer(base64Ciphertext);
6149
6253
  // Decrypt the cypher text
@@ -6155,14 +6259,12 @@ class CryptoService {
6155
6259
  const decoder = new TextDecoder();
6156
6260
  return decoder.decode(decrypted);
6157
6261
  }
6158
- async loadKey() {
6159
- if (!this.environments.secretKey) {
6160
- throw new Error('The secret key is not defined in the environment configuration.');
6262
+ async loadKey(secretKey) {
6263
+ if (!secretKey) {
6264
+ throw new Error('The secret key is not defined.');
6161
6265
  }
6162
- // Decode the base64 key to Uint8Array
6163
- const rawKey = this.base64ToUint8Array(this.environments.secretKey);
6164
- // Import the key to API Crypto
6165
- return await crypto.subtle.importKey('raw', rawKey, { name: 'AES-GCM' }, true, AES_KEY_USAGES);
6266
+ const rawKey = new TextEncoder().encode(secretKey);
6267
+ return crypto.subtle.importKey('raw', rawKey, { name: 'AES-GCM' }, true, AES_KEY_USAGES);
6166
6268
  }
6167
6269
  uint8ArrayToBase64(data) {
6168
6270
  let binary = '';