@crowdin/app-project-module 0.28.6 → 0.28.8

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.
@@ -84,7 +84,7 @@ function handle(config) {
84
84
  modules['organization-menu'] = [
85
85
  {
86
86
  key: config.identifier + '-resources',
87
- name: config.name,
87
+ name: config.organizationMenu.name || config.name,
88
88
  url: '/resources/' + (config.organizationMenu.fileName || 'index.html'),
89
89
  icon: (0, util_1.getLogoUrl)(config, config.organizationMenu, '/resources'),
90
90
  },
@@ -94,7 +94,7 @@ function handle(config) {
94
94
  modules['profile-resources-menu'] = [
95
95
  {
96
96
  key: config.identifier + '-profile-resources-menu',
97
- name: config.name,
97
+ name: config.profileResourcesMenu.name || config.name,
98
98
  url: '/resources/' + (config.profileResourcesMenu.fileName || 'index.html'),
99
99
  icon: (0, util_1.getLogoUrl)(config, config.profileResourcesMenu, '/resources'),
100
100
  environments: config.profileResourcesMenu.environments,
@@ -105,7 +105,7 @@ function handle(config) {
105
105
  modules['editor-right-panel'] = [
106
106
  {
107
107
  key: config.identifier + '-editor-panels',
108
- name: config.name,
108
+ name: config.editorRightPanel.name || config.name,
109
109
  url: '/editor-panels/' + (config.editorRightPanel.fileName || 'index.html'),
110
110
  modes: config.editorRightPanel.modes,
111
111
  environments: config.editorRightPanel.environments,
@@ -116,7 +116,7 @@ function handle(config) {
116
116
  modules['project-menu'] = [
117
117
  {
118
118
  key: config.identifier + '-project-menu',
119
- name: config.name,
119
+ name: config.projectMenu.name || config.name,
120
120
  url: '/project-menu/' + (config.projectMenu.fileName || 'index.html'),
121
121
  environments: config.projectMenu.environments,
122
122
  },
@@ -126,7 +126,7 @@ function handle(config) {
126
126
  modules['project-menu-crowdsource'] = [
127
127
  {
128
128
  key: config.identifier + '-project-menu-crowdsource',
129
- name: config.name,
129
+ name: config.projectMenuCrowdsource.name || config.name,
130
130
  url: '/project-menu-crowdsource/' + (config.projectMenuCrowdsource.fileName || 'index.html'),
131
131
  },
132
132
  ];
@@ -135,7 +135,7 @@ function handle(config) {
135
135
  modules['project-tools'] = [
136
136
  {
137
137
  key: config.identifier + '-tools',
138
- name: config.name,
138
+ name: config.projectTools.name || config.name,
139
139
  description: config.description,
140
140
  logo: (0, util_1.getLogoUrl)(config, config.projectTools, '/tools'),
141
141
  url: '/tools/' + (config.projectTools.fileName || 'index.html'),
@@ -147,7 +147,7 @@ function handle(config) {
147
147
  modules['project-reports'] = [
148
148
  {
149
149
  key: config.identifier + '-project-reports',
150
- name: config.name,
150
+ name: config.projectReports.name || config.name,
151
151
  description: config.description,
152
152
  logo: (0, util_1.getLogoUrl)(config, config.projectReports, '/reports'),
153
153
  url: '/reports/' + (config.projectReports.fileName || 'index.html'),
@@ -158,7 +158,7 @@ function handle(config) {
158
158
  modules['modal'] = [
159
159
  {
160
160
  key: config.identifier + '-modal',
161
- name: config.name,
161
+ name: config.modal.name || config.name,
162
162
  url: config.modal.url || '/modal/' + (config.modal.fileName || 'index.html'),
163
163
  environments: config.modal.environments,
164
164
  },
@@ -168,7 +168,7 @@ function handle(config) {
168
168
  modules['context-menu'] = [
169
169
  {
170
170
  key: config.identifier + '-context-menu',
171
- name: config.name,
171
+ name: config.contextMenu.name || config.name,
172
172
  description: config.description,
173
173
  options: Object.assign(Object.assign({ location: config.contextMenu.location, type: config.contextMenu.type }, (config.contextMenu.module
174
174
  ? {
@@ -177,6 +177,7 @@ function handle(config) {
177
177
  },
178
178
  }
179
179
  : {})), { url: '/context/' + (config.contextMenu.fileName || 'index.html') }),
180
+ signaturePatterns: config.contextMenu.signaturePatterns,
180
181
  environments: config.contextMenu.environments,
181
182
  },
182
183
  ];
@@ -46,12 +46,12 @@ function prepareCrowdinRequest(jwtToken, config, optional = false, checkSubscrip
46
46
  exports.prepareCrowdinRequest = prepareCrowdinRequest;
47
47
  function handle(config, optional = false, checkSubscriptionExpiration = true) {
48
48
  return (0, util_1.runAsyncWrapper)((req, res, next) => __awaiter(this, void 0, void 0, function* () {
49
- const tokenJwt = getToken(req);
50
- if (!tokenJwt) {
49
+ const jwtToken = getToken(req);
50
+ if (!jwtToken) {
51
51
  return res.status(403).send({ error: 'Access denied' });
52
52
  }
53
53
  try {
54
- const data = yield prepareCrowdinRequest(tokenJwt, config, optional, checkSubscriptionExpiration);
54
+ const data = yield prepareCrowdinRequest(jwtToken, config, optional, checkSubscriptionExpiration);
55
55
  req.crowdinContext = data.context;
56
56
  if (data.client) {
57
57
  req.crowdinApiClient = data.client;
@@ -76,9 +76,9 @@ function handle(config, optional = false, checkSubscriptionExpiration = true) {
76
76
  }
77
77
  exports.default = handle;
78
78
  function getToken(req) {
79
- const tokenJwt = (req.query.tokenJwt || req.query.jwtToken);
80
- if (tokenJwt) {
81
- return tokenJwt;
79
+ const jwtToken = req.query.jwtToken;
80
+ if (jwtToken) {
81
+ return jwtToken;
82
82
  }
83
83
  if (req.headers.authorization) {
84
84
  if (req.headers.authorization.startsWith('Bearer ') || req.headers.authorization.startsWith('bearer ')) {
@@ -19,12 +19,12 @@ function handle(config, allowUnauthorized = false) {
19
19
  next();
20
20
  return;
21
21
  }
22
- const tokenJwt = req.query.tokenJwt;
23
- if (!tokenJwt) {
22
+ const jwtToken = req.query.jwtToken;
23
+ if (!jwtToken) {
24
24
  return res.status(403).send({ error: 'Access denied' });
25
25
  }
26
26
  (0, util_1.log)('Validating jwt token from incoming request', config.logger);
27
- const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(tokenJwt, config.clientSecret, config.jwtValidationOptions);
27
+ const jwtPayload = yield (0, crowdin_apps_functions_1.validateJwtToken)(jwtToken, config.clientSecret, config.jwtValidationOptions);
28
28
  const id = `${jwtPayload.domain || jwtPayload.context.organization_id}`;
29
29
  (0, util_1.log)('Loading crowdin credentials', config.logger);
30
30
  const credentials = yield (0, storage_1.getStorage)().getCrowdinCredentials(id);
@@ -683,6 +683,10 @@ export interface UiModule {
683
683
  * make module publicly available without crowdin context
684
684
  */
685
685
  allowUnauthorized?: boolean;
686
+ /**
687
+ * Module name
688
+ */
689
+ name?: string;
686
690
  }
687
691
  export interface EditorPanels extends UiModule {
688
692
  /**
@@ -706,6 +710,14 @@ export interface ContextModule {
706
710
  location: ContextOptionsLocations;
707
711
  type: ContextOptionsTypes;
708
712
  module: string;
713
+ /**
714
+ * Context menu name
715
+ */
716
+ name?: string;
717
+ /**
718
+ * Support fileName pattern only. Contains fileName field regular expressions used to detect the file type. If the file name matches any of the regular expressions, the context menu will be displayed.
719
+ */
720
+ signaturePatterns?: SignaturePatterns;
709
721
  }
710
722
  export declare enum ContextOptionsLocations {
711
723
  TM = "tm",
@@ -1,143 +1,94 @@
1
1
  if (!window.Promise) {
2
- window.Promise = Promise;
2
+ window.Promise = Promise;
3
3
  }
4
4
 
5
5
  const urlParams = new URLSearchParams(window.location.search);
6
6
  const origin = urlParams.get('origin');
7
7
  const clientId = urlParams.get('client_id');
8
- const tokenJwt = urlParams.get('tokenJwt');
9
8
  let restParams = window.location.search;
10
9
  const frameData = JSON.parse(window.name);
11
10
 
12
11
  const postPromises = {};
13
12
 
14
- function parentWindowPostMessage(data) {
15
- return new Promise((resolve, reject) => {
16
- window.parent.postMessage(JSON.stringify(data), origin);
17
- const timerId = setTimeout(() => {
18
- reject();
19
- }, 10000);
20
- postPromises[data.uid] = { resolve: resolve, timer: timerId };
21
- });
22
- }
23
-
24
13
  window.addEventListener('message', handleMessage);
25
14
 
26
15
  function isJson(string) {
27
- try {
28
- JSON.parse(string);
29
- } catch (e) {
30
- return false;
31
- }
16
+ try {
17
+ JSON.parse(string);
18
+ } catch (e) {
19
+ return false;
20
+ }
32
21
 
33
- return true;
22
+ return true;
34
23
  }
35
24
 
36
25
  function handleMessage(event) {
37
- const eventData =
38
- event.data && typeof event.data === 'string' && isJson(event.data) ? JSON.parse(event.data) : {};
39
- if (postPromises[eventData.uid]) {
40
- if (postPromises[eventData.uid].timer) {
41
- clearTimeout(postPromises[eventData.uid].timer);
26
+ const eventData = event.data && typeof event.data === 'string' && isJson(event.data) ? JSON.parse(event.data) : {};
27
+ if (postPromises[eventData.uid]) {
28
+ if (postPromises[eventData.uid].timer) {
29
+ clearTimeout(postPromises[eventData.uid].timer);
30
+ }
31
+ postPromises[eventData.uid].resolve(eventData.data);
42
32
  }
43
- postPromises[eventData.uid].resolve(eventData.data);
44
- }
45
33
  }
46
34
 
47
35
  function showToast(message) {
48
- if (!!message) {
49
- const toasts = document.querySelector('crowdin-toasts');
50
- if (toasts && toasts.pushToasts) {
51
- toasts.pushToasts([message]);
36
+ if (!!message) {
37
+ const toasts = document.querySelector('crowdin-toasts');
38
+ if (toasts && toasts.pushToasts) {
39
+ toasts.pushToasts([message]);
40
+ }
52
41
  }
53
- }
54
42
  }
55
43
 
56
44
  function catchRejection(e, message) {
57
- //session expired
58
- if (e.code && e.code === 401) {
59
- reloadLocation();
60
- return;
61
- }
62
- //payment required
63
- if (e.code && e.code === 402 && subscriptionModal) {
64
- subscriptionLink = e.message || message;
65
- subscriptionModal.open();
66
- return;
67
- }
68
- showToast(e.message || message);
45
+ //session expired
46
+ if (e.code && e.code === 401) {
47
+ reloadLocation();
48
+ return;
49
+ }
50
+ //payment required
51
+ if (e.code && e.code === 402 && subscriptionModal) {
52
+ subscriptionLink = e.message || message;
53
+ subscriptionModal.open();
54
+ return;
55
+ }
56
+ showToast(e.message || message);
69
57
  }
70
58
 
71
59
  function checkResponse(response) {
72
- return new Promise((resolve, reject) => {
73
- if (response.status === 204) {
74
- return resolve();
75
- }
76
- response
77
- .json()
78
- .then((res) => {
79
- if (![200, 201, 304].includes(response.status)) {
80
- reject(res);
81
- } else {
82
- if (res.message) {
83
- showToast(res.message);
84
- }
85
- resolve(res);
60
+ return new Promise((resolve, reject) => {
61
+ if (response.status === 204) {
62
+ return resolve();
86
63
  }
87
- })
88
- .catch((e) => {
89
- reject(e);
90
- });
91
- });
64
+ response
65
+ .json()
66
+ .then((res) => {
67
+ if (![200, 201, 304].includes(response.status)) {
68
+ reject(res);
69
+ } else {
70
+ if (res.message) {
71
+ showToast(res.message);
72
+ }
73
+ resolve(res);
74
+ }
75
+ })
76
+ .catch((e) => {
77
+ reject(e);
78
+ });
79
+ });
92
80
  }
93
81
 
94
82
  function checkOrigin() {
95
- return new Promise((resolve, reject) => {
96
- try {
97
- const tokenData = parseJwt(tokenJwt);
98
- if (tokenData.exp < parseInt(new Date().getTime() / 1000)) {
99
- // request for new token
100
- parentWindowPostMessage({
101
- identifier: frameData.app.identifier,
102
- key: frameData.app.key,
103
- client_id: clientId,
104
- command: 'token',
105
- uid: new Date().getTime(),
106
- data: {},
107
- })
108
- .then((eventData) => {
109
- restParams = `?origin=${origin}&client_id=${clientId}&tokenJwt=${eventData.tokenJwt}`;
83
+ return new Promise((resolve, reject) => {
84
+ AP.getJwtToken(jwtToken => {
85
+ restParams = `?origin=${origin}&client_id=${clientId}&jwtToken=${jwtToken}`;
110
86
  resolve(restParams);
111
- })
112
- .catch(() => reject());
113
- } else {
114
- resolve(restParams);
115
- }
116
- } catch (e) {
117
- reject();
118
- }
119
- });
120
- }
121
-
122
- function parseJwt(token) {
123
- const base64Url = token.split('.')[1];
124
- const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
125
- const jsonPayload = decodeURIComponent(
126
- atob(base64)
127
- .split('')
128
- .map(function (c) {
129
- return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
130
- })
131
- .join(''),
132
- );
133
- return JSON.parse(jsonPayload);
87
+ });
88
+ });
134
89
  }
135
90
 
136
91
  function reloadLocation() {
137
- window.location.href =
138
- window.location.protocol +
139
- '//' +
140
- window.location.host +
141
- window.location.pathname +
142
- restParams;
92
+ window.location.href =
93
+ window.location.protocol + '//' + window.location.host + window.location.pathname + restParams;
143
94
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crowdin/app-project-module",
3
- "version": "0.28.6",
3
+ "version": "0.28.8",
4
4
  "description": "Module that generates for you all common endpoints for serving standalone Crowdin App",
5
5
  "main": "out/index.js",
6
6
  "types": "out/index.d.ts",
@@ -26,7 +26,6 @@
26
26
  "uuid": "^8.3.2"
27
27
  },
28
28
  "devDependencies": {
29
- "@types/amqplib": "^0.10.1",
30
29
  "@babel/preset-react": "^7.18.6",
31
30
  "@emotion/react": "^11.10.6",
32
31
  "@emotion/styled": "^11.10.6",
@@ -42,6 +41,7 @@
42
41
  "@rollup/plugin-node-resolve": "^15.0.1",
43
42
  "@rollup/plugin-replace": "^5.0.2",
44
43
  "@rollup/plugin-terser": "^0.4.0",
44
+ "@types/amqplib": "^0.10.1",
45
45
  "@types/crypto-js": "^4.0.0",
46
46
  "@types/express": "4.17.17",
47
47
  "@types/express-handlebars": "^5.3.1",