@things-factory/shell 10.1.46 → 10.1.47
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/dist-server/middlewares/domain-middleware.d.ts +12 -0
- package/dist-server/middlewares/domain-middleware.js +19 -4
- package/dist-server/middlewares/domain-middleware.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/tests/domain-middleware-refusal.test.ts +44 -0
- package/tests/undefined-custom-properties.test.ts +4 -13
- package/translations/en.json +12 -1
- package/translations/ja.json +12 -1
- package/translations/ko.json +15 -4
- package/translations/ms.json +12 -1
- package/translations/zh.json +12 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/shell",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.47",
|
|
4
4
|
"description": "Core module for framework",
|
|
5
5
|
"bin": {
|
|
6
6
|
"things-factory": "bin/things-factory",
|
|
@@ -126,5 +126,5 @@
|
|
|
126
126
|
"pg": "^8.7.3",
|
|
127
127
|
"sqlite3": "^5.0.8"
|
|
128
128
|
},
|
|
129
|
-
"gitHead": "
|
|
129
|
+
"gitHead": "185f20d7d9a15715a0ee2757a6a8189ec36cfb9d"
|
|
130
130
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* The domain is given in state, so the URL lookup is never reached - and importing it drags in every entity. */
|
|
2
|
+
jest.mock('../server/utils/get-domain', () => ({ getDomainFromURL: jest.fn() }))
|
|
3
|
+
|
|
4
|
+
import { domainMiddleware, REFUSAL_HEADER, REFUSED_ADDRESS } from '../server/middlewares/domain-middleware'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A request refused by the domain's IP lists says why (ADR README plan 3, left open there).
|
|
8
|
+
*
|
|
9
|
+
* The same 403 also means "no domain chosen", and the client answers that by sending the person to
|
|
10
|
+
* check-in. For a refused address check-in sends them straight back, so the client has to tell the
|
|
11
|
+
* two apart - the header is how. Anything that is not an address refusal carries no header.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
function run(iplist: any, ip: string) {
|
|
15
|
+
const headers: Record<string, string> = {}
|
|
16
|
+
const context: any = {
|
|
17
|
+
state: { domain: { id: 'd1', iplist } },
|
|
18
|
+
req: { headers: { 'x-client-ip': ip }, connection: {}, socket: {} },
|
|
19
|
+
status: 200,
|
|
20
|
+
set: (name: string, value: string) => (headers[name.toLowerCase()] = value)
|
|
21
|
+
}
|
|
22
|
+
let passed = false
|
|
23
|
+
return domainMiddleware(context, async () => {
|
|
24
|
+
passed = true
|
|
25
|
+
}).then(() => ({ status: context.status, headers, passed }))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('domain middleware - an address the domain does not let in', () => {
|
|
29
|
+
it('★ outside the whitelist: 403, and it says the address was refused', async () => {
|
|
30
|
+
const result = await run({ whitelist: ['^10\\.'] }, '192.168.0.9')
|
|
31
|
+
expect(result).toEqual({ status: 403, headers: { [REFUSAL_HEADER]: REFUSED_ADDRESS }, passed: false })
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('★ on the blacklist: 403, and it says the address was refused', async () => {
|
|
35
|
+
const result = await run({ blacklist: ['^192\\.168\\.'] }, '192.168.0.9')
|
|
36
|
+
expect(result).toEqual({ status: 403, headers: { [REFUSAL_HEADER]: REFUSED_ADDRESS }, passed: false })
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('★ an address that is let in passes with no refusal header', async () => {
|
|
40
|
+
expect(await run({ whitelist: ['^10\\.'] }, '10.0.0.1')).toEqual({ status: 200, headers: {}, passed: true })
|
|
41
|
+
expect(await run({ blacklist: ['^192\\.168\\.'] }, '10.0.0.1')).toEqual({ status: 200, headers: {}, passed: true })
|
|
42
|
+
expect(await run(undefined, '10.0.0.1')).toEqual({ status: 200, headers: {}, passed: true })
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -91,8 +91,9 @@ const HOOKS = [
|
|
|
91
91
|
]
|
|
92
92
|
|
|
93
93
|
/*
|
|
94
|
-
* The installed operato components, as of @operato 10.
|
|
95
|
-
*
|
|
94
|
+
* The installed operato components, as of @operato 10.24-10.25 (process is not installed here). The ten
|
|
95
|
+
* typos fixed in 10.23 left this list with that install. What remains is read in operato and defined by
|
|
96
|
+
* no product we checked; a name leaves when something defines it or the read goes.
|
|
96
97
|
*/
|
|
97
98
|
const OPERATO_KNOWN = [
|
|
98
99
|
'--button-radius',
|
|
@@ -100,19 +101,9 @@ const OPERATO_KNOWN = [
|
|
|
100
101
|
'--component-detail-border-color',
|
|
101
102
|
'--form-input-width',
|
|
102
103
|
'--grid-record-focused-color',
|
|
103
|
-
'--legend-background-color',
|
|
104
|
-
'--legend-border',
|
|
105
|
-
'--legend-border-radius',
|
|
106
|
-
'--legend-margin',
|
|
107
|
-
'--md-sys-color-on-primary-container-rgb',
|
|
108
|
-
'--md-sys-on-color-secondary',
|
|
109
|
-
'--md-sys-shape-corner-tiny',
|
|
110
|
-
'--md-sys-typescale-label-medium-weight',
|
|
111
104
|
'--opacity-light-dark-color',
|
|
112
|
-
'--pading-default',
|
|
113
105
|
'--record-view-edit-border',
|
|
114
|
-
'--record-view-grid-field-border'
|
|
115
|
-
'--spacing-smail'
|
|
106
|
+
'--record-view-grid-field-border'
|
|
116
107
|
]
|
|
117
108
|
|
|
118
109
|
describe('custom properties read with no fallback are defined', () => {
|
package/translations/en.json
CHANGED
|
@@ -132,6 +132,9 @@
|
|
|
132
132
|
"text.data_uploaded_successfully": "data uploaded successfully",
|
|
133
133
|
"text.draft": "draft",
|
|
134
134
|
"text.entity360-not-yet": "there is no 360 for this kind yet.",
|
|
135
|
+
"text.entity360-none": "none",
|
|
136
|
+
"text.entity360-forbidden": "you may not see this",
|
|
137
|
+
"text.entity360-failed": "could not be read",
|
|
135
138
|
"text.error": "error",
|
|
136
139
|
"text.existing_item_found": "existing item found",
|
|
137
140
|
"text.failed": "failed",
|
|
@@ -166,5 +169,13 @@
|
|
|
166
169
|
"term.domain": "site",
|
|
167
170
|
"field.roles": "roles",
|
|
168
171
|
"label.released": "released",
|
|
169
|
-
"label.import": "import"
|
|
172
|
+
"label.import": "import",
|
|
173
|
+
"error.address-not-allowed": "this site does not accept connections from where you are. ask its administrator.",
|
|
174
|
+
"button.undo": "undo",
|
|
175
|
+
"button.redo": "redo",
|
|
176
|
+
"button.fit-view": "fit to view",
|
|
177
|
+
"button.hide-start-pane": "hide the left pane",
|
|
178
|
+
"button.show-start-pane": "show the left pane",
|
|
179
|
+
"button.hide-end-pane": "hide the right pane",
|
|
180
|
+
"button.show-end-pane": "show the right pane"
|
|
170
181
|
}
|
package/translations/ja.json
CHANGED
|
@@ -132,6 +132,9 @@
|
|
|
132
132
|
"text.data_uploaded_successfully": "資料が正常に作成されました.",
|
|
133
133
|
"text.draft": "ドラフト保存",
|
|
134
134
|
"text.entity360-not-yet": "この種類の 360 はまだありません。",
|
|
135
|
+
"text.entity360-none": "なし",
|
|
136
|
+
"text.entity360-forbidden": "閲覧できません",
|
|
137
|
+
"text.entity360-failed": "読み込めませんでした",
|
|
135
138
|
"text.error": "エラー",
|
|
136
139
|
"text.existing_item_found": "既にある項目です",
|
|
137
140
|
"text.failed": "失敗",
|
|
@@ -166,5 +169,13 @@
|
|
|
166
169
|
"term.domain": "事業場",
|
|
167
170
|
"field.roles": "ロール",
|
|
168
171
|
"label.released": "公開済み",
|
|
169
|
-
"label.import": "インポート"
|
|
172
|
+
"label.import": "インポート",
|
|
173
|
+
"error.address-not-allowed": "この事業所は現在の場所からの接続を受け付けていません。事業所の管理者にお問い合わせください。",
|
|
174
|
+
"button.undo": "元に戻す",
|
|
175
|
+
"button.redo": "やり直す",
|
|
176
|
+
"button.fit-view": "画面に合わせる",
|
|
177
|
+
"button.hide-start-pane": "左のパネルを閉じる",
|
|
178
|
+
"button.show-start-pane": "左のパネルを開く",
|
|
179
|
+
"button.hide-end-pane": "右のパネルを閉じる",
|
|
180
|
+
"button.show-end-pane": "右のパネルを開く"
|
|
170
181
|
}
|
package/translations/ko.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"button.collapse": "줄이기",
|
|
7
7
|
"button.confirm": "확인",
|
|
8
8
|
"button.copy": "복사",
|
|
9
|
-
"button.copy to draft": "
|
|
9
|
+
"button.copy to draft": "초안으로 복사",
|
|
10
10
|
"button.create": "생성",
|
|
11
11
|
"button.delete": "삭제",
|
|
12
12
|
"button.detail": "상세",
|
|
@@ -132,6 +132,9 @@
|
|
|
132
132
|
"text.data_uploaded_successfully": "성공적으로 자료를 업로드하였습니다.",
|
|
133
133
|
"text.draft": "초안저장",
|
|
134
134
|
"text.entity360-not-yet": "이 종류의 360 은 아직 없습니다.",
|
|
135
|
+
"text.entity360-none": "없음",
|
|
136
|
+
"text.entity360-forbidden": "볼 수 없음",
|
|
137
|
+
"text.entity360-failed": "읽지 못함",
|
|
135
138
|
"text.error": "오류",
|
|
136
139
|
"text.existing_item_found": "이미 있는 항목입니다",
|
|
137
140
|
"text.failed": "실패",
|
|
@@ -140,12 +143,12 @@
|
|
|
140
143
|
"text.initial version all new": "최초 버전 — 전체 신규",
|
|
141
144
|
"text.loading": "읽는 중…",
|
|
142
145
|
"text.no difference from previous": "앞 버전과 차이가 없습니다",
|
|
143
|
-
"text.no released version information available": "
|
|
146
|
+
"text.no released version information available": "발행된 버전이 없습니다",
|
|
144
147
|
"text.nothing_changed": "변경사항 없음",
|
|
145
148
|
"text.nothing_selected": "선택되지 않음",
|
|
146
149
|
"text.offline": "오프라인",
|
|
147
150
|
"text.online": "온라인",
|
|
148
|
-
"text.release comment optional": "
|
|
151
|
+
"text.release comment optional": "발행 메모(선택) — 비우면 자동으로 채웁니다",
|
|
149
152
|
"text.saved": "저장되었습니다",
|
|
150
153
|
"text.sure_to_x": "{x}하시겠습니까?",
|
|
151
154
|
"text.technical detail": "기술 정보",
|
|
@@ -166,5 +169,13 @@
|
|
|
166
169
|
"term.domain": "사업장",
|
|
167
170
|
"field.roles": "역할",
|
|
168
171
|
"label.released": "발행됨",
|
|
169
|
-
"label.import": "가져오기"
|
|
172
|
+
"label.import": "가져오기",
|
|
173
|
+
"error.address-not-allowed": "이 사업장은 지금 계신 곳에서의 접속을 받지 않습니다. 사업장 관리자에게 문의하십시오.",
|
|
174
|
+
"button.undo": "되돌리기",
|
|
175
|
+
"button.redo": "다시 실행",
|
|
176
|
+
"button.fit-view": "화면에 맞추기",
|
|
177
|
+
"button.hide-start-pane": "왼쪽 판 접기",
|
|
178
|
+
"button.show-start-pane": "왼쪽 판 펼치기",
|
|
179
|
+
"button.hide-end-pane": "오른쪽 판 접기",
|
|
180
|
+
"button.show-end-pane": "오른쪽 판 펼치기"
|
|
170
181
|
}
|
package/translations/ms.json
CHANGED
|
@@ -132,6 +132,9 @@
|
|
|
132
132
|
"text.data_uploaded_successfully": "data uploaded successfully",
|
|
133
133
|
"text.draft": "draf",
|
|
134
134
|
"text.entity360-not-yet": "belum ada 360 untuk jenis ini.",
|
|
135
|
+
"text.entity360-none": "tiada",
|
|
136
|
+
"text.entity360-forbidden": "anda tidak boleh melihat ini",
|
|
137
|
+
"text.entity360-failed": "tidak dapat dibaca",
|
|
135
138
|
"text.error": "Ralat",
|
|
136
139
|
"text.existing_item_found": "item ini sudah ada",
|
|
137
140
|
"text.failed": "gagal",
|
|
@@ -166,5 +169,13 @@
|
|
|
166
169
|
"term.domain": "tapak",
|
|
167
170
|
"field.roles": "peranan",
|
|
168
171
|
"label.released": "diterbitkan",
|
|
169
|
-
"label.import": "import"
|
|
172
|
+
"label.import": "import",
|
|
173
|
+
"error.address-not-allowed": "tapak ini tidak menerima sambungan dari lokasi anda. sila hubungi pentadbirnya.",
|
|
174
|
+
"button.undo": "buat asal",
|
|
175
|
+
"button.redo": "buat semula",
|
|
176
|
+
"button.fit-view": "muat ke paparan",
|
|
177
|
+
"button.hide-start-pane": "sembunyikan panel kiri",
|
|
178
|
+
"button.show-start-pane": "tunjukkan panel kiri",
|
|
179
|
+
"button.hide-end-pane": "sembunyikan panel kanan",
|
|
180
|
+
"button.show-end-pane": "tunjukkan panel kanan"
|
|
170
181
|
}
|
package/translations/zh.json
CHANGED
|
@@ -132,6 +132,9 @@
|
|
|
132
132
|
"text.data_uploaded_successfully": "数据上传成功。",
|
|
133
133
|
"text.draft": "草稿",
|
|
134
134
|
"text.entity360-not-yet": "此类暂无 360 视图。",
|
|
135
|
+
"text.entity360-none": "无",
|
|
136
|
+
"text.entity360-forbidden": "无权查看",
|
|
137
|
+
"text.entity360-failed": "无法读取",
|
|
135
138
|
"text.error": "错误",
|
|
136
139
|
"text.existing_item_found": "该项目已存在",
|
|
137
140
|
"text.failed": "失败",
|
|
@@ -166,5 +169,13 @@
|
|
|
166
169
|
"field.roles": "角色",
|
|
167
170
|
"term.domain": "站点",
|
|
168
171
|
"label.released": "已发布",
|
|
169
|
-
"label.import": "导入"
|
|
172
|
+
"label.import": "导入",
|
|
173
|
+
"error.address-not-allowed": "此站点不接受来自您当前位置的连接。请联系站点管理员。",
|
|
174
|
+
"button.undo": "撤销",
|
|
175
|
+
"button.redo": "重做",
|
|
176
|
+
"button.fit-view": "适应视图",
|
|
177
|
+
"button.hide-start-pane": "收起左侧面板",
|
|
178
|
+
"button.show-start-pane": "展开左侧面板",
|
|
179
|
+
"button.hide-end-pane": "收起右侧面板",
|
|
180
|
+
"button.show-end-pane": "展开右侧面板"
|
|
170
181
|
}
|