@things-factory/shell 10.1.46 → 10.1.79

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/shell",
3
- "version": "10.1.46",
3
+ "version": "10.1.79",
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": "d3467cde550453f3348fed0ed6c79a12a6ba0db4"
129
+ "gitHead": "94cde9ba17dfdddb0a16139b71e5a7e370977e4a"
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.19-10.22 (process is not installed here). The fixed typos leave this list when the
95
- * next @operato release is installed - the test goes red then, and the line is deleted with it.
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', () => {
@@ -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,18 @@
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",
181
+ "title.unsaved-draft": "there is an unsaved edit",
182
+ "text.unsaved-draft-kept": "what you changed {minutes} minutes ago is still kept in this browser.",
183
+ "text.unsaved-draft-behind": "it has been saved again since then. saving will tell you about the conflict.",
184
+ "button.resume-editing": "resume editing",
185
+ "button.discard": "discard"
170
186
  }
@@ -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,18 @@
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": "右のパネルを開く",
181
+ "title.unsaved-draft": "保存していない編集があります",
182
+ "text.unsaved-draft-kept": "{minutes}分前に変更した内容がこのブラウザに残っています。",
183
+ "text.unsaved-draft-behind": "その後、再び保存されています。保存するときに競合をお知らせします。",
184
+ "button.resume-editing": "編集を続ける",
185
+ "button.discard": "破棄"
170
186
  }
@@ -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,18 @@
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": "오른쪽 판 펼치기",
181
+ "title.unsaved-draft": "저장하지 않은 편집이 있습니다",
182
+ "text.unsaved-draft-kept": "{minutes}분 전에 고친 내용이 이 브라우저에 남아 있습니다.",
183
+ "text.unsaved-draft-behind": "그 뒤에 다시 저장되었습니다. 저장할 때 충돌을 알려 드립니다.",
184
+ "button.resume-editing": "이어서 편집",
185
+ "button.discard": "버리기"
170
186
  }
@@ -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,18 @@
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",
181
+ "title.unsaved-draft": "ada suntingan yang belum disimpan",
182
+ "text.unsaved-draft-kept": "perubahan yang anda buat {minutes} minit lalu masih disimpan dalam pelayar ini.",
183
+ "text.unsaved-draft-behind": "ia telah disimpan semula sejak itu. semasa menyimpan, anda akan dimaklumkan tentang konflik.",
184
+ "button.resume-editing": "sambung menyunting",
185
+ "button.discard": "buang"
170
186
  }
@@ -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,18 @@
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": "展开右侧面板",
181
+ "title.unsaved-draft": "有未保存的编辑",
182
+ "text.unsaved-draft-kept": "您 {minutes} 分钟前所做的更改仍保留在此浏览器中。",
183
+ "text.unsaved-draft-behind": "此后已被再次保存。保存时会提示冲突。",
184
+ "button.resume-editing": "继续编辑",
185
+ "button.discard": "放弃"
170
186
  }