@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.
package/out/handlers/manifest.js
CHANGED
|
@@ -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
|
|
50
|
-
if (!
|
|
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(
|
|
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
|
|
80
|
-
if (
|
|
81
|
-
return
|
|
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
|
|
23
|
-
if (!
|
|
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)(
|
|
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);
|
package/out/models/index.d.ts
CHANGED
|
@@ -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",
|
package/out/static/js/main.js
CHANGED
|
@@ -1,143 +1,94 @@
|
|
|
1
1
|
if (!window.Promise) {
|
|
2
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
16
|
+
try {
|
|
17
|
+
JSON.parse(string);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
32
21
|
|
|
33
|
-
|
|
22
|
+
return true;
|
|
34
23
|
}
|
|
35
24
|
|
|
36
25
|
function handleMessage(event) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
89
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
|
|
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.
|
|
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",
|