@steedos-labs/content-compliance 0.8.25 → 0.8.27

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.
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var tslib_1 = require("tslib");
4
+ var fs = require("node:fs");
5
+ var path = require("node:path");
6
+ var vm = require("node:vm");
7
+ var clientScript = fs.readFileSync(path.resolve(__dirname, '../../../main/default/client/pepsico_content.client.js'), 'utf8');
8
+ var ORIGIN = 'https://example.test';
9
+ var SPACE_ID = 'space-1';
10
+ var SESSION_TOKEN = 'session-token';
11
+ var RESIGNED = "Bearer ".concat(SPACE_ID, ",").concat(SESSION_TOKEN);
12
+ var EXPIRED_ROOMS_JWT = 'Bearer expired-rooms-jwt';
13
+ var createStorage = function (values) { return ({
14
+ getItem: function (key) { return (key in values ? values[key] : null); },
15
+ setItem: function (key, value) {
16
+ values[key] = value;
17
+ },
18
+ removeItem: function (key) {
19
+ delete values[key];
20
+ }
21
+ }); };
22
+ var loadClientScript = function (stored) {
23
+ if (stored === void 0) { stored = {}; }
24
+ var fetchCalls = [];
25
+ var consoleCalls = [];
26
+ var record = function (level) { return function (message) {
27
+ consoleCalls.push({ level: level, message: message });
28
+ }; };
29
+ var consoleStub = { debug: record('debug'), warn: record('warn') };
30
+ var localStorage = createStorage(tslib_1.__assign({}, stored));
31
+ var window = {
32
+ __meteor_runtime_config__: {},
33
+ drawerWidth: '',
34
+ fetch: function (input, init) {
35
+ fetchCalls.push({ input: input, init: init });
36
+ return Promise.resolve({ status: 200 });
37
+ },
38
+ localStorage: localStorage,
39
+ location: { origin: ORIGIN }
40
+ };
41
+ window.window = window;
42
+ vm.runInNewContext(clientScript, {
43
+ Date: Date,
44
+ Headers: Headers,
45
+ Object: Object,
46
+ Request: Request,
47
+ URL: URL,
48
+ console: consoleStub,
49
+ document: { title: '' },
50
+ loadCss: function () { return undefined; },
51
+ localStorage: localStorage,
52
+ Steedos: { absoluteUrl: function (url) { return url; } },
53
+ window: window
54
+ });
55
+ return { window: window, fetchCalls: fetchCalls, consoleCalls: consoleCalls };
56
+ };
57
+ var authorizationOf = function (call) {
58
+ var headers = call.init && call.init.headers;
59
+ if (!headers)
60
+ return null;
61
+ return typeof headers.get === 'function'
62
+ ? headers.get('Authorization')
63
+ : headers.Authorization;
64
+ };
65
+ var platformSession = { 'steedos:spaceId': SPACE_ID, 'steedos:token': SESSION_TOKEN };
66
+ describe('rooms 凭证改签 (#445)', function () {
67
+ it('从平台实际写入的 key 读取会话凭证', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
68
+ var _a, window, fetchCalls;
69
+ return tslib_1.__generator(this, function (_b) {
70
+ switch (_b.label) {
71
+ case 0:
72
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
73
+ return [4, window.fetch('/v2/c/users?userIds=u1', {
74
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
75
+ })];
76
+ case 1:
77
+ _b.sent();
78
+ expect(authorizationOf(fetchCalls[0])).toBe(RESIGNED);
79
+ return [2];
80
+ }
81
+ });
82
+ }); });
83
+ it('回落到历史 key', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
84
+ var _a, window, fetchCalls;
85
+ return tslib_1.__generator(this, function (_b) {
86
+ switch (_b.label) {
87
+ case 0:
88
+ _a = loadClientScript({
89
+ 'steedos:spaceId': SPACE_ID,
90
+ 'steedos:authToken': SESSION_TOKEN
91
+ }), window = _a.window, fetchCalls = _a.fetchCalls;
92
+ return [4, window.fetch('/v2/c/users?userIds=u1', {
93
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
94
+ })];
95
+ case 1:
96
+ _b.sent();
97
+ expect(authorizationOf(fetchCalls[0])).toBe(RESIGNED);
98
+ return [2];
99
+ }
100
+ });
101
+ }); });
102
+ it('改签 @ 提及搜索(绝对地址同源)', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
103
+ var _a, window, fetchCalls;
104
+ return tslib_1.__generator(this, function (_b) {
105
+ switch (_b.label) {
106
+ case 0:
107
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
108
+ return [4, window.fetch("".concat(ORIGIN, "/v2/c/users/search?keyword=li"), {
109
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
110
+ })];
111
+ case 1:
112
+ _b.sent();
113
+ expect(authorizationOf(fetchCalls[0])).toBe(RESIGNED);
114
+ return [2];
115
+ }
116
+ });
117
+ }); });
118
+ it('改签 POST 发评论 —— 原实现只拦 GET,发评论会静默丢失', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
119
+ var _a, window, fetchCalls;
120
+ return tslib_1.__generator(this, function (_b) {
121
+ switch (_b.label) {
122
+ case 0:
123
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
124
+ return [4, window.fetch('/v2/c/rooms/objects:pepsico_material:r1/threads', {
125
+ method: 'POST',
126
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
127
+ })];
128
+ case 1:
129
+ _b.sent();
130
+ expect(authorizationOf(fetchCalls[0])).toBe(RESIGNED);
131
+ return [2];
132
+ }
133
+ });
134
+ }); });
135
+ it('改签 threads 子路径 —— 原实现用精确路径匹配,该路径匹配不上', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
136
+ var _a, window, fetchCalls;
137
+ return tslib_1.__generator(this, function (_b) {
138
+ switch (_b.label) {
139
+ case 0:
140
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
141
+ return [4, window.fetch('/v2/c/rooms/objects:pepsico_material:r1/threads', {
142
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
143
+ })];
144
+ case 1:
145
+ _b.sent();
146
+ expect(authorizationOf(fetchCalls[0])).toBe(RESIGNED);
147
+ return [2];
148
+ }
149
+ });
150
+ }); });
151
+ it('不动 /v2/c/auth —— 它本身就是拿会话凭证换票的接口', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
152
+ var _a, window, fetchCalls;
153
+ return tslib_1.__generator(this, function (_b) {
154
+ switch (_b.label) {
155
+ case 0:
156
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
157
+ return [4, window.fetch('/v2/c/auth', { method: 'POST' })];
158
+ case 1:
159
+ _b.sent();
160
+ expect(authorizationOf(fetchCalls[0])).toBeFalsy();
161
+ return [2];
162
+ }
163
+ });
164
+ }); });
165
+ it('不动非 /v2/c/ 的同源请求', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
166
+ var _a, window, fetchCalls;
167
+ return tslib_1.__generator(this, function (_b) {
168
+ switch (_b.label) {
169
+ case 0:
170
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
171
+ return [4, window.fetch('/api/v1/pepsico_material', {
172
+ headers: { Authorization: 'Bearer other' }
173
+ })];
174
+ case 1:
175
+ _b.sent();
176
+ expect(authorizationOf(fetchCalls[0])).toBe('Bearer other');
177
+ return [2];
178
+ }
179
+ });
180
+ }); });
181
+ it('不动跨域请求,避免把会话凭证泄漏到外部域', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
182
+ var _a, window, fetchCalls;
183
+ return tslib_1.__generator(this, function (_b) {
184
+ switch (_b.label) {
185
+ case 0:
186
+ _a = loadClientScript(platformSession), window = _a.window, fetchCalls = _a.fetchCalls;
187
+ return [4, window.fetch('https://elsewhere.test/v2/c/users?userIds=u1', {
188
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
189
+ })];
190
+ case 1:
191
+ _b.sent();
192
+ expect(authorizationOf(fetchCalls[0])).toBe(EXPIRED_ROOMS_JWT);
193
+ return [2];
194
+ }
195
+ });
196
+ }); });
197
+ it('无 localStorage 凭证时删掉过期 JWT,让 cookie 会话接管', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
198
+ var _a, window, fetchCalls;
199
+ return tslib_1.__generator(this, function (_b) {
200
+ switch (_b.label) {
201
+ case 0:
202
+ _a = loadClientScript({}), window = _a.window, fetchCalls = _a.fetchCalls;
203
+ return [4, window.fetch('/v2/c/users?userIds=u1', {
204
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
205
+ })];
206
+ case 1:
207
+ _b.sent();
208
+ expect(authorizationOf(fetchCalls[0])).toBeNull();
209
+ return [2];
210
+ }
211
+ });
212
+ }); });
213
+ it('无凭证且请求本就没有 Authorization 头时,不额外包装请求', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
214
+ var _a, window, fetchCalls;
215
+ return tslib_1.__generator(this, function (_b) {
216
+ switch (_b.label) {
217
+ case 0:
218
+ _a = loadClientScript({}), window = _a.window, fetchCalls = _a.fetchCalls;
219
+ return [4, window.fetch('/v2/c/users?userIds=u1')];
220
+ case 1:
221
+ _b.sent();
222
+ expect(fetchCalls[0].init).toBeUndefined();
223
+ return [2];
224
+ }
225
+ });
226
+ }); });
227
+ });
228
+ describe('rooms 凭证改签的可观测性', function () {
229
+ it('装上拦截时打一条安装日志', function () {
230
+ var consoleCalls = loadClientScript(platformSession).consoleCalls;
231
+ expect(consoleCalls.map(function (call) { return call.message; })).toContain('[pepsico][rooms-auth-fix] 已安装 /v2/c/ 请求改签拦截');
232
+ });
233
+ it('改签命中时打一条日志,且重复请求不刷屏', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
234
+ var _a, window, consoleCalls, resigned;
235
+ return tslib_1.__generator(this, function (_b) {
236
+ switch (_b.label) {
237
+ case 0:
238
+ _a = loadClientScript(platformSession), window = _a.window, consoleCalls = _a.consoleCalls;
239
+ return [4, window.fetch('/v2/c/users?userIds=u1')];
240
+ case 1:
241
+ _b.sent();
242
+ return [4, window.fetch('/v2/c/users?userIds=u2')];
243
+ case 2:
244
+ _b.sent();
245
+ resigned = consoleCalls.filter(function (call) {
246
+ return call.message.indexOf('已用 Steedos 会话凭证改签') !== -1;
247
+ });
248
+ expect(resigned).toHaveLength(1);
249
+ return [2];
250
+ }
251
+ });
252
+ }); });
253
+ it('回落到 cookie 会话时告警,便于发现 localStorage 无凭证的部署', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
254
+ var _a, window, consoleCalls, warnings;
255
+ return tslib_1.__generator(this, function (_b) {
256
+ switch (_b.label) {
257
+ case 0:
258
+ _a = loadClientScript({}), window = _a.window, consoleCalls = _a.consoleCalls;
259
+ return [4, window.fetch('/v2/c/users?userIds=u1', {
260
+ headers: { Authorization: EXPIRED_ROOMS_JWT }
261
+ })];
262
+ case 1:
263
+ _b.sent();
264
+ warnings = consoleCalls.filter(function (call) { return call.level === 'warn'; });
265
+ expect(warnings).toHaveLength(1);
266
+ expect(warnings[0].message).toContain('已删除过期的 rooms JWT');
267
+ return [2];
268
+ }
269
+ });
270
+ }); });
271
+ it('未命中 /v2/c/ 的请求不产生改签日志 —— 无该日志即代表拦截一次都没生效', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
272
+ var _a, window, consoleCalls;
273
+ return tslib_1.__generator(this, function (_b) {
274
+ switch (_b.label) {
275
+ case 0:
276
+ _a = loadClientScript(platformSession), window = _a.window, consoleCalls = _a.consoleCalls;
277
+ return [4, window.fetch('/api/v1/other')];
278
+ case 1:
279
+ _b.sent();
280
+ expect(consoleCalls.some(function (call) { return call.message.indexOf('已用 Steedos 会话凭证改签') !== -1; })).toBe(false);
281
+ return [2];
282
+ }
283
+ });
284
+ }); });
285
+ });
286
+ //# sourceMappingURL=roomsCredentialResign.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roomsCredentialResign.test.js","sourceRoot":"","sources":["../../../src/pages/__tests__/roomsCredentialResign.test.ts"],"names":[],"mappings":"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"}
@@ -63,3 +63,124 @@ if(false){
63
63
  }, {});
