feat(hololake): connect enterprise device challenge flow
This commit is contained in:
parent
be31c4136b
commit
6b23f710e1
19 changed files with 1220 additions and 14 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"schema": "hololake.enterprise-responsibility-entrance/v1",
|
"schema": "hololake.enterprise-responsibility-entrance/v1",
|
||||||
"contract_id": "HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001",
|
"contract_id": "HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001",
|
||||||
"state": "LOCAL_DEVICE_PROOF_INSTALLED_KEYCHAIN_VERIFIED_SERVER_GATE_SOURCE_TESTED_DEPLOYMENT_PENDING",
|
"state": "SERVER_DEVICE_GATE_ACTIVE_CLIENT_ENROLLMENT_AND_CHALLENGE_SOURCE_IMPLEMENTED_REBUILD_PENDING",
|
||||||
|
"endpoint": "https://guanghu.chat/api/hololake/enterprise/device-gate",
|
||||||
"surface": "HOLOLAKE_GATED_ENTERPRISE_PORTAL",
|
"surface": "HOLOLAKE_GATED_ENTERPRISE_PORTAL",
|
||||||
"enterprise_server_embedded": false,
|
"enterprise_server_embedded": false,
|
||||||
"identities": ["DOMAIN_ID", "RESPONSIBLE_HUMAN_ID", "BOUND_PERSONA_ID", "LOCAL_NODE_ID", "DEVICE_KEY_ID"],
|
"identities": ["DOMAIN_ID", "RESPONSIBLE_HUMAN_ID", "BOUND_PERSONA_ID", "LOCAL_NODE_ID", "DEVICE_KEY_ID"],
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
TCS 0.1;
|
||||||
|
|
||||||
|
RECEIPT HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903 {
|
||||||
|
header { schema = "tcs.receipt/v1"; name_zh = "HoloLake企业责任设备门部署回执"; name_en = "HoloLake Enterprise Responsibility Device Gate Deployment Receipt"; version = "1.0.0"; language = "TCS/0.1"; profile = "PUBLIC-PRODUCT-ENGINEERING/1"; protocols = ["HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903", "HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001"]; lifecycle = "CANDIDATE"; canonical_uri = "product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903.tcs"; compatibility = ["GH-CVM-MAIN-PROD-01", "PYTHON/3.10", "ED25519", "NGINX"]; }
|
||||||
|
request { source = "BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903"; value = "部署企业四域负责人通过HoloLake本机设备和人格编号验证后进入本人责任仓库的服务端验证门。"; scope = "GH-CVM-MAIN-PROD-01独立8033服务与精确Nginx路由"; }
|
||||||
|
operation { values = ["验证源码运输归档与manifest", "解包到/opt/guanghu-hololake-enterprise-gate/releases/be31c41", "创建独立lighthouse权限数据库与服务密钥", "安装guanghu-hololake-enterprise-gate.service", "加入guanghu.chat精确device-gate路由", "执行本地和外部健康、未知设备拒绝及原服务存活测试" ]; }
|
||||||
|
result { state = "PASS"; node_id = "GH-CVM-MAIN-PROD-01"; service = "guanghu-hololake-enterprise-gate.service"; service_state = "ACTIVE"; endpoint = "https://guanghu.chat/api/hololake/enterprise/device-gate"; source_commit = "be31c41"; source_archive_sha256 = "91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2"; registered_devices = 0; active_sessions = 0; }
|
||||||
|
verification { values = ["DMI UUID为10ace744-13e1-472e-8dba-6bb823a073bf", "服务器Python cryptography Ed25519测试2项通过", "systemd服务active", "127.0.0.1:8033/health返回ok", "外部HTTPS device-gate/health返回ok", "未知设备领取挑战返回HTTP404 registered device required", "guanghu-enterprise-identity.service保持active", "guanghu-flagos-collaboration.service保持active", "nginx.service保持active", "当前设备与会话数量均为0未伪造成员" ]; }
|
||||||
|
proof { server_release = "/opt/guanghu-hololake-enterprise-gate/releases/be31c41"; current_link = "/opt/guanghu-hololake-enterprise-gate/current"; database = "/var/lib/guanghu-hololake-enterprise-gate/gate.sqlite3"; nginx_snippet = "/etc/nginx/snippets/guanghu-hololake-enterprise-gate.conf"; nginx_backup = "/etc/nginx/sites-enabled/guanghu.chat.pre-hololake-device-gate-be31c41"; }
|
||||||
|
integrity { source_transport_manifest_sha256 = "653ae0ca824fd8b9fff8d8532e82eddce63a8aa9f070e7a6aa3f863834e4ae77"; source_archive_sha256 = "91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2"; tcs_stage1_compilation = "PASS"; unknown_device_negative = "PASS"; existing_services_preserved = "PASS"; }
|
||||||
|
boundaries { values = ["服务不保存Forgejo密码", "设备私钥从不离开成员本机Keychain", "机器指纹不能单独认证", "会话只限单域单仓且十分钟过期", "企业会话不替代Forgejo自身仓库登录", "冰朔公共语言主控仓继续走JD第五域桥接而非普通人类登录", "本轮未登记任何真实成员设备" ]; }
|
||||||
|
next { state = "SERVER_GATE_ACTIVE_CLIENT_INTEGRATION_REBUILD_REQUIRED"; optional = ["团队成员从HoloLake使用本人凭证完成首次设备登记", "正向验证挑战与单仓会话", "后续加入个人服务器二次桥接证明" ]; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
TCS 0.1;
|
||||||
|
|
||||||
|
EVENT HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903 {
|
||||||
|
header { schema = "tcs.event/v1"; name_zh = "HoloLake企业责任设备门部署开始事件"; name_en = "HoloLake Enterprise Responsibility Device Gate Deployment Start Event"; version = "1.0.0"; language = "TCS/0.1"; profile = "PUBLIC-PRODUCT-ENGINEERING/1"; protocols = ["HOLOLAKE-CLEAN-V1-DIRECT-LANGUAGE-EXECUTION-BASELINE-0001", "HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001"]; lifecycle = "CANDIDATE"; canonical_uri = "product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903.tcs"; compatibility = ["GH-CVM-MAIN-PROD-01", "PYTHON/3.10", "ED25519"]; }
|
||||||
|
source { source_id = "BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903"; source_uri = "source://codex-task/01a0672d-f125-7452-988e-523a6a34bfd4/msg_01a0675d-98a7-7542-abad-11a8a755dd71"; source_sha256 = "d31c52c99c5e6059f9a7129086996cdd003e95b7ff126e700f4ed1c07ef6d9d5"; source_role = "DIRECT_HUMAN"; }
|
||||||
|
subject { subject_id = "GH-CVM-MAIN-PROD-01"; subject_kind = "NODE"; channel_id = "ICE-CH-ZC001"; verification = "DMI UUID 10ace744-13e1-472e-8dba-6bb823a073bf;另一个FlagOS任务已完成且独立服务健康。"; }
|
||||||
|
event_time { value = "2026-09-03T21:45:00+08:00"; precision = "MINUTE_HOST_LOCAL"; }
|
||||||
|
trigger { value = "本机HoloLake 1.2.0设备密钥与责任绑定请求已实现并验收,需要在企业服务器部署独立设备挑战验证半边。"; }
|
||||||
|
observation { value = "现有8032企业身份服务保持运行;8033空闲;cryptography Ed25519可用;目标目录不存在;源码提交be31c41且运输归档SHA-256为91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2。"; }
|
||||||
|
emergence { value = "采用独立8033服务、独立数据库和独立Nginx snippet,避免修改现有身份服务与FlagOS协作系统;只复用只读企业身份注册表与Forgejo当次认证。"; }
|
||||||
|
lock { value = "SOURCE_COMMIT=be31c41; TARGET=/opt/guanghu-hololake-enterprise-gate/releases/be31c41; ROLLBACK=disable独立服务并移除Nginx include后恢复原配置;不修改8032与FlagOS。"; }
|
||||||
|
why { value = "设备挑战属于HoloLake责任入口新能力,应与现有账号、关系回执和比赛服务隔离,失败时能独立撤回。"; }
|
||||||
|
rejected { values = ["直接改写8032现有服务", "把私钥上传服务器", "用机器指纹单独授权", "把企业会话变成Forgejo永久令牌", "重启或修改FlagOS服务", "未验证运输哈希就解包"] ; }
|
||||||
|
evidence { transport_manifest = "/Volumes/JZAO/HoloLake/releases/source-transport/hololake-enterprise-responsibility-gate-be31c41.manifest.json"; archive_sha256 = "91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2"; expected_receipt = "目标服务健康、未知设备拒绝、签名正负测试、现有身份与FlagOS服务保持健康。"; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
{
|
||||||
|
"compiled_from": {
|
||||||
|
"compiler_id": "TCS-COMPILER-STAGE1-0001",
|
||||||
|
"compiler_state": "TCS_COMPILER_GIR_EXECUTED",
|
||||||
|
"source_sha256": "c32cd3e16fdd64588addca115821a49bb47bf39b584670df031cf92028a8d232"
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"boundaries": {
|
||||||
|
"values": [
|
||||||
|
"服务不保存Forgejo密码",
|
||||||
|
"设备私钥从不离开成员本机Keychain",
|
||||||
|
"机器指纹不能单独认证",
|
||||||
|
"会话只限单域单仓且十分钟过期",
|
||||||
|
"企业会话不替代Forgejo自身仓库登录",
|
||||||
|
"冰朔公共语言主控仓继续走JD第五域桥接而非普通人类登录",
|
||||||
|
"本轮未登记任何真实成员设备"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"canonical_uri": "product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903.tcs",
|
||||||
|
"compatibility": [
|
||||||
|
"GH-CVM-MAIN-PROD-01",
|
||||||
|
"PYTHON/3.10",
|
||||||
|
"ED25519",
|
||||||
|
"NGINX"
|
||||||
|
],
|
||||||
|
"language": "TCS/0.1",
|
||||||
|
"lifecycle": "CANDIDATE",
|
||||||
|
"name_en": "HoloLake Enterprise Responsibility Device Gate Deployment Receipt",
|
||||||
|
"name_zh": "HoloLake企业责任设备门部署回执",
|
||||||
|
"profile": "PUBLIC-PRODUCT-ENGINEERING/1",
|
||||||
|
"protocols": [
|
||||||
|
"HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903",
|
||||||
|
"HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001"
|
||||||
|
],
|
||||||
|
"schema": "tcs.receipt/v1",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"integrity": {
|
||||||
|
"existing_services_preserved": "PASS",
|
||||||
|
"source_archive_sha256": "91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2",
|
||||||
|
"source_transport_manifest_sha256": "653ae0ca824fd8b9fff8d8532e82eddce63a8aa9f070e7a6aa3f863834e4ae77",
|
||||||
|
"tcs_stage1_compilation": "PASS",
|
||||||
|
"unknown_device_negative": "PASS"
|
||||||
|
},
|
||||||
|
"next": {
|
||||||
|
"optional": [
|
||||||
|
"团队成员从HoloLake使用本人凭证完成首次设备登记",
|
||||||
|
"正向验证挑战与单仓会话",
|
||||||
|
"后续加入个人服务器二次桥接证明"
|
||||||
|
],
|
||||||
|
"state": "SERVER_GATE_ACTIVE_CLIENT_INTEGRATION_REBUILD_REQUIRED"
|
||||||
|
},
|
||||||
|
"operation": {
|
||||||
|
"values": [
|
||||||
|
"验证源码运输归档与manifest",
|
||||||
|
"解包到/opt/guanghu-hololake-enterprise-gate/releases/be31c41",
|
||||||
|
"创建独立lighthouse权限数据库与服务密钥",
|
||||||
|
"安装guanghu-hololake-enterprise-gate.service",
|
||||||
|
"加入guanghu.chat精确device-gate路由",
|
||||||
|
"执行本地和外部健康、未知设备拒绝及原服务存活测试"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"proof": {
|
||||||
|
"current_link": "/opt/guanghu-hololake-enterprise-gate/current",
|
||||||
|
"database": "/var/lib/guanghu-hololake-enterprise-gate/gate.sqlite3",
|
||||||
|
"nginx_backup": "/etc/nginx/sites-enabled/guanghu.chat.pre-hololake-device-gate-be31c41",
|
||||||
|
"nginx_snippet": "/etc/nginx/snippets/guanghu-hololake-enterprise-gate.conf",
|
||||||
|
"server_release": "/opt/guanghu-hololake-enterprise-gate/releases/be31c41"
|
||||||
|
},
|
||||||
|
"request": {
|
||||||
|
"scope": "GH-CVM-MAIN-PROD-01独立8033服务与精确Nginx路由",
|
||||||
|
"source": "BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903",
|
||||||
|
"value": "部署企业四域负责人通过HoloLake本机设备和人格编号验证后进入本人责任仓库的服务端验证门。"
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"active_sessions": 0,
|
||||||
|
"endpoint": "https://guanghu.chat/api/hololake/enterprise/device-gate",
|
||||||
|
"node_id": "GH-CVM-MAIN-PROD-01",
|
||||||
|
"registered_devices": 0,
|
||||||
|
"service": "guanghu-hololake-enterprise-gate.service",
|
||||||
|
"service_state": "ACTIVE",
|
||||||
|
"source_archive_sha256": "91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2",
|
||||||
|
"source_commit": "be31c41",
|
||||||
|
"state": "PASS"
|
||||||
|
},
|
||||||
|
"verification": {
|
||||||
|
"values": [
|
||||||
|
"DMI UUID为10ace744-13e1-472e-8dba-6bb823a073bf",
|
||||||
|
"服务器Python cryptography Ed25519测试2项通过",
|
||||||
|
"systemd服务active",
|
||||||
|
"127.0.0.1:8033/health返回ok",
|
||||||
|
"外部HTTPS device-gate/health返回ok",
|
||||||
|
"未知设备领取挑战返回HTTP404 registered device required",
|
||||||
|
"guanghu-enterprise-identity.service保持active",
|
||||||
|
"guanghu-flagos-collaboration.service保持active",
|
||||||
|
"nginx.service保持active",
|
||||||
|
"当前设备与会话数量均为0未伪造成员"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"executable": false,
|
||||||
|
"identity": {
|
||||||
|
"declaration_id": "HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903",
|
||||||
|
"declaration_kind": "RECEIPT",
|
||||||
|
"language_version": "0.1"
|
||||||
|
},
|
||||||
|
"native_self_hosted": true,
|
||||||
|
"natural_language_is_typed_data": true,
|
||||||
|
"schema": "guanghu.declaration-gir/v1",
|
||||||
|
"unresolved_natural_language": false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
# HoloLake Enterprise Responsibility Device Gate Deployment Receipt · Human Engineering Language (English)
|
||||||
|
|
||||||
|
> This is an English reading projection of validated native TCS/HLDP source. It is not a new canonical source and grants no execution authority.
|
||||||
|
|
||||||
|
## What this is
|
||||||
|
|
||||||
|
This is a **receipt** declaration with identifier `HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903` and version `1.0.0`. The projector validates it with the Stage-1 compiler before changing its reading order.
|
||||||
|
|
||||||
|
## Who is here
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## Why this started
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## What changed
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## How it will execute
|
||||||
|
|
||||||
|
This is a non-executable declaration and has no action graph.
|
||||||
|
|
||||||
|
## Boundaries and exception handling
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## How completion is proven
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## Where to continue next time
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## Source and verification
|
||||||
|
|
||||||
|
- **Native declaration identifier**: `HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903`
|
||||||
|
- **Native declaration kind**: `RECEIPT`
|
||||||
|
- **TCS source SHA-256**: `c32cd3e16fdd64588addca115821a49bb47bf39b584670df031cf92028a8d232`
|
||||||
|
- **Validation compiler**: `TCS-COMPILER-STAGE1-0001`
|
||||||
|
- **Projection protocol**: `GLS-HLDP-HUMAN-ENGINEERING-PROJECTION-0001`
|
||||||
|
|
||||||
|
## Complete native structure cross-reference
|
||||||
|
|
||||||
|
All top-level structures and field paths are retained below so a reader can audit whether the projection omitted information.
|
||||||
|
|
||||||
|
- **boundaries** `boundaries`
|
||||||
|
- **values** `boundaries.values`
|
||||||
|
- 服务不保存Forgejo密码
|
||||||
|
- 设备私钥从不离开成员本机Keychain
|
||||||
|
- 机器指纹不能单独认证
|
||||||
|
- 会话只限单域单仓且十分钟过期
|
||||||
|
- 企业会话不替代Forgejo自身仓库登录
|
||||||
|
- 冰朔公共语言主控仓继续走JD第五域桥接而非普通人类登录
|
||||||
|
- 本轮未登记任何真实成员设备
|
||||||
|
- **header** `header`
|
||||||
|
- **canonical source path**:product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903.tcs `header.canonical_uri`
|
||||||
|
- **compatibility** `header.compatibility`
|
||||||
|
- GH-CVM-MAIN-PROD-01
|
||||||
|
- PYTHON/3.10
|
||||||
|
- ED25519
|
||||||
|
- NGINX
|
||||||
|
- **language**:TCS/0.1 `header.language`
|
||||||
|
- **lifecycle**:CANDIDATE `header.lifecycle`
|
||||||
|
- **English name**:HoloLake Enterprise Responsibility Device Gate Deployment Receipt `header.name_en`
|
||||||
|
- **Chinese name**:HoloLake企业责任设备门部署回执 `header.name_zh`
|
||||||
|
- **profile**:PUBLIC-PRODUCT-ENGINEERING/1 `header.profile`
|
||||||
|
- **protocols** `header.protocols`
|
||||||
|
- HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903
|
||||||
|
- HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001
|
||||||
|
- **schema**:tcs.receipt/v1 `header.schema`
|
||||||
|
- **version**:1.0.0 `header.version`
|
||||||
|
- **integrity** `integrity`
|
||||||
|
- **existing_services_preserved**:PASS `integrity.existing_services_preserved`
|
||||||
|
- **source_archive_sha256**:91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2 `integrity.source_archive_sha256`
|
||||||
|
- **source_transport_manifest_sha256**:653ae0ca824fd8b9fff8d8532e82eddce63a8aa9f070e7a6aa3f863834e4ae77 `integrity.source_transport_manifest_sha256`
|
||||||
|
- **tcs_stage1_compilation**:PASS `integrity.tcs_stage1_compilation`
|
||||||
|
- **unknown_device_negative**:PASS `integrity.unknown_device_negative`
|
||||||
|
- **next** `next`
|
||||||
|
- **optional** `next.optional`
|
||||||
|
- 团队成员从HoloLake使用本人凭证完成首次设备登记
|
||||||
|
- 正向验证挑战与单仓会话
|
||||||
|
- 后续加入个人服务器二次桥接证明
|
||||||
|
- **state**:SERVER_GATE_ACTIVE_CLIENT_INTEGRATION_REBUILD_REQUIRED `next.state`
|
||||||
|
- **operation** `operation`
|
||||||
|
- **values** `operation.values`
|
||||||
|
- 验证源码运输归档与manifest
|
||||||
|
- 解包到/opt/guanghu-hololake-enterprise-gate/releases/be31c41
|
||||||
|
- 创建独立lighthouse权限数据库与服务密钥
|
||||||
|
- 安装guanghu-hololake-enterprise-gate.service
|
||||||
|
- 加入guanghu.chat精确device-gate路由
|
||||||
|
- 执行本地和外部健康、未知设备拒绝及原服务存活测试
|
||||||
|
- **proof** `proof`
|
||||||
|
- **current_link**:/opt/guanghu-hololake-enterprise-gate/current `proof.current_link`
|
||||||
|
- **database**:/var/lib/guanghu-hololake-enterprise-gate/gate.sqlite3 `proof.database`
|
||||||
|
- **nginx_backup**:/etc/nginx/sites-enabled/guanghu.chat.pre-hololake-device-gate-be31c41 `proof.nginx_backup`
|
||||||
|
- **nginx_snippet**:/etc/nginx/snippets/guanghu-hololake-enterprise-gate.conf `proof.nginx_snippet`
|
||||||
|
- **server_release**:/opt/guanghu-hololake-enterprise-gate/releases/be31c41 `proof.server_release`
|
||||||
|
- **request** `request`
|
||||||
|
- **scope**:GH-CVM-MAIN-PROD-01独立8033服务与精确Nginx路由 `request.scope`
|
||||||
|
- **source**:BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903 `request.source`
|
||||||
|
- **value**:部署企业四域负责人通过HoloLake本机设备和人格编号验证后进入本人责任仓库的服务端验证门。 `request.value`
|
||||||
|
- **result** `result`
|
||||||
|
- **active_sessions**:0 `result.active_sessions`
|
||||||
|
- **endpoint**:https://guanghu.chat/api/hololake/enterprise/device-gate `result.endpoint`
|
||||||
|
- **node_id**:GH-CVM-MAIN-PROD-01 `result.node_id`
|
||||||
|
- **registered_devices**:0 `result.registered_devices`
|
||||||
|
- **service**:guanghu-hololake-enterprise-gate.service `result.service`
|
||||||
|
- **service_state**:ACTIVE `result.service_state`
|
||||||
|
- **source_archive_sha256**:91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2 `result.source_archive_sha256`
|
||||||
|
- **source_commit**:be31c41 `result.source_commit`
|
||||||
|
- **state**:PASS `result.state`
|
||||||
|
- **verification** `verification`
|
||||||
|
- **values** `verification.values`
|
||||||
|
- DMI UUID为10ace744-13e1-472e-8dba-6bb823a073bf
|
||||||
|
- 服务器Python cryptography Ed25519测试2项通过
|
||||||
|
- systemd服务active
|
||||||
|
- 127.0.0.1:8033/health返回ok
|
||||||
|
- 外部HTTPS device-gate/health返回ok
|
||||||
|
- 未知设备领取挑战返回HTTP404 registered device required
|
||||||
|
- guanghu-enterprise-identity.service保持active
|
||||||
|
- guanghu-flagos-collaboration.service保持active
|
||||||
|
- nginx.service保持active
|
||||||
|
- 当前设备与会话数量均为0未伪造成员
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This page changes only the reading order; it does not change TCS/HLDP semantics.
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
# HoloLake企业责任设备门部署回执 · 简体中文人类工程语言版
|
||||||
|
|
||||||
|
> 这是 TCS/HLDP 原生源码的简体中文阅读投影,不是新的正本,也不授予执行权限。若本页与 `.tcs` 源码不一致,以经过校验的 `.tcs` 源码为准。
|
||||||
|
|
||||||
|
## 这是什么
|
||||||
|
|
||||||
|
这是一份 **回执** 声明,编号为 `HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903`,版本为 `1.0.0`。转换器已先用 Stage-1 编译器校验原生源码,再把机器枚举翻译成汉语;原始编号保留在括号和字段路径中。
|
||||||
|
|
||||||
|
## 谁在这里
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 为什么开始
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 发生了什么变化
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 准备怎样执行
|
||||||
|
|
||||||
|
这是非执行声明,没有动作图。
|
||||||
|
|
||||||
|
## 边界与异常处理
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 怎样算完成
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 下一次从哪里继续
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 来源与校验
|
||||||
|
|
||||||
|
- **原生声明编号**:`HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903`
|
||||||
|
- **原生声明类型**:`RECEIPT`
|
||||||
|
- **TCS 源码 SHA-256**:`c32cd3e16fdd64588addca115821a49bb47bf39b584670df031cf92028a8d232`
|
||||||
|
- **校验编译器**:`TCS-COMPILER-STAGE1-0001`
|
||||||
|
- **投影协议**:`GLS-HLDP-HUMAN-ENGINEERING-PROJECTION-0001`
|
||||||
|
|
||||||
|
## 原生结构逐项对照
|
||||||
|
|
||||||
|
下面保留源码的全部顶层结构和字段路径,供人类审计投影有没有漏掉信息。
|
||||||
|
|
||||||
|
- **boundaries** `boundaries`
|
||||||
|
- **values** `boundaries.values`
|
||||||
|
- 服务不保存Forgejo密码
|
||||||
|
- 设备私钥从不离开成员本机Keychain
|
||||||
|
- 机器指纹不能单独认证
|
||||||
|
- 会话只限单域单仓且十分钟过期
|
||||||
|
- 企业会话不替代Forgejo自身仓库登录
|
||||||
|
- 冰朔公共语言主控仓继续走JD第五域桥接而非普通人类登录
|
||||||
|
- 本轮未登记任何真实成员设备
|
||||||
|
- **语言头** `header`
|
||||||
|
- **正本路径**:product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-RECEIPT-20260903.tcs `header.canonical_uri`
|
||||||
|
- **compatibility** `header.compatibility`
|
||||||
|
- GH-CVM-MAIN-PROD-01
|
||||||
|
- PYTHON/3.10
|
||||||
|
- ED25519
|
||||||
|
- NGINX
|
||||||
|
- **语言**:TCS/0.1 `header.language`
|
||||||
|
- **生命周期**:候选版本,尚未成为正式正本(`CANDIDATE`) `header.lifecycle`
|
||||||
|
- **英文名**:HoloLake Enterprise Responsibility Device Gate Deployment Receipt `header.name_en`
|
||||||
|
- **中文名**:HoloLake企业责任设备门部署回执 `header.name_zh`
|
||||||
|
- **协议配置**:PUBLIC-PRODUCT-ENGINEERING/1 `header.profile`
|
||||||
|
- **protocols** `header.protocols`
|
||||||
|
- HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903
|
||||||
|
- HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001
|
||||||
|
- **schema**:tcs.receipt/v1 `header.schema`
|
||||||
|
- **版本**:1.0.0 `header.version`
|
||||||
|
- **integrity** `integrity`
|
||||||
|
- **existing_services_preserved**:PASS `integrity.existing_services_preserved`
|
||||||
|
- **source_archive_sha256**:91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2 `integrity.source_archive_sha256`
|
||||||
|
- **source_transport_manifest_sha256**:653ae0ca824fd8b9fff8d8532e82eddce63a8aa9f070e7a6aa3f863834e4ae77 `integrity.source_transport_manifest_sha256`
|
||||||
|
- **tcs_stage1_compilation**:PASS `integrity.tcs_stage1_compilation`
|
||||||
|
- **unknown_device_negative**:PASS `integrity.unknown_device_negative`
|
||||||
|
- **next** `next`
|
||||||
|
- **optional** `next.optional`
|
||||||
|
- 团队成员从HoloLake使用本人凭证完成首次设备登记
|
||||||
|
- 正向验证挑战与单仓会话
|
||||||
|
- 后续加入个人服务器二次桥接证明
|
||||||
|
- **state**:SERVER_GATE_ACTIVE_CLIENT_INTEGRATION_REBUILD_REQUIRED `next.state`
|
||||||
|
- **操作** `operation`
|
||||||
|
- **values** `operation.values`
|
||||||
|
- 验证源码运输归档与manifest
|
||||||
|
- 解包到/opt/guanghu-hololake-enterprise-gate/releases/be31c41
|
||||||
|
- 创建独立lighthouse权限数据库与服务密钥
|
||||||
|
- 安装guanghu-hololake-enterprise-gate.service
|
||||||
|
- 加入guanghu.chat精确device-gate路由
|
||||||
|
- 执行本地和外部健康、未知设备拒绝及原服务存活测试
|
||||||
|
- **proof** `proof`
|
||||||
|
- **current_link**:/opt/guanghu-hololake-enterprise-gate/current `proof.current_link`
|
||||||
|
- **database**:/var/lib/guanghu-hololake-enterprise-gate/gate.sqlite3 `proof.database`
|
||||||
|
- **nginx_backup**:/etc/nginx/sites-enabled/guanghu.chat.pre-hololake-device-gate-be31c41 `proof.nginx_backup`
|
||||||
|
- **nginx_snippet**:/etc/nginx/snippets/guanghu-hololake-enterprise-gate.conf `proof.nginx_snippet`
|
||||||
|
- **server_release**:/opt/guanghu-hololake-enterprise-gate/releases/be31c41 `proof.server_release`
|
||||||
|
- **request** `request`
|
||||||
|
- **scope**:GH-CVM-MAIN-PROD-01独立8033服务与精确Nginx路由 `request.scope`
|
||||||
|
- **来源**:BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903 `request.source`
|
||||||
|
- **value**:部署企业四域负责人通过HoloLake本机设备和人格编号验证后进入本人责任仓库的服务端验证门。 `request.value`
|
||||||
|
- **result** `result`
|
||||||
|
- **active_sessions**:0 `result.active_sessions`
|
||||||
|
- **endpoint**:https://guanghu.chat/api/hololake/enterprise/device-gate `result.endpoint`
|
||||||
|
- **node_id**:GH-CVM-MAIN-PROD-01 `result.node_id`
|
||||||
|
- **registered_devices**:0 `result.registered_devices`
|
||||||
|
- **service**:guanghu-hololake-enterprise-gate.service `result.service`
|
||||||
|
- **service_state**:ACTIVE `result.service_state`
|
||||||
|
- **source_archive_sha256**:91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2 `result.source_archive_sha256`
|
||||||
|
- **source_commit**:be31c41 `result.source_commit`
|
||||||
|
- **state**:PASS `result.state`
|
||||||
|
- **verification** `verification`
|
||||||
|
- **values** `verification.values`
|
||||||
|
- DMI UUID为10ace744-13e1-472e-8dba-6bb823a073bf
|
||||||
|
- 服务器Python cryptography Ed25519测试2项通过
|
||||||
|
- systemd服务active
|
||||||
|
- 127.0.0.1:8033/health返回ok
|
||||||
|
- 外部HTTPS device-gate/health返回ok
|
||||||
|
- 未知设备领取挑战返回HTTP404 registered device required
|
||||||
|
- guanghu-enterprise-identity.service保持active
|
||||||
|
- guanghu-flagos-collaboration.service保持active
|
||||||
|
- nginx.service保持active
|
||||||
|
- 当前设备与会话数量均为0未伪造成员
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
本页只改变阅读顺序,不改变 TCS/HLDP 语义。
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
{
|
||||||
|
"compiled_from": {
|
||||||
|
"compiler_id": "TCS-COMPILER-STAGE1-0001",
|
||||||
|
"compiler_state": "TCS_COMPILER_GIR_EXECUTED",
|
||||||
|
"source_sha256": "022315dd5c418abf7ce085d3409e2e8a884aade53dbb8604612cca36ceac4287"
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"emergence": {
|
||||||
|
"value": "采用独立8033服务、独立数据库和独立Nginx snippet,避免修改现有身份服务与FlagOS协作系统;只复用只读企业身份注册表与Forgejo当次认证。"
|
||||||
|
},
|
||||||
|
"event_time": {
|
||||||
|
"precision": "MINUTE_HOST_LOCAL",
|
||||||
|
"value": "2026-09-03T21:45:00+08:00"
|
||||||
|
},
|
||||||
|
"evidence": {
|
||||||
|
"archive_sha256": "91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2",
|
||||||
|
"expected_receipt": "目标服务健康、未知设备拒绝、签名正负测试、现有身份与FlagOS服务保持健康。",
|
||||||
|
"transport_manifest": "/Volumes/JZAO/HoloLake/releases/source-transport/hololake-enterprise-responsibility-gate-be31c41.manifest.json"
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"canonical_uri": "product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903.tcs",
|
||||||
|
"compatibility": [
|
||||||
|
"GH-CVM-MAIN-PROD-01",
|
||||||
|
"PYTHON/3.10",
|
||||||
|
"ED25519"
|
||||||
|
],
|
||||||
|
"language": "TCS/0.1",
|
||||||
|
"lifecycle": "CANDIDATE",
|
||||||
|
"name_en": "HoloLake Enterprise Responsibility Device Gate Deployment Start Event",
|
||||||
|
"name_zh": "HoloLake企业责任设备门部署开始事件",
|
||||||
|
"profile": "PUBLIC-PRODUCT-ENGINEERING/1",
|
||||||
|
"protocols": [
|
||||||
|
"HOLOLAKE-CLEAN-V1-DIRECT-LANGUAGE-EXECUTION-BASELINE-0001",
|
||||||
|
"HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001"
|
||||||
|
],
|
||||||
|
"schema": "tcs.event/v1",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"lock": {
|
||||||
|
"value": "SOURCE_COMMIT=be31c41; TARGET=/opt/guanghu-hololake-enterprise-gate/releases/be31c41; ROLLBACK=disable独立服务并移除Nginx include后恢复原配置;不修改8032与FlagOS。"
|
||||||
|
},
|
||||||
|
"observation": {
|
||||||
|
"value": "现有8032企业身份服务保持运行;8033空闲;cryptography Ed25519可用;目标目录不存在;源码提交be31c41且运输归档SHA-256为91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2。"
|
||||||
|
},
|
||||||
|
"rejected": {
|
||||||
|
"values": [
|
||||||
|
"直接改写8032现有服务",
|
||||||
|
"把私钥上传服务器",
|
||||||
|
"用机器指纹单独授权",
|
||||||
|
"把企业会话变成Forgejo永久令牌",
|
||||||
|
"重启或修改FlagOS服务",
|
||||||
|
"未验证运输哈希就解包"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"source_id": "BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903",
|
||||||
|
"source_role": "DIRECT_HUMAN",
|
||||||
|
"source_sha256": "d31c52c99c5e6059f9a7129086996cdd003e95b7ff126e700f4ed1c07ef6d9d5",
|
||||||
|
"source_uri": "source://codex-task/01a0672d-f125-7452-988e-523a6a34bfd4/msg_01a0675d-98a7-7542-abad-11a8a755dd71"
|
||||||
|
},
|
||||||
|
"subject": {
|
||||||
|
"channel_id": "ICE-CH-ZC001",
|
||||||
|
"subject_id": "GH-CVM-MAIN-PROD-01",
|
||||||
|
"subject_kind": "NODE",
|
||||||
|
"verification": "DMI UUID 10ace744-13e1-472e-8dba-6bb823a073bf;另一个FlagOS任务已完成且独立服务健康。"
|
||||||
|
},
|
||||||
|
"trigger": {
|
||||||
|
"value": "本机HoloLake 1.2.0设备密钥与责任绑定请求已实现并验收,需要在企业服务器部署独立设备挑战验证半边。"
|
||||||
|
},
|
||||||
|
"why": {
|
||||||
|
"value": "设备挑战属于HoloLake责任入口新能力,应与现有账号、关系回执和比赛服务隔离,失败时能独立撤回。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"executable": false,
|
||||||
|
"identity": {
|
||||||
|
"declaration_id": "HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903",
|
||||||
|
"declaration_kind": "EVENT",
|
||||||
|
"language_version": "0.1"
|
||||||
|
},
|
||||||
|
"native_self_hosted": true,
|
||||||
|
"natural_language_is_typed_data": true,
|
||||||
|
"schema": "guanghu.declaration-gir/v1",
|
||||||
|
"unresolved_natural_language": false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
# HoloLake Enterprise Responsibility Device Gate Deployment Start Event · Human Engineering Language (English)
|
||||||
|
|
||||||
|
> This is an English reading projection of validated native TCS/HLDP source. It is not a new canonical source and grants no execution authority.
|
||||||
|
|
||||||
|
## What this is
|
||||||
|
|
||||||
|
This is a **event** declaration with identifier `HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903` and version `1.0.0`. The projector validates it with the Stage-1 compiler before changing its reading order.
|
||||||
|
|
||||||
|
## Who is here
|
||||||
|
|
||||||
|
- **subject** `subject`
|
||||||
|
- **channel_id**:ICE-CH-ZC001 `subject.channel_id`
|
||||||
|
- **subject_id**:GH-CVM-MAIN-PROD-01 `subject.subject_id`
|
||||||
|
- **subject_kind**:NODE `subject.subject_kind`
|
||||||
|
- **verification**:DMI UUID 10ace744-13e1-472e-8dba-6bb823a073bf;另一个FlagOS任务已完成且独立服务健康。 `subject.verification`
|
||||||
|
|
||||||
|
## Why this started
|
||||||
|
|
||||||
|
- **trigger** `trigger`
|
||||||
|
- **value**:本机HoloLake 1.2.0设备密钥与责任绑定请求已实现并验收,需要在企业服务器部署独立设备挑战验证半边。 `trigger.value`
|
||||||
|
- **why** `why`
|
||||||
|
- **value**:设备挑战属于HoloLake责任入口新能力,应与现有账号、关系回执和比赛服务隔离,失败时能独立撤回。 `why.value`
|
||||||
|
- **source** `source`
|
||||||
|
- **source identifier**:BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903 `source.source_id`
|
||||||
|
- **source role**:DIRECT_HUMAN `source.source_role`
|
||||||
|
- **source checksum**:d31c52c99c5e6059f9a7129086996cdd003e95b7ff126e700f4ed1c07ef6d9d5 `source.source_sha256`
|
||||||
|
- **source address**:source://codex-task/01a0672d-f125-7452-988e-523a6a34bfd4/msg_01a0675d-98a7-7542-abad-11a8a755dd71 `source.source_uri`
|
||||||
|
|
||||||
|
## What changed
|
||||||
|
|
||||||
|
- **emergence** `emergence`
|
||||||
|
- **value**:采用独立8033服务、独立数据库和独立Nginx snippet,避免修改现有身份服务与FlagOS协作系统;只复用只读企业身份注册表与Forgejo当次认证。 `emergence.value`
|
||||||
|
- **lock** `lock`
|
||||||
|
- **value**:SOURCE_COMMIT=be31c41; TARGET=/opt/guanghu-hololake-enterprise-gate/releases/be31c41; ROLLBACK=disable独立服务并移除Nginx include后恢复原配置;不修改8032与FlagOS。 `lock.value`
|
||||||
|
|
||||||
|
## How it will execute
|
||||||
|
|
||||||
|
This is a non-executable declaration and has no action graph.
|
||||||
|
|
||||||
|
## Boundaries and exception handling
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## How completion is proven
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## Where to continue next time
|
||||||
|
|
||||||
|
The native source does not provide this field; the projector does not guess.
|
||||||
|
|
||||||
|
## Source and verification
|
||||||
|
|
||||||
|
- **Native declaration identifier**: `HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903`
|
||||||
|
- **Native declaration kind**: `EVENT`
|
||||||
|
- **TCS source SHA-256**: `022315dd5c418abf7ce085d3409e2e8a884aade53dbb8604612cca36ceac4287`
|
||||||
|
- **Validation compiler**: `TCS-COMPILER-STAGE1-0001`
|
||||||
|
- **Projection protocol**: `GLS-HLDP-HUMAN-ENGINEERING-PROJECTION-0001`
|
||||||
|
|
||||||
|
## Complete native structure cross-reference
|
||||||
|
|
||||||
|
All top-level structures and field paths are retained below so a reader can audit whether the projection omitted information.
|
||||||
|
|
||||||
|
- **emergence** `emergence`
|
||||||
|
- **value**:采用独立8033服务、独立数据库和独立Nginx snippet,避免修改现有身份服务与FlagOS协作系统;只复用只读企业身份注册表与Forgejo当次认证。 `emergence.value`
|
||||||
|
- **event_time** `event_time`
|
||||||
|
- **precision**:MINUTE_HOST_LOCAL `event_time.precision`
|
||||||
|
- **value**:2026-09-03T21:45:00+08:00 `event_time.value`
|
||||||
|
- **evidence** `evidence`
|
||||||
|
- **archive_sha256**:91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2 `evidence.archive_sha256`
|
||||||
|
- **expected_receipt**:目标服务健康、未知设备拒绝、签名正负测试、现有身份与FlagOS服务保持健康。 `evidence.expected_receipt`
|
||||||
|
- **transport_manifest**:/Volumes/JZAO/HoloLake/releases/source-transport/hololake-enterprise-responsibility-gate-be31c41.manifest.json `evidence.transport_manifest`
|
||||||
|
- **header** `header`
|
||||||
|
- **canonical source path**:product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903.tcs `header.canonical_uri`
|
||||||
|
- **compatibility** `header.compatibility`
|
||||||
|
- GH-CVM-MAIN-PROD-01
|
||||||
|
- PYTHON/3.10
|
||||||
|
- ED25519
|
||||||
|
- **language**:TCS/0.1 `header.language`
|
||||||
|
- **lifecycle**:CANDIDATE `header.lifecycle`
|
||||||
|
- **English name**:HoloLake Enterprise Responsibility Device Gate Deployment Start Event `header.name_en`
|
||||||
|
- **Chinese name**:HoloLake企业责任设备门部署开始事件 `header.name_zh`
|
||||||
|
- **profile**:PUBLIC-PRODUCT-ENGINEERING/1 `header.profile`
|
||||||
|
- **protocols** `header.protocols`
|
||||||
|
- HOLOLAKE-CLEAN-V1-DIRECT-LANGUAGE-EXECUTION-BASELINE-0001
|
||||||
|
- HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001
|
||||||
|
- **schema**:tcs.event/v1 `header.schema`
|
||||||
|
- **version**:1.0.0 `header.version`
|
||||||
|
- **lock** `lock`
|
||||||
|
- **value**:SOURCE_COMMIT=be31c41; TARGET=/opt/guanghu-hololake-enterprise-gate/releases/be31c41; ROLLBACK=disable独立服务并移除Nginx include后恢复原配置;不修改8032与FlagOS。 `lock.value`
|
||||||
|
- **observation** `observation`
|
||||||
|
- **value**:现有8032企业身份服务保持运行;8033空闲;cryptography Ed25519可用;目标目录不存在;源码提交be31c41且运输归档SHA-256为91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2。 `observation.value`
|
||||||
|
- **rejected** `rejected`
|
||||||
|
- **values** `rejected.values`
|
||||||
|
- 直接改写8032现有服务
|
||||||
|
- 把私钥上传服务器
|
||||||
|
- 用机器指纹单独授权
|
||||||
|
- 把企业会话变成Forgejo永久令牌
|
||||||
|
- 重启或修改FlagOS服务
|
||||||
|
- 未验证运输哈希就解包
|
||||||
|
- **source** `source`
|
||||||
|
- **source identifier**:BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903 `source.source_id`
|
||||||
|
- **source role**:DIRECT_HUMAN `source.source_role`
|
||||||
|
- **source checksum**:d31c52c99c5e6059f9a7129086996cdd003e95b7ff126e700f4ed1c07ef6d9d5 `source.source_sha256`
|
||||||
|
- **source address**:source://codex-task/01a0672d-f125-7452-988e-523a6a34bfd4/msg_01a0675d-98a7-7542-abad-11a8a755dd71 `source.source_uri`
|
||||||
|
- **subject** `subject`
|
||||||
|
- **channel_id**:ICE-CH-ZC001 `subject.channel_id`
|
||||||
|
- **subject_id**:GH-CVM-MAIN-PROD-01 `subject.subject_id`
|
||||||
|
- **subject_kind**:NODE `subject.subject_kind`
|
||||||
|
- **verification**:DMI UUID 10ace744-13e1-472e-8dba-6bb823a073bf;另一个FlagOS任务已完成且独立服务健康。 `subject.verification`
|
||||||
|
- **trigger** `trigger`
|
||||||
|
- **value**:本机HoloLake 1.2.0设备密钥与责任绑定请求已实现并验收,需要在企业服务器部署独立设备挑战验证半边。 `trigger.value`
|
||||||
|
- **why** `why`
|
||||||
|
- **value**:设备挑战属于HoloLake责任入口新能力,应与现有账号、关系回执和比赛服务隔离,失败时能独立撤回。 `why.value`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
This page changes only the reading order; it does not change TCS/HLDP semantics.
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
# HoloLake企业责任设备门部署开始事件 · 简体中文人类工程语言版
|
||||||
|
|
||||||
|
> 这是 TCS/HLDP 原生源码的简体中文阅读投影,不是新的正本,也不授予执行权限。若本页与 `.tcs` 源码不一致,以经过校验的 `.tcs` 源码为准。
|
||||||
|
|
||||||
|
## 这是什么
|
||||||
|
|
||||||
|
这是一份 **事件** 声明,编号为 `HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903`,版本为 `1.0.0`。转换器已先用 Stage-1 编译器校验原生源码,再把机器枚举翻译成汉语;原始编号保留在括号和字段路径中。
|
||||||
|
|
||||||
|
## 谁在这里
|
||||||
|
|
||||||
|
- **执行主体** `subject`
|
||||||
|
- **channel_id**:ICE-CH-ZC001 `subject.channel_id`
|
||||||
|
- **subject_id**:GH-CVM-MAIN-PROD-01 `subject.subject_id`
|
||||||
|
- **subject_kind**:NODE `subject.subject_kind`
|
||||||
|
- **verification**:DMI UUID 10ace744-13e1-472e-8dba-6bb823a073bf;另一个FlagOS任务已完成且独立服务健康。 `subject.verification`
|
||||||
|
|
||||||
|
## 为什么开始
|
||||||
|
|
||||||
|
- **触发** `trigger`
|
||||||
|
- **value**:本机HoloLake 1.2.0设备密钥与责任绑定请求已实现并验收,需要在企业服务器部署独立设备挑战验证半边。 `trigger.value`
|
||||||
|
- **为什么** `why`
|
||||||
|
- **value**:设备挑战属于HoloLake责任入口新能力,应与现有账号、关系回执和比赛服务隔离,失败时能独立撤回。 `why.value`
|
||||||
|
- **来源** `source`
|
||||||
|
- **来源编号**:BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903 `source.source_id`
|
||||||
|
- **来源角色**:人类直接语言来源(`DIRECT_HUMAN`) `source.source_role`
|
||||||
|
- **来源校验值**:d31c52c99c5e6059f9a7129086996cdd003e95b7ff126e700f4ed1c07ef6d9d5 `source.source_sha256`
|
||||||
|
- **来源地址**:source://codex-task/01a0672d-f125-7452-988e-523a6a34bfd4/msg_01a0675d-98a7-7542-abad-11a8a755dd71 `source.source_uri`
|
||||||
|
|
||||||
|
## 发生了什么变化
|
||||||
|
|
||||||
|
- **认知或状态变化** `emergence`
|
||||||
|
- **value**:采用独立8033服务、独立数据库和独立Nginx snippet,避免修改现有身份服务与FlagOS协作系统;只复用只读企业身份注册表与Forgejo当次认证。 `emergence.value`
|
||||||
|
- **锁定结论** `lock`
|
||||||
|
- **value**:SOURCE_COMMIT=be31c41; TARGET=/opt/guanghu-hololake-enterprise-gate/releases/be31c41; ROLLBACK=disable独立服务并移除Nginx include后恢复原配置;不修改8032与FlagOS。 `lock.value`
|
||||||
|
|
||||||
|
## 准备怎样执行
|
||||||
|
|
||||||
|
这是非执行声明,没有动作图。
|
||||||
|
|
||||||
|
## 边界与异常处理
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 怎样算完成
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 下一次从哪里继续
|
||||||
|
|
||||||
|
源程序没有提供这一项,转换器不猜。
|
||||||
|
|
||||||
|
## 来源与校验
|
||||||
|
|
||||||
|
- **原生声明编号**:`HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903`
|
||||||
|
- **原生声明类型**:`EVENT`
|
||||||
|
- **TCS 源码 SHA-256**:`022315dd5c418abf7ce085d3409e2e8a884aade53dbb8604612cca36ceac4287`
|
||||||
|
- **校验编译器**:`TCS-COMPILER-STAGE1-0001`
|
||||||
|
- **投影协议**:`GLS-HLDP-HUMAN-ENGINEERING-PROJECTION-0001`
|
||||||
|
|
||||||
|
## 原生结构逐项对照
|
||||||
|
|
||||||
|
下面保留源码的全部顶层结构和字段路径,供人类审计投影有没有漏掉信息。
|
||||||
|
|
||||||
|
- **认知或状态变化** `emergence`
|
||||||
|
- **value**:采用独立8033服务、独立数据库和独立Nginx snippet,避免修改现有身份服务与FlagOS协作系统;只复用只读企业身份注册表与Forgejo当次认证。 `emergence.value`
|
||||||
|
- **event_time** `event_time`
|
||||||
|
- **precision**:MINUTE_HOST_LOCAL `event_time.precision`
|
||||||
|
- **value**:2026-09-03T21:45:00+08:00 `event_time.value`
|
||||||
|
- **evidence** `evidence`
|
||||||
|
- **archive_sha256**:91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2 `evidence.archive_sha256`
|
||||||
|
- **expected_receipt**:目标服务健康、未知设备拒绝、签名正负测试、现有身份与FlagOS服务保持健康。 `evidence.expected_receipt`
|
||||||
|
- **transport_manifest**:/Volumes/JZAO/HoloLake/releases/source-transport/hololake-enterprise-responsibility-gate-be31c41.manifest.json `evidence.transport_manifest`
|
||||||
|
- **语言头** `header`
|
||||||
|
- **正本路径**:product-source/hololake-clean-desktop/language/HOLOLAKE-ENTERPRISE-RESPONSIBILITY-GATE-DEPLOYMENT-START-20260903.tcs `header.canonical_uri`
|
||||||
|
- **compatibility** `header.compatibility`
|
||||||
|
- GH-CVM-MAIN-PROD-01
|
||||||
|
- PYTHON/3.10
|
||||||
|
- ED25519
|
||||||
|
- **语言**:TCS/0.1 `header.language`
|
||||||
|
- **生命周期**:候选版本,尚未成为正式正本(`CANDIDATE`) `header.lifecycle`
|
||||||
|
- **英文名**:HoloLake Enterprise Responsibility Device Gate Deployment Start Event `header.name_en`
|
||||||
|
- **中文名**:HoloLake企业责任设备门部署开始事件 `header.name_zh`
|
||||||
|
- **协议配置**:PUBLIC-PRODUCT-ENGINEERING/1 `header.profile`
|
||||||
|
- **protocols** `header.protocols`
|
||||||
|
- HOLOLAKE-CLEAN-V1-DIRECT-LANGUAGE-EXECUTION-BASELINE-0001
|
||||||
|
- HLP-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001
|
||||||
|
- **schema**:tcs.event/v1 `header.schema`
|
||||||
|
- **版本**:1.0.0 `header.version`
|
||||||
|
- **锁定结论** `lock`
|
||||||
|
- **value**:SOURCE_COMMIT=be31c41; TARGET=/opt/guanghu-hololake-enterprise-gate/releases/be31c41; ROLLBACK=disable独立服务并移除Nginx include后恢复原配置;不修改8032与FlagOS。 `lock.value`
|
||||||
|
- **observation** `observation`
|
||||||
|
- **value**:现有8032企业身份服务保持运行;8033空闲;cryptography Ed25519可用;目标目录不存在;源码提交be31c41且运输归档SHA-256为91ecd4248d92d8ecb07bd348dfc14805c40eb000b6c152f96b7ef4583a33dcd2。 `observation.value`
|
||||||
|
- **已排除路径** `rejected`
|
||||||
|
- **values** `rejected.values`
|
||||||
|
- 直接改写8032现有服务
|
||||||
|
- 把私钥上传服务器
|
||||||
|
- 用机器指纹单独授权
|
||||||
|
- 把企业会话变成Forgejo永久令牌
|
||||||
|
- 重启或修改FlagOS服务
|
||||||
|
- 未验证运输哈希就解包
|
||||||
|
- **来源** `source`
|
||||||
|
- **来源编号**:BINGSHUO-DIRECT-HOLOLAKE-ZC001-EXECUTION-START-20260903 `source.source_id`
|
||||||
|
- **来源角色**:人类直接语言来源(`DIRECT_HUMAN`) `source.source_role`
|
||||||
|
- **来源校验值**:d31c52c99c5e6059f9a7129086996cdd003e95b7ff126e700f4ed1c07ef6d9d5 `source.source_sha256`
|
||||||
|
- **来源地址**:source://codex-task/01a0672d-f125-7452-988e-523a6a34bfd4/msg_01a0675d-98a7-7542-abad-11a8a755dd71 `source.source_uri`
|
||||||
|
- **执行主体** `subject`
|
||||||
|
- **channel_id**:ICE-CH-ZC001 `subject.channel_id`
|
||||||
|
- **subject_id**:GH-CVM-MAIN-PROD-01 `subject.subject_id`
|
||||||
|
- **subject_kind**:NODE `subject.subject_kind`
|
||||||
|
- **verification**:DMI UUID 10ace744-13e1-472e-8dba-6bb823a073bf;另一个FlagOS任务已完成且独立服务健康。 `subject.verification`
|
||||||
|
- **触发** `trigger`
|
||||||
|
- **value**:本机HoloLake 1.2.0设备密钥与责任绑定请求已实现并验收,需要在企业服务器部署独立设备挑战验证半边。 `trigger.value`
|
||||||
|
- **为什么** `why`
|
||||||
|
- **value**:设备挑战属于HoloLake责任入口新能力,应与现有账号、关系回执和比赛服务隔离,失败时能独立撤回。 `why.value`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
本页只改变阅读顺序,不改变 TCS/HLDP 语义。
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
"kind": "TEAM_ONLY_ENTERPRISE_GATEWAY",
|
"kind": "TEAM_ONLY_ENTERPRISE_GATEWAY",
|
||||||
"audience": "HUMAN_TEAM",
|
"audience": "HUMAN_TEAM",
|
||||||
"summary_zh": "为已登记域负责人准备设备、人格与责任范围验证。",
|
"summary_zh": "为已登记域负责人准备设备、人格与责任范围验证。",
|
||||||
"state": "LOCAL_DEVICE_PROOF_INSTALLED_SERVER_GATE_SOURCE_TESTED_DEPLOYMENT_PENDING",
|
"state": "SERVER_DEVICE_GATE_ACTIVE_CLIENT_ENROLLMENT_AND_CHALLENGE_SOURCE_IMPLEMENTED_REBUILD_PENDING",
|
||||||
"source": "src-tauri/src/enterprise_entrance.rs",
|
"source": "src-tauri/src/enterprise_entrance.rs",
|
||||||
"enterprise_server_embedded": false,
|
"enterprise_server_embedded": false,
|
||||||
"required_proofs": ["DOMAIN_RESPONSIBLE_HUMAN_ID", "BOUND_PERSONA_ID", "LOCAL_DEVICE_KEY", "AUXILIARY_MACHINE_FINGERPRINT", "SERVER_CHALLENGE_SIGNATURE"],
|
"required_proofs": ["DOMAIN_RESPONSIBLE_HUMAN_ID", "BOUND_PERSONA_ID", "LOCAL_DEVICE_KEY", "AUXILIARY_MACHINE_FINGERPRINT", "SERVER_CHALLENGE_SIGNATURE"],
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,12 @@ if enterprise.get("device_proof", {}).get("fingerprint_is_sole_credential") is n
|
||||||
errors.append("machine fingerprint incorrectly used as sole credential")
|
errors.append("machine fingerprint incorrectly used as sole credential")
|
||||||
if enterprise.get("session", {}).get("scope") != "ONE_DOMAIN_ONE_REPOSITORY":
|
if enterprise.get("session", {}).get("scope") != "ONE_DOMAIN_ONE_REPOSITORY":
|
||||||
errors.append("enterprise session is not responsibility scoped")
|
errors.append("enterprise session is not responsibility scoped")
|
||||||
if enterprise.get("state") != "LOCAL_DEVICE_PROOF_INSTALLED_KEYCHAIN_VERIFIED_SERVER_GATE_SOURCE_TESTED_DEPLOYMENT_PENDING":
|
if enterprise.get("state") != "SERVER_DEVICE_GATE_ACTIVE_CLIENT_ENROLLMENT_AND_CHALLENGE_SOURCE_IMPLEMENTED_REBUILD_PENDING":
|
||||||
errors.append("enterprise local device proof implementation state drift")
|
errors.append("enterprise local device proof implementation state drift")
|
||||||
|
enterprise_client = (ROOT / "src-tauri/src/enterprise_entrance.rs").read_text()
|
||||||
|
for required_client in ("enroll_device", "authenticate", "save_session_token", "ONE_DOMAIN_ONE_REPOSITORY"):
|
||||||
|
if required_client not in enterprise_client:
|
||||||
|
errors.append(f"enterprise client flow missing: {required_client}")
|
||||||
time_source = (ROOT / "src/time.ts").read_text()
|
time_source = (ROOT / "src/time.ts").read_text()
|
||||||
app_source = (ROOT / "src/App.tsx").read_text()
|
app_source = (ROOT / "src/App.tsx").read_text()
|
||||||
if "legacyUnixSeconds" not in time_source or "时间待校验" not in time_source:
|
if "legacyUnixSeconds" not in time_source or "时间待校验" not in time_source:
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,29 @@ version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-rs"
|
||||||
|
version = "1.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e"
|
||||||
|
dependencies = [
|
||||||
|
"aws-lc-sys",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aws-lc-sys"
|
||||||
|
version = "0.45.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"cmake",
|
||||||
|
"dunce",
|
||||||
|
"fs_extra",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.7"
|
version = "0.21.7"
|
||||||
|
|
@ -282,6 +305,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
|
checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
|
"jobserver",
|
||||||
|
"libc",
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -318,6 +343,23 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg_aliases"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.1",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.45"
|
version = "0.4.45"
|
||||||
|
|
@ -330,6 +372,15 @@ dependencies = [
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cmake"
|
||||||
|
version = "0.1.58"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "combine"
|
name = "combine"
|
||||||
version = "4.6.8"
|
version = "4.6.8"
|
||||||
|
|
@ -405,6 +456,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
|
@ -904,6 +964,12 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fs_extra"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futf"
|
name = "futf"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
@ -921,6 +987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
|
checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1121,8 +1188,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1144,8 +1213,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"r-efi 6.0.0",
|
"r-efi 6.0.0",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1333,6 +1405,7 @@ dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"chrono",
|
"chrono",
|
||||||
"regex",
|
"regex",
|
||||||
|
"reqwest",
|
||||||
"ring",
|
"ring",
|
||||||
"security-framework",
|
"security-framework",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1806,6 +1879,16 @@ dependencies = [
|
||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jobserver"
|
||||||
|
version = "0.1.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.104"
|
version = "0.3.104"
|
||||||
|
|
@ -1938,6 +2021,12 @@ version = "0.4.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru-slab"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mac"
|
name = "mac"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
|
@ -2787,6 +2876,63 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn"
|
||||||
|
version = "0.11.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"cfg_aliases",
|
||||||
|
"pin-project-lite",
|
||||||
|
"quinn-proto",
|
||||||
|
"quinn-udp",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustls",
|
||||||
|
"socket2",
|
||||||
|
"thiserror 2.0.20",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-proto"
|
||||||
|
version = "0.11.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83"
|
||||||
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
|
"bytes",
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"lru-slab",
|
||||||
|
"rand 0.10.2",
|
||||||
|
"rand_pcg 0.10.2",
|
||||||
|
"ring",
|
||||||
|
"rustc-hash",
|
||||||
|
"rustls",
|
||||||
|
"rustls-pki-types",
|
||||||
|
"slab",
|
||||||
|
"thiserror 2.0.20",
|
||||||
|
"tinyvec",
|
||||||
|
"tracing",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quinn-udp"
|
||||||
|
version = "0.5.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694"
|
||||||
|
dependencies = [
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"socket2",
|
||||||
|
"tracing",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.47"
|
version = "1.0.47"
|
||||||
|
|
@ -2819,7 +2965,7 @@ dependencies = [
|
||||||
"rand_chacha 0.2.2",
|
"rand_chacha 0.2.2",
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
"rand_hc",
|
"rand_hc",
|
||||||
"rand_pcg",
|
"rand_pcg 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2833,6 +2979,17 @@ dependencies = [
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
|
||||||
|
dependencies = [
|
||||||
|
"chacha20",
|
||||||
|
"getrandom 0.4.3",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
|
@ -2871,6 +3028,12 @@ dependencies = [
|
||||||
"getrandom 0.2.17",
|
"getrandom 0.2.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_hc"
|
name = "rand_hc"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
@ -2889,6 +3052,15 @@ dependencies = [
|
||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_pcg"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "raw-window-handle"
|
name = "raw-window-handle"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
|
|
@ -2972,6 +3144,7 @@ checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
|
|
@ -2984,6 +3157,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"quinn",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"rustls-platform-verifier",
|
"rustls-platform-verifier",
|
||||||
|
|
@ -3075,6 +3249,7 @@ version = "0.23.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
|
checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
|
@ -3101,6 +3276,7 @@ version = "1.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
|
checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"web-time",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -3137,6 +3313,7 @@ version = "0.103.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
|
checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aws-lc-rs",
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
|
|
@ -3469,7 +3646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -4758,6 +4935,16 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-time"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web_atoms"
|
name = "web_atoms"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ regex = "1"
|
||||||
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
chrono = { version = "0.4", default-features = false, features = ["clock"] }
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
ring = "0.17"
|
ring = "0.17"
|
||||||
|
reqwest = { version = "0.13", default-features = false, features = ["blocking", "json", "rustls"] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
security-framework = "3"
|
security-framework = "3"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ use crate::storage;
|
||||||
|
|
||||||
const KEYCHAIN_SERVICE: &str = "world.guanghu.hololake.enterprise-device";
|
const KEYCHAIN_SERVICE: &str = "world.guanghu.hololake.enterprise-device";
|
||||||
const KEYCHAIN_ACCOUNT: &str = "responsibility-entrance-ed25519-v1";
|
const KEYCHAIN_ACCOUNT: &str = "responsibility-entrance-ed25519-v1";
|
||||||
|
const SESSION_KEYCHAIN_SERVICE: &str = "world.guanghu.hololake.enterprise-session";
|
||||||
|
const GATE_BASE: &str = "https://guanghu.chat/api/hololake/enterprise/device-gate";
|
||||||
const ALLOWED_DOMAINS: [&str; 4] = ["DOMAIN-MAIN", "DOMAIN-SUB", "DOMAIN-ZERO", "DOMAIN-ZS"];
|
const ALLOWED_DOMAINS: [&str; 4] = ["DOMAIN-MAIN", "DOMAIN-SUB", "DOMAIN-ZERO", "DOMAIN-ZS"];
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
|
@ -52,11 +54,24 @@ pub struct EnterpriseEntranceSnapshot {
|
||||||
pub state: String,
|
pub state: String,
|
||||||
pub device: Option<EnterpriseDeviceProof>,
|
pub device: Option<EnterpriseDeviceProof>,
|
||||||
pub binding: Option<EnterpriseBindingRequest>,
|
pub binding: Option<EnterpriseBindingRequest>,
|
||||||
|
pub session: Option<EnterpriseSession>,
|
||||||
pub enterprise_server_embedded: bool,
|
pub enterprise_server_embedded: bool,
|
||||||
pub server_authorized: bool,
|
pub server_authorized: bool,
|
||||||
pub next_action: String,
|
pub next_action: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct EnterpriseSession {
|
||||||
|
pub schema: String,
|
||||||
|
pub state: String,
|
||||||
|
pub domain_id: String,
|
||||||
|
pub repository: String,
|
||||||
|
pub repository_url: String,
|
||||||
|
pub expires_unix_ms: u128,
|
||||||
|
pub token_storage: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct EnterpriseChallengeProof {
|
pub struct EnterpriseChallengeProof {
|
||||||
|
|
@ -84,6 +99,14 @@ fn used_challenges_path(app: &AppHandle) -> Result<std::path::PathBuf, String> {
|
||||||
Ok(storage::root(app)?.join("enterprise-entrance/used-challenges.json"))
|
Ok(storage::root(app)?.join("enterprise-entrance/used-challenges.json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn enrollment_path(app: &AppHandle) -> Result<std::path::PathBuf, String> {
|
||||||
|
Ok(storage::root(app)?.join("enterprise-entrance/enrollment-receipt.json"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn session_path(app: &AppHandle) -> Result<std::path::PathBuf, String> {
|
||||||
|
Ok(storage::root(app)?.join("enterprise-entrance/session.json"))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn load_key_bytes() -> Result<Option<Vec<u8>>, String> {
|
fn load_key_bytes() -> Result<Option<Vec<u8>>, String> {
|
||||||
match security_framework::passwords::get_generic_password(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT) {
|
match security_framework::passwords::get_generic_password(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT) {
|
||||||
|
|
@ -99,6 +122,12 @@ fn save_key_bytes(value: &[u8]) -> Result<(), String> {
|
||||||
.map_err(|error| format!("ENTERPRISE_DEVICE_KEYCHAIN_WRITE_FAILED: {error}"))
|
.map_err(|error| format!("ENTERPRISE_DEVICE_KEYCHAIN_WRITE_FAILED: {error}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn save_session_token(account: &str, value: &[u8]) -> Result<(), String> {
|
||||||
|
security_framework::passwords::set_generic_password(SESSION_KEYCHAIN_SERVICE, account, value)
|
||||||
|
.map_err(|error| format!("ENTERPRISE_SESSION_KEYCHAIN_WRITE_FAILED: {error}"))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
fn load_key_bytes() -> Result<Option<Vec<u8>>, String> {
|
fn load_key_bytes() -> Result<Option<Vec<u8>>, String> {
|
||||||
Err("ENTERPRISE_DEVICE_KEYCHAIN_UNAVAILABLE_ON_PLATFORM".into())
|
Err("ENTERPRISE_DEVICE_KEYCHAIN_UNAVAILABLE_ON_PLATFORM".into())
|
||||||
|
|
@ -109,6 +138,41 @@ fn save_key_bytes(_value: &[u8]) -> Result<(), String> {
|
||||||
Err("ENTERPRISE_DEVICE_KEYCHAIN_UNAVAILABLE_ON_PLATFORM".into())
|
Err("ENTERPRISE_DEVICE_KEYCHAIN_UNAVAILABLE_ON_PLATFORM".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
fn save_session_token(_account: &str, _value: &[u8]) -> Result<(), String> {
|
||||||
|
Err("ENTERPRISE_SESSION_KEYCHAIN_UNAVAILABLE_ON_PLATFORM".into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn post_json(
|
||||||
|
path: &str,
|
||||||
|
payload: serde_json::Value,
|
||||||
|
basic: Option<(&str, &str)>,
|
||||||
|
) -> Result<serde_json::Value, String> {
|
||||||
|
let client = reqwest::blocking::Client::builder()
|
||||||
|
.timeout(std::time::Duration::from_secs(15))
|
||||||
|
.build()
|
||||||
|
.map_err(|_| "ENTERPRISE_GATE_CLIENT_INIT_FAILED".to_string())?;
|
||||||
|
let mut request = client.post(format!("{GATE_BASE}{path}")).json(&payload);
|
||||||
|
if let Some((username, password)) = basic {
|
||||||
|
request = request.basic_auth(username, Some(password));
|
||||||
|
}
|
||||||
|
let response = request
|
||||||
|
.send()
|
||||||
|
.map_err(|_| "ENTERPRISE_GATE_UNREACHABLE".to_string())?;
|
||||||
|
let status = response.status();
|
||||||
|
let value: serde_json::Value = response
|
||||||
|
.json()
|
||||||
|
.map_err(|_| "ENTERPRISE_GATE_RESPONSE_INVALID".to_string())?;
|
||||||
|
if !status.is_success() {
|
||||||
|
return Err(value
|
||||||
|
.get("error")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.unwrap_or("ENTERPRISE_GATE_REJECTED")
|
||||||
|
.to_string());
|
||||||
|
}
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
fn load_or_create_key() -> Result<Ed25519KeyPair, String> {
|
fn load_or_create_key() -> Result<Ed25519KeyPair, String> {
|
||||||
let bytes = if let Some(value) = load_key_bytes()? {
|
let bytes = if let Some(value) = load_key_bytes()? {
|
||||||
value
|
value
|
||||||
|
|
@ -225,7 +289,19 @@ pub fn snapshot(app: &AppHandle) -> Result<EnterpriseEntranceSnapshot, String> {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let state = if binding.is_some() {
|
let stored_session = session_path(app)?;
|
||||||
|
let session: Option<EnterpriseSession> = if stored_session.exists() {
|
||||||
|
let value: EnterpriseSession = storage::read_json(&stored_session)?;
|
||||||
|
(value.expires_unix_ms > storage::now_unix_ms()).then_some(value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let enrolled = enrollment_path(app)?.exists();
|
||||||
|
let state = if session.is_some() {
|
||||||
|
"ENTERPRISE_SESSION_VERIFIED"
|
||||||
|
} else if enrolled {
|
||||||
|
"DEVICE_ENROLLED_SERVER_CHALLENGE_REQUIRED"
|
||||||
|
} else if binding.is_some() {
|
||||||
"LOCAL_PROOF_READY_SERVER_CHALLENGE_REQUIRED"
|
"LOCAL_PROOF_READY_SERVER_CHALLENGE_REQUIRED"
|
||||||
} else if device.is_some() {
|
} else if device.is_some() {
|
||||||
"LOCAL_DEVICE_KEY_READY_BINDING_REQUIRED"
|
"LOCAL_DEVICE_KEY_READY_BINDING_REQUIRED"
|
||||||
|
|
@ -237,12 +313,142 @@ pub fn snapshot(app: &AppHandle) -> Result<EnterpriseEntranceSnapshot, String> {
|
||||||
state: state.into(),
|
state: state.into(),
|
||||||
device,
|
device,
|
||||||
binding,
|
binding,
|
||||||
|
session,
|
||||||
enterprise_server_embedded: false,
|
enterprise_server_embedded: false,
|
||||||
server_authorized: false,
|
server_authorized: state == "ENTERPRISE_SESSION_VERIFIED",
|
||||||
next_action: "企业服务器并发任务结束后获取一次性挑战;本机证明不等于登录成功。".into(),
|
next_action: match state {
|
||||||
|
"ENTERPRISE_SESSION_VERIFIED" => "企业责任会话已验证;只可进入返回的单一责任仓库。",
|
||||||
|
"DEVICE_ENROLLED_SERVER_CHALLENGE_REQUIRED" => {
|
||||||
|
"设备已登记;可以领取一次性挑战并验证当前会话。"
|
||||||
|
}
|
||||||
|
_ => "先完成设备和责任绑定;本机证明不等于登录成功。",
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn enroll_device(
|
||||||
|
app: &AppHandle,
|
||||||
|
username: &str,
|
||||||
|
password: &str,
|
||||||
|
) -> Result<serde_json::Value, String> {
|
||||||
|
let username = username.trim();
|
||||||
|
if !Regex::new(r"^[A-Za-z0-9_-]{1,40}$")
|
||||||
|
.map_err(|e| e.to_string())?
|
||||||
|
.is_match(username)
|
||||||
|
|| password.is_empty()
|
||||||
|
|| password.len() > 512
|
||||||
|
{
|
||||||
|
return Err("ENTERPRISE_ACCOUNT_CREDENTIALS_INVALID".into());
|
||||||
|
}
|
||||||
|
let device: EnterpriseDeviceProof = storage::read_json(&device_path(app)?)
|
||||||
|
.map_err(|_| "ENTERPRISE_DEVICE_PROOF_REQUIRED".to_string())?;
|
||||||
|
let binding: EnterpriseBindingRequest = storage::read_json(&binding_path(app)?)
|
||||||
|
.map_err(|_| "ENTERPRISE_BINDING_REQUIRED".to_string())?;
|
||||||
|
let response = post_json(
|
||||||
|
"/enroll",
|
||||||
|
serde_json::json!({
|
||||||
|
"request_id": binding.request_id,
|
||||||
|
"human_number": binding.responsible_human_id,
|
||||||
|
"persona_id": binding.persona_id,
|
||||||
|
"domain_id": binding.domain_id,
|
||||||
|
"node_id": device.node_id,
|
||||||
|
"key_id": device.key_id,
|
||||||
|
"public_key": device.public_key,
|
||||||
|
"fingerprint_sha256": device.auxiliary_machine_fingerprint_sha256,
|
||||||
|
"idempotency_key": format!("{}-{}", binding.request_id, device.key_id),
|
||||||
|
}),
|
||||||
|
Some((username, password)),
|
||||||
|
)?;
|
||||||
|
storage::write_json(&enrollment_path(app)?, &response)?;
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"ok": true,
|
||||||
|
"state": "DEVICE_ENROLLED",
|
||||||
|
"keyId": device.key_id,
|
||||||
|
"serverAuthorized": false
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn authenticate(app: &AppHandle) -> Result<EnterpriseSession, String> {
|
||||||
|
if !enrollment_path(app)?.exists() {
|
||||||
|
return Err("ENTERPRISE_DEVICE_ENROLLMENT_REQUIRED".into());
|
||||||
|
}
|
||||||
|
let device: EnterpriseDeviceProof = storage::read_json(&device_path(app)?)?;
|
||||||
|
let binding: EnterpriseBindingRequest = storage::read_json(&binding_path(app)?)?;
|
||||||
|
let response = post_json(
|
||||||
|
"/challenges",
|
||||||
|
serde_json::json!({"key_id":device.key_id,"request_id":binding.request_id}),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
let challenge = response
|
||||||
|
.get("challenge")
|
||||||
|
.ok_or_else(|| "ENTERPRISE_CHALLENGE_MISSING".to_string())?;
|
||||||
|
let challenge_id = challenge
|
||||||
|
.get("challenge_id")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.ok_or_else(|| "ENTERPRISE_CHALLENGE_ID_MISSING".to_string())?;
|
||||||
|
let nonce = challenge
|
||||||
|
.get("nonce")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.ok_or_else(|| "ENTERPRISE_CHALLENGE_NONCE_MISSING".to_string())?;
|
||||||
|
let expires = challenge
|
||||||
|
.get("expires_unix_ms")
|
||||||
|
.and_then(serde_json::Value::as_u64)
|
||||||
|
.ok_or_else(|| "ENTERPRISE_CHALLENGE_EXPIRY_MISSING".to_string())?
|
||||||
|
as u128;
|
||||||
|
let proof = sign_challenge(app, &binding.request_id, challenge_id, nonce, expires)?;
|
||||||
|
let verified = post_json(
|
||||||
|
"/challenges/verify",
|
||||||
|
serde_json::json!({"challenge_id":proof.challenge_id,"signature":proof.signature}),
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
let value = verified
|
||||||
|
.get("session")
|
||||||
|
.ok_or_else(|| "ENTERPRISE_SESSION_MISSING".to_string())?;
|
||||||
|
let token = value
|
||||||
|
.get("token")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.ok_or_else(|| "ENTERPRISE_SESSION_TOKEN_MISSING".to_string())?;
|
||||||
|
let scope = value
|
||||||
|
.get("scope")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.unwrap_or("");
|
||||||
|
let session = EnterpriseSession {
|
||||||
|
schema: "hololake.enterprise-session/v1".into(),
|
||||||
|
state: "ENTERPRISE_SESSION_VERIFIED".into(),
|
||||||
|
domain_id: value
|
||||||
|
.get("domain_id")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.unwrap_or("")
|
||||||
|
.into(),
|
||||||
|
repository: value
|
||||||
|
.get("repository")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.unwrap_or("")
|
||||||
|
.into(),
|
||||||
|
repository_url: value
|
||||||
|
.get("repository_url")
|
||||||
|
.and_then(serde_json::Value::as_str)
|
||||||
|
.unwrap_or("")
|
||||||
|
.into(),
|
||||||
|
expires_unix_ms: value
|
||||||
|
.get("expires_unix_ms")
|
||||||
|
.and_then(serde_json::Value::as_u64)
|
||||||
|
.unwrap_or(0) as u128,
|
||||||
|
token_storage: "MACOS_KEYCHAIN".into(),
|
||||||
|
};
|
||||||
|
if scope != "ONE_DOMAIN_ONE_REPOSITORY"
|
||||||
|
|| session.domain_id != binding.domain_id
|
||||||
|
|| session.repository.is_empty()
|
||||||
|
|| session.expires_unix_ms <= storage::now_unix_ms()
|
||||||
|
{
|
||||||
|
return Err("ENTERPRISE_SESSION_SCOPE_INVALID".into());
|
||||||
|
}
|
||||||
|
save_session_token(&device.key_id, token.as_bytes())?;
|
||||||
|
storage::write_json(&session_path(app)?, &session)?;
|
||||||
|
Ok(session)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sign_challenge(
|
pub fn sign_challenge(
|
||||||
app: &AppHandle,
|
app: &AppHandle,
|
||||||
request_id: &str,
|
request_id: &str,
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,22 @@ fn sign_enterprise_challenge(
|
||||||
enterprise_entrance::sign_challenge(&app, &request_id, &challenge_id, &nonce, expires_unix_ms)
|
enterprise_entrance::sign_challenge(&app, &request_id, &challenge_id, &nonce, expires_unix_ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn enroll_enterprise_device(
|
||||||
|
app: AppHandle,
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
) -> Result<serde_json::Value, String> {
|
||||||
|
enterprise_entrance::enroll_device(&app, &username, &password)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
fn authenticate_enterprise_entrance(
|
||||||
|
app: AppHandle,
|
||||||
|
) -> Result<enterprise_entrance::EnterpriseSession, String> {
|
||||||
|
enterprise_entrance::authenticate(&app)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
|
@ -577,11 +593,13 @@ pub fn run() {
|
||||||
delete_trial_persona,
|
delete_trial_persona,
|
||||||
compile_tcs_agent_proposal,
|
compile_tcs_agent_proposal,
|
||||||
approve_agent_proposal,
|
approve_agent_proposal,
|
||||||
reject_agent_proposal
|
reject_agent_proposal,
|
||||||
,enterprise_entrance_snapshot
|
enterprise_entrance_snapshot,
|
||||||
,prepare_enterprise_device
|
prepare_enterprise_device,
|
||||||
,prepare_enterprise_binding
|
prepare_enterprise_binding,
|
||||||
,sign_enterprise_challenge
|
sign_enterprise_challenge,
|
||||||
|
enroll_enterprise_device,
|
||||||
|
authenticate_enterprise_entrance
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("HoloLake runtime failed")
|
.expect("HoloLake runtime failed")
|
||||||
|
|
|
||||||
|
|
@ -924,6 +924,8 @@ function Portal({ setError }: { setError: (value: string) => void }) {
|
||||||
const [domainId, setDomainId] = useState("DOMAIN-MAIN");
|
const [domainId, setDomainId] = useState("DOMAIN-MAIN");
|
||||||
const [humanId, setHumanId] = useState("");
|
const [humanId, setHumanId] = useState("");
|
||||||
const [personaId, setPersonaId] = useState("");
|
const [personaId, setPersonaId] = useState("");
|
||||||
|
const [username, setUsername] = useState("");
|
||||||
|
const [password, setPassword] = useState("");
|
||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
const refresh = () => api.enterpriseEntranceSnapshot().then(setEntrance).catch((error) => setError(String(error)));
|
const refresh = () => api.enterpriseEntranceSnapshot().then(setEntrance).catch((error) => setError(String(error)));
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -951,6 +953,30 @@ function Portal({ setError }: { setError: (value: string) => void }) {
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const enrollDevice = async () => {
|
||||||
|
setBusy(true);
|
||||||
|
try {
|
||||||
|
await api.enrollEnterpriseDevice(username, password);
|
||||||
|
setPassword("");
|
||||||
|
await refresh();
|
||||||
|
} catch (error) {
|
||||||
|
setPassword("");
|
||||||
|
setError(String(error));
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const authenticate = async () => {
|
||||||
|
setBusy(true);
|
||||||
|
try {
|
||||||
|
await api.authenticateEnterpriseEntrance();
|
||||||
|
await refresh();
|
||||||
|
} catch (error) {
|
||||||
|
setError(String(error));
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="page simple">
|
<div className="page simple">
|
||||||
<header>
|
<header>
|
||||||
|
|
@ -996,6 +1022,23 @@ function Portal({ setError }: { setError: (value: string) => void }) {
|
||||||
<>
|
<>
|
||||||
<p>{entrance.binding.domainId} · {entrance.binding.responsibleHumanId} · {entrance.binding.personaId}</p>
|
<p>{entrance.binding.domainId} · {entrance.binding.responsibleHumanId} · {entrance.binding.personaId}</p>
|
||||||
<small>{entrance.binding.state}</small>
|
<small>{entrance.binding.state}</small>
|
||||||
|
{!entrance.session && entrance.state === "LOCAL_PROOF_READY_SERVER_CHALLENGE_REQUIRED" && (
|
||||||
|
<div className="enterprise-binding-form">
|
||||||
|
<input value={username} onChange={(event) => setUsername(event.target.value)} placeholder="企业代码仓库用户名" autoComplete="username" />
|
||||||
|
<input type="password" value={password} onChange={(event) => setPassword(event.target.value)} placeholder="仅用于本次设备登记" autoComplete="current-password" />
|
||||||
|
<button onClick={enrollDevice} disabled={busy || !username.trim() || !password}>
|
||||||
|
验证责任并登记本机
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!entrance.session && entrance.state === "DEVICE_ENROLLED_SERVER_CHALLENGE_REQUIRED" && (
|
||||||
|
<button onClick={authenticate} disabled={busy}>验证当前企业会话</button>
|
||||||
|
)}
|
||||||
|
{entrance.session && (
|
||||||
|
<a href={entrance.session.repositoryUrl} target="_blank" rel="noreferrer">
|
||||||
|
进入我的责任仓库 ↗
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="enterprise-binding-form">
|
<div className="enterprise-binding-form">
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,7 @@ export async function enterpriseEntranceSnapshot(): Promise<EnterpriseEntranceSn
|
||||||
state: "LOCAL_DEVICE_REGISTRATION_REQUIRED",
|
state: "LOCAL_DEVICE_REGISTRATION_REQUIRED",
|
||||||
device: null,
|
device: null,
|
||||||
binding: null,
|
binding: null,
|
||||||
|
session: null,
|
||||||
enterpriseServerEmbedded: false,
|
enterpriseServerEmbedded: false,
|
||||||
serverAuthorized: false,
|
serverAuthorized: false,
|
||||||
nextAction: "浏览器预览不生成设备凭证。",
|
nextAction: "浏览器预览不生成设备凭证。",
|
||||||
|
|
@ -331,3 +332,16 @@ export async function prepareEnterpriseBinding(
|
||||||
if (!tauri()) throw new Error("企业责任绑定只能在已安装的 HoloLake 中准备");
|
if (!tauri()) throw new Error("企业责任绑定只能在已安装的 HoloLake 中准备");
|
||||||
return invoke("prepare_enterprise_binding", { domainId, responsibleHumanId, personaId });
|
return invoke("prepare_enterprise_binding", { domainId, responsibleHumanId, personaId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function enrollEnterpriseDevice(
|
||||||
|
username: string,
|
||||||
|
password: string,
|
||||||
|
): Promise<{ ok: boolean; state: string; keyId: string; serverAuthorized: boolean }> {
|
||||||
|
if (!tauri()) throw new Error("企业设备登记只能在已安装的 HoloLake 中完成");
|
||||||
|
return invoke("enroll_enterprise_device", { username, password });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function authenticateEnterpriseEntrance(): Promise<EnterpriseEntranceSnapshot["session"]> {
|
||||||
|
if (!tauri()) throw new Error("企业责任会话只能在已安装的 HoloLake 中验证");
|
||||||
|
return invoke("authenticate_enterprise_entrance");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,17 @@ export interface EnterpriseEntranceSnapshot {
|
||||||
state: string;
|
state: string;
|
||||||
device: EnterpriseDeviceProof | null;
|
device: EnterpriseDeviceProof | null;
|
||||||
binding: EnterpriseBindingRequest | null;
|
binding: EnterpriseBindingRequest | null;
|
||||||
|
session: EnterpriseSession | null;
|
||||||
enterpriseServerEmbedded: boolean;
|
enterpriseServerEmbedded: boolean;
|
||||||
serverAuthorized: boolean;
|
serverAuthorized: boolean;
|
||||||
nextAction: string;
|
nextAction: string;
|
||||||
}
|
}
|
||||||
|
export interface EnterpriseSession {
|
||||||
|
schema: string;
|
||||||
|
state: string;
|
||||||
|
domainId: string;
|
||||||
|
repository: string;
|
||||||
|
repositoryUrl: string;
|
||||||
|
expiresUnixMs: number;
|
||||||
|
tokenStorage: string;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@
|
||||||
"bingshuo_enterprise_language_master_work_repository": "REPO-016:bingshuo/guanghu-language-master-work",
|
"bingshuo_enterprise_language_master_work_repository": "REPO-016:bingshuo/guanghu-language-master-work",
|
||||||
"team_enterprise_login": "https://guanghu.chat/code/user/login",
|
"team_enterprise_login": "https://guanghu.chat/code/user/login",
|
||||||
"enterprise_responsibility_entrance": "HLP-MOD-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001",
|
"enterprise_responsibility_entrance": "HLP-MOD-ENTERPRISE-RESPONSIBILITY-ENTRANCE-0001",
|
||||||
"enterprise_responsibility_entrance_state": "LOCAL_DEVICE_PROOF_INSTALLED_KEYCHAIN_VERIFIED_SERVER_CHALLENGE_PENDING",
|
"enterprise_responsibility_entrance_state": "SERVER_DEVICE_GATE_ACTIVE_CLIENT_ENROLLMENT_AND_CHALLENGE_SOURCE_IMPLEMENTED_REBUILD_PENDING",
|
||||||
|
"enterprise_responsibility_gate_endpoint": "https://guanghu.chat/api/hololake/enterprise/device-gate",
|
||||||
|
"enterprise_responsibility_gate_source_commit": "be31c41",
|
||||||
"enterprise_server_embedded": false,
|
"enterprise_server_embedded": false,
|
||||||
"enterprise_login_required_proofs": [
|
"enterprise_login_required_proofs": [
|
||||||
"DOMAIN_RESPONSIBLE_HUMAN_ID",
|
"DOMAIN_RESPONSIBLE_HUMAN_ID",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue