@eduwork/dsh-oidc 0.1.0 → 0.2.0

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.
Files changed (58) hide show
  1. package/CHANGELOG.en.md +40 -1
  2. package/CHANGELOG.md +40 -1
  3. package/README.en.md +23 -21
  4. package/README.md +17 -15
  5. package/THIRD_PARTY_NOTICES.en.md +7 -5
  6. package/THIRD_PARTY_NOTICES.md +7 -5
  7. package/cordis.patch.yml +2 -1
  8. package/docs/EDUWORK-MIGRATION.en.md +14 -2
  9. package/docs/EDUWORK-MIGRATION.md +14 -2
  10. package/docs/account-extensions.en.md +40 -0
  11. package/docs/account-extensions.md +42 -0
  12. package/docs/architecture.en.md +9 -9
  13. package/docs/architecture.md +11 -10
  14. package/docs/compatibility.en.md +11 -2
  15. package/docs/compatibility.md +11 -2
  16. package/docs/desktop-host.en.md +69 -0
  17. package/docs/desktop-host.md +79 -0
  18. package/docs/development.en.md +42 -0
  19. package/docs/development.md +42 -0
  20. package/docs/dsh-integration.en.md +23 -7
  21. package/docs/dsh-integration.md +23 -7
  22. package/docs/ecnu-reference.en.md +3 -3
  23. package/docs/ecnu-reference.md +3 -3
  24. package/docs/enterprise-profile.en.md +19 -11
  25. package/docs/enterprise-profile.md +18 -10
  26. package/docs/getting-started.en.md +12 -12
  27. package/docs/getting-started.md +16 -14
  28. package/docs/key-binding-protocol.en.md +2 -2
  29. package/docs/key-binding-protocol.md +2 -2
  30. package/docs/oidc-interoperability.en.md +3 -3
  31. package/docs/oidc-interoperability.md +2 -2
  32. package/docs/public-resource-protocol.en.md +51 -0
  33. package/docs/public-resource-protocol.md +50 -0
  34. package/docs/release-checklist.en.md +4 -2
  35. package/docs/release-checklist.md +4 -2
  36. package/docs/server-integration-contract.en.md +124 -8
  37. package/docs/server-integration-contract.md +136 -8
  38. package/examples/ecnu.enterprise-profile.example.json +2 -2
  39. package/examples/enterprise-profile.example.json +78 -77
  40. package/examples/identity-only.example.json +10 -0
  41. package/examples/resources-discovery.example.json +20 -0
  42. package/lib/callback-page.js +42 -0
  43. package/lib/client.js +934 -294
  44. package/lib/desktop-oidc.js +205 -0
  45. package/lib/index.js +148 -18
  46. package/lib/oidc.js +314 -58
  47. package/lib/profile.js +53 -24
  48. package/lib/provider/core.js +76 -15
  49. package/lib/provider/index.js +33 -20
  50. package/lib/provider/transform-adapter.js +31 -10
  51. package/lib/resources.js +23 -0
  52. package/lib/typert-schemas.js +34 -3
  53. package/lib/typert.host.js +42 -36
  54. package/lib/typert.remote-client.js +41 -35
  55. package/package.json +100 -29
  56. package/protocol/openapi.yaml +2 -2
  57. package/protocol/resources.openapi.yaml +51 -0
  58. package/schema/enterprise-profile.v1alpha1.schema.json +193 -188