64
64
  })
65
65
  }
66
+
67
+ // issue #445 临时规避:@steedos-widgets/liveblocks 的 resolveUsers / resolveRoomsInfo /
68
+ // resolveMentionSuggestions,以及发评论/读评论,全部复用缓存的 rooms JWT(仅 60 秒有效)。
69
+ // 过期后 /v2/c/ 接口返回 401 —— 评论作者名显示为 Anonymous、@ 提及搜不到人(刷新才恢复),
70
+ // 发评论则静默丢失。这里把全部同源 /v2/c/ 请求的 Authorization 改签为 Steedos 会话凭证,
71
+ // 使其命中 RoomsGuard 的 AuthGuard 分支(不受 60 秒限制);/v2/c/auth 除外,它本身就是拿
72
+ // 会话凭证换票的接口。平台包(@builder6/rooms / @steedos-widgets/liveblocks)修复后,
73
+ // 本拦截可整体移除。
74
+ //
75
+ // 凭证的 localStorage key 要留意:平台(@steedos/webapp)写入的是 'steedos:token'。
76
+ // 此处原先读的 'steedos:authToken' 平台从未写入,取到 null 后整段改签被静默跳过,
77
+ // 等于这个兜底自上线起从未生效过。'steedos:authToken' 现仅作历史回落保留。
78
+ //
79
+ // 覆盖范围也一并放宽:原实现只拦 GET、且用精确路径匹配 ['/v2/c/users',
80
+ // '/v2/c/users/search', '/v2/c/rooms'],因此 POST 发评论与 /v2/c/rooms/{roomId}/threads
81
+ // 都不在范围内。现改为前缀匹配且不限方法。
82
+ //
83
+ // 会话不在 localStorage(例如只落 cookie)的部署里取不到凭证。此时改为删掉那个已过期的
84
+ // Authorization 头:服务端 AuthGuard.extractTokenFromHeaderOrCookie 优先读头、头不存在
85
+ // 才回落 cookie,过期 JWT 恰好把有效的 cookie 会话挡在外面,删掉反而能过。
86
+ // 与饮料项目(steedos-project-pepsico-bev)的同一处规避保持行为一致。
87
+ //
88
+ // 这段规避坏掉时是**静默**的 —— 上一次就是读错 localStorage key,整段从未生效却没有
89
+ // 任何迹象,一直拖到 UAT 抓包才发现。同类的静默失效还有:widget 抢先缓存了原始 fetch
90
+ // 引用导致包装无效、平台升级后接口不再是 /v2/c/ 前缀。所以在安装与两个命中分支上各打
91
+ // 一次日志(每页仅一次,不刷屏),按下面的阶梯即可在控制台自查:
92
+ // 看不到 "已安装" 行 → client.js 没跑,或 window.fetch 不可包装
93
+ // 有 "已安装"、无 "改签"/"删除" → 拦截装上了但一次都没命中(前缀变了,或 widget 没走 window.fetch)
94
+ // 有 "删除过期 JWT" 行 → localStorage 里没有会话凭证,正走 cookie 兜底
95
+ (function () {
96
+ if (window.__pepsicoRoomsAuthFix || typeof window.fetch !== 'function') return;
97
+ window.__pepsicoRoomsAuthFix = true;
98
+
99
+ var PATCHED_PATH_PREFIX = '/v2/c/';
100
+ var EXCLUDED_PATHS = ['/v2/c/auth'];
101
+ var nativeFetch = window.fetch;
102
+ var logged = {};
103
+
104
+ function logOnce(key, level, message) {
105
+ if (logged[key]) return;
106
+ logged[key] = true;
107
+
108
+ try {
109
+ if (typeof console !== 'undefined' && typeof console[level] === 'function') {
110
+ console[level]('[pepsico][rooms-auth-fix] ' + message);
111
+ }
112
+ } catch (e) {}
113
+ }
114
+
115
+ function steedosAuthorization() {
116
+ try {
117
+ var spaceId = window.localStorage.getItem('steedos:spaceId');
118
+ var authToken = window.localStorage.getItem('steedos:token') ||
119
+ window.localStorage.getItem('steedos:authToken');
120
+
121
+ if (spaceId && authToken) {
122
+ return 'Bearer ' + spaceId + ',' + authToken;
123
+ }
124
+ } catch (e) {}
125
+
126
+ return null;
127
+ }
128
+
129
+ function isPatchedUrl(url) {
130
+ try {
131
+ var parsed = new URL(url, window.location.origin);
132
+
133
+ return parsed.origin === window.location.origin &&
134
+ parsed.pathname.indexOf(PATCHED_PATH_PREFIX) === 0 &&
135
+ EXCLUDED_PATHS.indexOf(parsed.pathname) === -1;
136
+ } catch (e) {
137
+ return false;
138
+ }
139
+ }
140
+
141
+ window.fetch = function (input, init) {
142
+ try {
143
+ var url;
144
+
145
+ if (typeof input === 'string') {
146
+ url = input;
147
+ } else if (input && typeof input.url === 'string') {
148
+ url = input.url;
149
+ } else if (input) {
150
+ url = String(input);
151
+ }
152
+
153
+ if (url && isPatchedUrl(url)) {
154
+ var authorization = steedosAuthorization();
155
+ var requestHeaders = init && init.headers;
156
+
157
+ if (!requestHeaders && typeof Request === 'function' && input instanceof Request) {
158
+ requestHeaders = input.headers;
159
+ }
160
+
161
+ var headers = new Headers(requestHeaders || {});
162
+
163
+ if (authorization) {
164
+ headers.set('Authorization', authorization);
165
+ init = Object.assign({}, init, { headers: headers });
166
+ logOnce('resigned', 'debug', '已用 Steedos 会话凭证改签 /v2/c/ 请求');
167
+ } else if (headers.has('Authorization')) {
168
+ // 会话在 cookie 里:删掉过期的 rooms JWT,让 AuthGuard 回落到 cookie 会话
169
+ headers.delete('Authorization');
170
+ init = Object.assign({}, init, { headers: headers });
171
+ logOnce(
172
+ 'cookie-fallback',
173
+ 'warn',
174
+ 'localStorage 无会话凭证,已删除过期的 rooms JWT 改由 cookie 会话认证'
175
+ );
176
+ }
177
+ }
178
+ } catch (e) {
179
+ // 拦截逻辑自身出错时不影响原始请求
180
+ }
181
+
182
+ return nativeFetch.call(this, input, init);
183
+ };
184
+
185
+ logOnce('installed', 'debug', '已安装 /v2/c/ 请求改签拦截');
186
+ })();
@@ -17,6 +17,8 @@ options:
17
17
  value: mp4
