@atlaskit/editor-card-provider 6.1.0 → 6.2.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.
@@ -3,6 +3,7 @@
3
3
  import { extractSmartLinkEmbed } from '@atlaskit/link-extractors';
4
4
  import { NodeDataProvider } from '@atlaskit/node-data-provider';
5
5
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
+ import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
6
7
  import { getStatus, getBaseUrl, getResolverUrl } from '@atlaskit/linking-common';
7
8
  import DataLoader from 'dataloader';
8
9
  import { Transformer } from './transformer';
@@ -109,35 +110,21 @@ export class EditorCardProvider extends NodeDataProvider {
109
110
  }
110
111
  async checkLinkResolved(resourceUrl) {
111
112
  try {
112
- const response = expValEquals('platform_editor_smart_card_otp', 'isEnabled', true) ?
113
- // It's ok to cast any resourceUrl to inlineCard here, because only URL is important for the request.
114
- await this.getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS({
115
- type: 'inlineCard',
116
- attrs: {
117
- url: resourceUrl
118
- }
119
- }) : await this.cardClient.fetchData(resourceUrl);
113
+ const response = await this.fetchData(resourceUrl);
120
114
  if (getStatus(response) !== 'not_found') {
121
115
  return true;
122
116
  }
123
- } catch (e) {
117
+ } catch {
124
118
  return false;
125
119
  }
126
120
  }
127
121
  async fetchDataForResource(resourceUrl) {
128
122
  try {
129
- const response = expValEquals('platform_editor_smart_card_otp', 'isEnabled', true) ?
130
- // It's ok to cast any resourceUrl to inlineCard here, because only URL is important for the request.
131
- await this.getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS({
132
- type: 'inlineCard',
133
- attrs: {
134
- url: resourceUrl
135
- }
136
- }) : await this.cardClient.fetchData(resourceUrl);
123
+ const response = await this.fetchData(resourceUrl);
137
124
  if (getStatus(response) !== 'not_found') {
138
125
  return response;
139
126
  }
140
- } catch (e) {
127
+ } catch {
141
128
  return undefined;
142
129
  }
143
130
  }
@@ -234,20 +221,24 @@ export class EditorCardProvider extends NodeDataProvider {
234
221
  return 'embed';
235
222
  }
236
223
  }
224
+ async fetchData(url) {
225
+ // it uses fetchNodesData internally and caches the result
226
+ return expValEquals('platform_editor_smart_card_otp', 'isEnabled', true) ?
227
+ // It's ok to cast any resourceUrl to inlineCard here, because only URL is important for the request.
228
+ await this.getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS({
229
+ type: 'inlineCard',
230
+ attrs: {
231
+ url
232
+ }
233
+ }) : await this.cardClient.fetchData(url);
234
+ }
237
235
 
238
236
  /**
239
237
  * Make a /resolve call and find out if result has embed capability
240
238
  */
241
239
  async canBeResolvedAsEmbed(url) {
242
240
  try {
243
- const details = expValEquals('platform_editor_smart_card_otp', 'isEnabled', true) ?
244
- // It's ok to cast any resourceUrl to inlineCard here, because only URL is important for the request.
245
- await this.getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS({
246
- type: 'inlineCard',
247
- attrs: {
248
- url
249
- }
250
- }) : await this.cardClient.fetchData(url);
241
+ const details = await this.fetchData(url);
251
242
  if (!details) {
252
243
  return false;
253
244
  }
@@ -261,31 +252,40 @@ export class EditorCardProvider extends NodeDataProvider {
261
252
  }
262
253
  const embed = extractSmartLinkEmbed(details);
263
254
  return !!embed;
264
- } catch (e) {
255
+ } catch {
265
256
  return false;
266
257
  }
267
258
  }
259
+ async getAuthStatusFromResolveResponse(url) {
260
+ try {
261
+ const {
262
+ meta: {
263
+ access,
264
+ visibility
265
+ }
266
+ } = await this.fetchData(url);
267
+ return {
268
+ access,
269
+ visibility
270
+ };
271
+ } catch {
272
+ return undefined;
273
+ }
274
+ }
268
275
 