@@ -1,188 +1,193 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/freedomkk-qfeng/dsh-oidc/schema/enterprise-profile.v1alpha1.schema.json",
4
- "title": "dsh-oidc Enterprise Profile v1alpha1",
5
- "type": "object",
6
- "additionalProperties": false,
7
- "required": ["schemaVersion", "id", "displayName", "brand", "oidc", "keyBinding", "provider"],
8
- "properties": {
9
- "schemaVersion": { "const": "dsh-oidc/v1alpha1" },
10
- "id": { "$ref": "#/$defs/id" },
11
- "displayName": { "$ref": "#/$defs/nonEmpty120" },
12
- "organization": { "$ref": "#/$defs/nonEmpty120" },
13
- "nativeInstitutionID": { "type": "string", "minLength": 1, "maxLength": 64 },
14
- "allowInsecureDevelopment": { "type": "boolean", "default": false },
15
- "insecureDevelopmentOrigin": { "type": "string", "minLength": 8, "maxLength": 2048, "pattern": "^http://" },
16
- "brand": { "$ref": "#/$defs/brand" },
17
- "oidc": { "$ref": "#/$defs/oidc" },
18
- "keyBinding": { "$ref": "#/$defs/keyBinding" },
19
- "provider": { "$ref": "#/$defs/provider" }
20
- },
21
- "allOf": [
22
- {
23
- "if": {
24
- "not": {
25
- "type": "object",
26
- "properties": { "insecureDevelopmentOrigin": {} },
27
- "required": ["insecureDevelopmentOrigin"]
28
- }
29
- },
30
- "then": {
31
- "type": "object",
32
- "properties": {
33
- "oidc": { "type": "object", "properties": { "issuer": { "$ref": "#/$defs/secureEndpointURL" } } },
34
- "keyBinding": { "type": "object", "properties": { "baseURL": { "$ref": "#/$defs/secureEndpointURL" } } },
35
- "provider": { "type": "object", "properties": { "baseURL": { "$ref": "#/$defs/secureEndpointURL" } } }
36
- }
37
- }
38
- },
39
- {
40
- "if": {
41
- "type": "object",
42
- "properties": { "insecureDevelopmentOrigin": {} },
43
- "required": ["insecureDevelopmentOrigin"]
44
- },
45
- "then": { "type": "object", "properties": { "allowInsecureDevelopment": { "const": true } } }
46
- }
47
- ],
48
- "$defs": {
49
- "id": { "type": "string", "pattern": "^[a-z][a-z0-9-]{0,63}$" },
50
- "nonEmpty120": { "type": "string", "minLength": 1, "maxLength": 120, "pattern": "^\\S(?:.*\\S)?$" },
51
- "positiveInteger": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
52
- "httpsURL": { "type": "string", "minLength": 9, "maxLength": 2048, "pattern": "^https://" },
53
- "secureEndpointURL": { "type": "string", "minLength": 9, "maxLength": 2048, "pattern": "^(https://|http://(localhost|127\\.0\\.0\\.1|\\[::1\\])(?=[:/]))" },
54
- "endpointURL": { "type": "string", "minLength": 8, "maxLength": 2048, "pattern": "^(https://|http://)" },
55
- "brand": {
56
- "type": "object",
57
- "additionalProperties": false,
58
- "properties": {
59
- "productName": { "type": "string", "minLength": 1, "maxLength": 80 },
60
- "organizationName": { "$ref": "#/$defs/nonEmpty120" },
61
- "mark": { "type": "string", "minLength": 1, "maxLength": 4 },
62
- "logoURL": { "type": "string", "minLength": 9, "maxLength": 131072, "pattern": "^(https://|data:image/(png|webp);base64,)" },
63
- "primaryColor": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" },
64
- "loginTitle": { "type": "string", "minLength": 1, "maxLength": 120 },
65
- "loginDescription": { "type": "string", "minLength": 1, "maxLength": 500 },
66
- "supportURL": { "$ref": "#/$defs/httpsURL" }
67
- }
68
- },
69
- "oidc": {
70
- "type": "object",
71
- "additionalProperties": false,
72
- "required": ["issuer", "clientId", "scopes"],
73
- "properties": {
74
- "issuer": { "$ref": "#/$defs/endpointURL" },
75
- "clientId": { "type": "string", "minLength": 1, "maxLength": 256 },
76
- "scopes": {
77
- "type": "array",
78
- "minItems": 2,
79
- "maxItems": 64,
80
- "uniqueItems": true,
81
- "allOf": [
82
- { "contains": { "const": "openid" } },
83
- { "contains": { "const": "profile" } }
84
- ],
85
- "items": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^\\S+$" }
86
- }
87
- }
88
- },
89
- "keyBinding": {
90
- "type": "object",
91
- "additionalProperties": false,
92
- "required": ["baseURL"],
93
- "properties": {
94
- "baseURL": { "$ref": "#/$defs/endpointURL" },
95
- "credentialRef": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$", "maxLength": 128 }
96
- }
97
- },
98
- "compat": {
99
- "type": "object",
100
- "additionalProperties": false,
101
- "properties": {
102
- "supportsDeveloperRole": { "type": "boolean" },
103
- "supportsStore": { "type": "boolean" },
104
- "supportsReasoningEffort": { "type": "boolean" },
105
- "supportsUsageInStreaming": { "type": "boolean" },
106
- "maxTokensField": { "enum": ["max_completion_tokens", "max_tokens"] },
107
- "supportsStrictMode": { "type": "boolean" },
108
- "supportsLongCacheRetention": { "type": "boolean" },
109
- "thinkingFormat": { "enum": ["openai", "deepseek", "openrouter", "together", "baseten", "zai", "qwen", "chat-template", "qwen-chat-template", "string-thinking", "ant-ling"] },
110
- "requiresReasoningContentOnAssistantMessages": { "type": "boolean" }
111
- }
112
- },
113
- "retryPolicy": {
114
- "type": "object",
115
- "additionalProperties": false,
116
- "required": ["mode"],
117
- "properties": {
118
- "mode": { "enum": ["normal", "always"] },
119
- "maxRetries": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
120
- "retryableCodes": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 128 } },
121
- "backoff": {
122
- "type": "object",
123
- "additionalProperties": false,
124
- "properties": {
125
- "initialDelayMs": { "type": "number", "exclusiveMinimum": 0, "maximum": 2147483647 },
126
- "maxDelayMs": { "type": "number", "exclusiveMinimum": 0, "maximum": 2147483647 },
127
- "jitterRatio": { "type": "number", "minimum": 0, "maximum": 1 }
128
- }
129
- }
130
- }
131
- },
132
- "model": {
133
- "type": "object",
134
- "additionalProperties": false,
135
- "required": ["id"],
136
- "properties": {
137
- "id": { "type": "string", "minLength": 1, "maxLength": 256 },
138
- "name": { "type": "string", "minLength": 1, "maxLength": 256 },
139
- "input": { "type": "array", "minItems": 1, "maxItems": 2, "uniqueItems": true, "items": { "enum": ["text", "image"] } },
140
- "contextWindow": { "$ref": "#/$defs/positiveInteger" },
141
- "maxTokens": { "$ref": "#/$defs/positiveInteger" },
142
- "reasoning": { "type": "boolean" },
143
- "reasoningEfforts": {
144
- "oneOf": [
145
- { "const": false },
146
- {
147
- "type": "object",
148
- "minProperties": 1,
149
- "maxProperties": 7,
150
- "additionalProperties": false,
151
- "properties": {
152
- "off": { "type": ["string", "null"], "minLength": 1, "maxLength": 32 },
153
- "minimal": { "type": "string", "minLength": 1, "maxLength": 32 },
154
- "low": { "type": "string", "minLength": 1, "maxLength": 32 },
155
- "medium": { "type": "string", "minLength": 1, "maxLength": 32 },
156
- "high": { "type": "string", "minLength": 1, "maxLength": 32 },
157
- "xhigh": { "type": "string", "minLength": 1, "maxLength": 32 },
158
- "max": { "type": "string", "minLength": 1, "maxLength": 32 }
159
- }
160
- }
161
- ]
162
- },
163
- "compat": { "$ref": "#/$defs/compat" }
164
- }
165
- },
166
- "provider": {
167
- "type": "object",
168
- "additionalProperties": false,
169
- "required": ["id", "adapter", "baseURL", "models"],
170
- "properties": {
171
- "id": { "$ref": "#/$defs/id" },
172
- "displayName": { "$ref": "#/$defs/nonEmpty120" },
173
- "adapter": { "const": "openai-compatible" },
174
- "baseURL": { "$ref": "#/$defs/endpointURL" },
175
- "reasoning": { "enum": ["off", "minimal", "low", "medium", "high", "xhigh", "max"] },
176
- "defaultContextWindow": { "$ref": "#/$defs/positiveInteger" },
177
- "defaultMaxTokens": { "$ref": "#/$defs/positiveInteger" },
178
- "maxRequestImageBytes": { "$ref": "#/$defs/positiveInteger" },
179
- "requestImagePixelBudget": { "$ref": "#/$defs/positiveInteger" },
180
- "requestImageMaxBytes": { "$ref": "#/$defs/positiveInteger" },
181
- "streamIdleTimeoutMs": { "$ref": "#/$defs/positiveInteger" },
182
- "retryPolicy": { "$ref": "#/$defs/retryPolicy" },
183
- "compat": { "$ref": "#/$defs/compat" },
184
- "models": { "type": "array", "minItems": 1, "maxItems": 128, "items": { "$ref": "#/$defs/model" } }
185
- }
186
- }
187
- }
188
- }
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/freedomkk-qfeng/dsh-oidc/schema/enterprise-profile.v1alpha1.schema.json",
4
+ "title": "dsh-oidc Enterprise Profile v1alpha1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "id", "displayName", "oidc"],
8
+ "dependentRequired": { "keyBinding": ["provider"], "provider": ["keyBinding"] },
9
+ "properties": {
10
+ "schemaVersion": { "const": "dsh-oidc/v1alpha1" },
11
+ "id": { "$ref": "#/$defs/id" },
12
+ "displayName": { "$ref": "#/$defs/nonEmpty120" },
13
+ "organization": { "$ref": "#/$defs/nonEmpty120" },
14
+ "nativeInstitutionID": { "type": "string", "minLength": 1, "maxLength": 64 },
15
+ "allowInsecureDevelopment": { "type": "boolean", "default": false },
16
+ "insecureDevelopmentOrigin": { "type": "string", "minLength": 8, "maxLength": 2048, "pattern": "^http://" },
17
+ "brand": { "$ref": "#/$defs/brand" },
18
+ "oidc": { "$ref": "#/$defs/oidc" },
19
+ "keyBinding": { "$ref": "#/$defs/keyBinding" },
20
+ "provider": { "$ref": "#/$defs/provider" }
21
+ },
22
+ "allOf": [
23
+ {
24
+ "if": {
25
+ "not": {
26
+ "type": "object",
27
+ "properties": { "insecureDevelopmentOrigin": {} },
28
+ "required": ["insecureDevelopmentOrigin"]
29
+ }
30
+ },
31
+ "then": {
32
+ "type": "object",
33
+ "properties": {
34
+ "oidc": { "type": "object", "properties": { "issuer": { "$ref": "#/$defs/secureEndpointURL" } } },
35
+ "keyBinding": { "type": "object", "properties": { "baseURL": { "$ref": "#/$defs/secureEndpointURL" } } },
36
+ "provider": { "type": "object", "properties": { "baseURL": { "$ref": "#/$defs/secureEndpointURL" } } }
37
+ }
38
+ }
39
+ },
40
+ {
41
+ "if": {
42
+ "type": "object",
43
+ "properties": { "insecureDevelopmentOrigin": {} },
44
+ "required": ["insecureDevelopmentOrigin"]
45
+ },
46
+ "then": { "type": "object", "properties": { "allowInsecureDevelopment": { "const": true } } }
47
+ }
48
+ ],
49
+ "$defs": {
50
+ "id": { "type": "string", "pattern": "^[a-z][a-z0-9-]{0,63}$" },
51
+ "nonEmpty120": { "type": "string", "minLength": 1, "maxLength": 120, "pattern": "^\\S(?:.*\\S)?$" },
52
+ "positiveInteger": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
53
+ "httpsURL": { "type": "string", "minLength": 9, "maxLength": 2048, "pattern": "^https://" },
54
+ "secureEndpointURL": { "type": "string", "minLength": 9, "maxLength": 2048, "pattern": "^(https://|http://(localhost|127\\.0\\.0\\.1|\\[::1\\])(?=[:/]))" },
55
+ "endpointURL": { "type": "string", "minLength": 8, "maxLength": 2048, "pattern": "^(https://|http://)" },
56
+ "brand": {
57
+ "type": "object",
58
+ "additionalProperties": false,
59
+ "properties": {
60
+ "productName": { "type": "string", "minLength": 1, "maxLength": 80 },
61
+ "organizationName": { "$ref": "#/$defs/nonEmpty120" },
62
+ "mark": { "type": "string", "minLength": 1, "maxLength": 4 },
63
+ "logoURL": { "type": "string", "minLength": 9, "maxLength": 131072, "pattern": "^(https://|data:image/(png|webp);base64,)" },
64
+ "primaryColor": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}$" },
65
+ "loginTitle": { "type": "string", "minLength": 1, "maxLength": 120 },
66
+ "loginDescription": { "type": "string", "minLength": 1, "maxLength": 500 },
67
+ "supportURL": { "$ref": "#/$defs/httpsURL" }
68
+ }
69
+ },
70
+ "oidc": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["issuer", "clientId", "scopes"],
74
+ "properties": {
75
+ "issuer": { "$ref": "#/$defs/endpointURL" },
76
+ "clientId": { "type": "string", "minLength": 1, "maxLength": 256 },
77
+ "scopes": {
78
+ "type": "array",
79
+ "minItems": 2,
80
+ "maxItems": 64,
81
+ "uniqueItems": true,
82
+ "allOf": [
83
+ { "contains": { "const": "openid" } },
84
+ { "contains": { "const": "profile" } }
85
+ ],
86
+ "items": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^\\S+$" }
87
+ }
88
+ }
89
+ },
90
+ "keyBinding": {
91
+ "type": "object",
92
+ "additionalProperties": false,
93
+ "required": ["baseURL"],
94
+ "properties": {
95
+ "type": { "enum": ["worker-user-center-v1", "eduwork-resources-v1"], "default": "worker-user-center-v1" },
96
+ "baseURL": { "$ref": "#/$defs/endpointURL" },
97
+ "credentialRef": { "type": "string", "default": "EDUWORK_API_KEY", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$", "maxLength": 128 }
98
+ }
99
+ },
100
+ "compat": {
101
+ "type": "object",
102
+ "additionalProperties": false,
103
+ "properties": {
104
+ "supportsDeveloperRole": { "type": "boolean" },
105
+ "supportsStore": { "type": "boolean" },
106
+ "supportsReasoningEffort": { "type": "boolean" },
107
+ "supportsUsageInStreaming": { "type": "boolean" },
108
+ "maxTokensField": { "enum": ["max_completion_tokens", "max_tokens"] },
109
+ "supportsStrictMode": { "type": "boolean" },
110
+ "supportsLongCacheRetention": { "type": "boolean" },
111
+ "thinkingFormat": { "enum": ["openai", "deepseek", "openrouter", "together", "baseten", "zai", "qwen", "chat-template", "qwen-chat-template", "string-thinking", "ant-ling"] },
112
+ "requiresReasoningContentOnAssistantMessages": { "type": "boolean" }
113
+ }
114
+ },
115
+ "retryPolicy": {
116
+ "type": "object",
117
+ "additionalProperties": false,
118
+ "required": ["mode"],
119
+ "properties": {
120
+ "mode": { "enum": ["normal", "always"] },
121
+ "maxRetries": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
122
+ "retryableCodes": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 128 } },
123
+ "backoff": {
124
+ "type": "object",
125
+ "additionalProperties": false,
126
+ "properties": {
127
+ "initialDelayMs": { "type": "number", "exclusiveMinimum": 0, "maximum": 2147483647 },
128
+ "maxDelayMs": { "type": "number", "exclusiveMinimum": 0, "maximum": 2147483647 },
129
+ "jitterRatio": { "type": "number", "minimum": 0, "maximum": 1 }
130
+ }
131
+ }
132
+ }
133
+ },
134
+ "model": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "required": ["id"],
138
+ "properties": {
139
+ "id": { "type": "string", "minLength": 1, "maxLength": 256 },
140
+ "name": { "type": "string", "minLength": 1, "maxLength": 256 },
141
+ "input": { "type": "array", "minItems": 1, "maxItems": 2, "uniqueItems": true, "items": { "enum": ["text", "image"] } },
142
+ "contextWindow": { "$ref": "#/$defs/positiveInteger" },
143
+ "maxTokens": { "$ref": "#/$defs/positiveInteger" },
144
+ "reasoning": { "type": "boolean" },
145
+ "defaultReasoningEffort": { "enum": ["off", "minimal", "low", "medium", "high", "xhigh", "max"] },
146
+ "reasoningEfforts": {
147
+ "oneOf": [
148
+ { "const": false },
149
+ {
150
+ "type": "object",
151
+ "minProperties": 1,
152
+ "maxProperties": 7,
153
+ "additionalProperties": false,
154
+ "properties": {
155
+ "off": { "type": ["string", "null"], "minLength": 1, "maxLength": 32 },
156
+ "minimal": { "type": "string", "minLength": 1, "maxLength": 32 },
157
+ "low": { "type": "string", "minLength": 1, "maxLength": 32 },
158
+ "medium": { "type": "string", "minLength": 1, "maxLength": 32 },
159
+ "high": { "type": "string", "minLength": 1, "maxLength": 32 },
160
+ "xhigh": { "type": "string", "minLength": 1, "maxLength": 32 },
161
+ "max": { "type": "string", "minLength": 1, "maxLength": 32 }
162
+ }
163
+ }
164
+ ]
165
+ },
166
+ "compat": { "$ref": "#/$defs/compat" }
167
+ }
168
+ },
169
+ "provider": {
170
+ "type": "object",
171
+ "additionalProperties": false,
172
+ "required": ["id", "adapter", "baseURL"],
173
+ "allOf": [{ "if": { "required": ["modelSource"], "properties": { "modelSource": { "const": "discovery" } } }, "else": { "required": ["models"], "properties": { "models": { "type": "array", "minItems": 1 } } } }],
174
+ "properties": {
175
+ "id": { "$ref": "#/$defs/id" },
176
+ "displayName": { "$ref": "#/$defs/nonEmpty120" },
177
+ "adapter": { "const": "openai-compatible" },
178
+ "baseURL": { "$ref": "#/$defs/endpointURL" },
179
+ "reasoning": { "enum": ["off", "minimal", "low", "medium", "high", "xhigh", "max"] },
180
+ "defaultContextWindow": { "$ref": "#/$defs/positiveInteger" },
181
+ "defaultMaxTokens": { "$ref": "#/$defs/positiveInteger" },
182
+ "maxRequestImageBytes": { "$ref": "#/$defs/positiveInteger" },
183
+ "requestImagePixelBudget": { "$ref": "#/$defs/positiveInteger" },
184
+ "requestImageMaxBytes": { "$ref": "#/$defs/positiveInteger" },
185
+ "streamIdleTimeoutMs": { "$ref": "#/$defs/positiveInteger" },
186
+ "retryPolicy": { "$ref": "#/$defs/retryPolicy" },
187
+ "compat": { "$ref": "#/$defs/compat" },
188
+ "modelSource": { "enum": ["profile", "discovery"], "default": "profile" },
189
+ "models": { "type": "array", "minItems": 0, "maxItems": 128, "items": { "$ref": "#/$defs/model" } }
190
+ }
191
+ }
192
+ }
193
+ }