18
18
  - label: png
19
19
  value: png
20
+ - label: gif
21
+ value: gif
20
22
  required: true
21
23
  sort_no: 150
22
24
  type: select
@@ -1,9 +1,24 @@
1
1
  name: pls_file
2
2
  amis:
3
3
  id: 'u:be441c91bd73'
4
+ # 覆盖平台默认的 file 只读渲染。平台默认取 ${pls_file|asArray} 的 value/name,
5
+ # 该值只有列表视图的响应适配器(getTableApi)会重写成对象数组; lookup 弹窗(picker)的
6
+ # 适配器没有这段重写, 字段值仍是裸文件 id 字符串, 导致 value 取空 ->
7
+ # 点击后打开 cfs_files_filerecord 记录抽屉时报"无法找到记录"。
8
+ # 这里统一改为从 _display 取值(列表、lookup 弹窗、记录详情三处都有 _display),
9
+ # 并去掉 url 上的 download 参数, 让 PDF 在新标签页内联预览而不是直接下载。
10
+ body:
11
+ type: each
12
+ source: '${_display.pls_file|asArray}'
13
+ className: flex flex-col
14
+ items:
15
+ type: tpl
16
+ tpl: >-
17
+ <% if(data && data.url){ %><a href="<%= data.url.split('?')[0] %>"
18
+ target="_blank"><%= data.name %></a><% } %>
4
19
  group: 上传信息