269
276
  /**
270
277
  * Make a /resolve call and find out if result has datasource capability
271
278
  */
272
279
  async getDatasourceFromResolveResponse(url) {
273
280
  try {
274
- const response = expValEquals('platform_editor_smart_card_otp', 'isEnabled', true) ?
275
- // It's ok to cast any resourceUrl to inlineCard here, because only URL is important for the request.
276
- await this.getDataAsPromise_DO_NOT_USE_OUTSIDE_MIGRATIONS({
277
- type: 'inlineCard',
278
- attrs: {
279
- url
280
- }
281
- }) : await this.cardClient.fetchData(url);
281
+ const response = await this.fetchData(url);
282
282
  const datasources = response && response.datasources || [];
283
283
  if (datasources.length > 0) {
284
284
  // For now we only have one datasource expected even though it is in an array.
285
285
  // When we have resources returning more than one we will have revisit this part.
286
286
  return datasources[0];
287
287
  }
288
- } catch (e) {
288
+ } catch {
289
289
  return undefined;
290
290
  }
291
291
  }
@@ -324,6 +324,7 @@ export class EditorCardProvider extends NodeDataProvider {
324
324
  const isSupported = !!matchedProviderPattern || (await this.checkLinkResolved(url));
325
325
  if (isSupported) {
326
326
  const providerDefaultAppearance = matchedProviderPattern === null || matchedProviderPattern === void 0 ? void 0 : matchedProviderPattern.defaultView;
327
+ const isEmbedFriendlyLocationEvaluated = isEmbedFriendlyLocation || isEmbedFriendlyLocation === undefined;
327
328
  let preferredAppearance = shouldForceAppearance === undefined ?
328
329
  // Ignore both User and provider's appearances if older editor that doesn't send shouldForceAppearance
329
330
  hardCodedAppearance || appearance :
@@ -332,7 +333,7 @@ export class EditorCardProvider extends NodeDataProvider {
332
333
  userPreference ||
333
334
  // If user's default choice is "inline" or user hasn't specified preferences at all,
334
335
  // we check whatever one of the hardcoded providers match url (jira /timeline, polaris, etc)
335
- (isEmbedFriendlyLocation || isEmbedFriendlyLocation === undefined) && hardCodedAppearance ||
336
+ isEmbedFriendlyLocationEvaluated && hardCodedAppearance ||
336
337
  // If non match, we see if this provider has default appearance for this particular regexp
337
338
  providerDefaultAppearance ||
338
339
  // If not, we pick what editor (or any other client) requested
@@ -359,6 +360,21 @@ export class EditorCardProvider extends NodeDataProvider {
359
360
  }]
360
361
  }, url);
361
362
  }
363
+ const isUnauthPasteAsBlockCardEnabledNoExposure = !expValEqualsNoExposure('platform_sl_3p_unauth_paste_as_block_card', 'cohort', 'control', 'control');
364
+ if (isUnauthPasteAsBlockCardEnabledNoExposure && isEmbedFriendlyLocationEvaluated && !userPreference) {
365
+ const authStatus = await this.getAuthStatusFromResolveResponse(url);
366
+ if (authStatus) {
367
+ const {
368
+ access
369
+ } = authStatus;
370
+ if (access === 'unauthorized') {
371
+ const isUnauthPasteAsBlockCardEnabled = !expValEquals('platform_sl_3p_unauth_paste_as_block_card', 'cohort', 'control', 'control');
372
+ if (isUnauthPasteAsBlockCardEnabled) {
373
+ return this.transformer.toSmartlinkAdf(url, 'block');
374
+ }
375
+ }
376
+ }
377
+ }
362
378
  return this.transformer.toSmartlinkAdf(url, preferredAppearance);
363
379
  }
364
380
  } catch (e) {