5
20
  is_wide: true
6
- label: PLS原始文件查看
21
+ label: PLS文件
7
22
  readonly: true
8
23
  required: false
9
24
  sort_no: 150
@@ -1,6 +1,8 @@
1
1
  name: lookup
2
2
  columns:
3
- - field: name
3
+ - field: pls_file
4
+ width: '300'
5
+ wrap: true
4
6
  - field: product_name
5
7
  - field: brand
6
8
  - field: issue_date
@@ -0,0 +1,9 @@
1
+ name: agency_contract_expiry_date
2
+ amis:
3
+ id: 'u:agency_contract_expiry_date'
4
+ group: 系统信息
5
+ label: Agency合同截止日期
6
+ required: false
7
+ sort_no: 1710
8
+ type: date
9
+ visible_on: '{{global.user.is_space_admin}}'
@@ -0,0 +1,14 @@
1
+ name: agency_pepsico_contact
2
+ amis:
3
+ id: 'u:agency_pepsico_contact'
4
+ filters: []
5
+ group: 系统信息
6
+ is_wide: false
7
+ label: Agency百事内部对接人
8
+ multiple: false
9
+ reference_to: space_users
10
+ reference_to_field: user
11
+ required: false
12
+ sort_no: 1720
13
+ type: lookup
14
+ visible_on: '{{global.user.is_space_admin}}'