@phygitallabs/phygital-consent 1.0.20 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/api/docs.json CHANGED
@@ -1,218 +1,292 @@
1
1
  {
2
- "schemes": [],
3
- "swagger": "2.0",
4
- "info": {
5
- "description": "Nomion Consent Service (NCS) – consent logging and retrieval. All APIs are public.",
6
- "title": "Phygital Consent API",
7
- "termsOfService": "http://swagger.io/terms/",
8
- "contact": {
9
- "name": "API Support",
10
- "url": "http://www.swagger.io/support",
11
- "email": "support@swagger.io"
12
- },
13
- "license": {
14
- "name": "Apache 2.0",
15
- "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
16
- },
17
- "version": "1.0"
2
+ "schemes": [],
3
+ "swagger": "2.0",
4
+ "info": {
5
+ "description": "Nomion Consent Service (NCS) – consent logging and retrieval. All APIs are public.",
6
+ "title": "Phygital Consent API",
7
+ "termsOfService": "http://swagger.io/terms/",
8
+ "contact": {
9
+ "name": "API Support",
10
+ "url": "http://www.swagger.io/support",
11
+ "email": "support@swagger.io"
18
12
  },
19
- "host": "localhost:8080",
20
- "basePath": "/",
21
- "paths": {
22
- "/health": {
23
- "get": {
24
- "summary": "Health check",
25
- "produces": ["application/json"],
26
- "responses": {
27
- "200": { "description": "OK" }
28
- }
29
- }
30
- },
31
- "/consent/v1/consent": {
32
- "get": {
33
- "tags": ["consent"],
34
- "summary": "Get all consent logs",
35
- "parameters": [
36
- { "type": "string", "name": "type", "in": "query", "description": "Filter by policy type (ACCOUNT_REGISTER | COOKIE_PREFERENCE)" },
37
- { "type": "string", "name": "user_agent", "in": "query", "description": "Filter by User-Agent" },
38
- { "type": "string", "name": "page_url", "in": "query", "description": "Filter by page URL" }
39
- ],
40
- "responses": {
41
- "200": { "description": "OK" },
42
- "500": { "description": "Internal Server Error" }
43
- }
44
- }
13
+ "license": {
14
+ "name": "Apache 2.0",
15
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
16
+ },
17
+ "version": "1.0"
18
+ },
19
+ "host": "localhost:8080",
20
+ "basePath": "/",
21
+ "paths": {
22
+ "/health": {
23
+ "get": {
24
+ "summary": "Health check",
25
+ "produces": ["application/json"],
26
+ "responses": {
27
+ "200": { "description": "OK" }
28
+ }
29
+ }
30
+ },
31
+ "/consent/v1/consent": {
32
+ "get": {
33
+ "tags": ["consent"],
34
+ "summary": "Get all consent logs",
35
+ "parameters": [
36
+ {
37
+ "type": "string",
38
+ "name": "type",
39
+ "in": "query",
40
+ "description": "Filter by policy type (ACCOUNT_REGISTER | COOKIE_PREFERENCE)"
41
+ },
42
+ {
43
+ "type": "string",
44
+ "name": "user_agent",
45
+ "in": "query",
46
+ "description": "Filter by User-Agent"
47
+ },
48
+ {
49
+ "type": "string",
50
+ "name": "page_url",
51
+ "in": "query",
52
+ "description": "Filter by page URL"
53
+ }
54
+ ],
55
+ "responses": {
56
+ "200": { "description": "OK" },
57
+ "500": { "description": "Internal Server Error" }
58
+ }
59
+ }
60
+ },
61
+ "/consent/v1/consent/{id}": {
62
+ "get": {
63
+ "tags": ["consent"],
64
+ "summary": "Get consent log by ID",
65
+ "parameters": [{ "type": "string", "name": "id", "in": "path", "required": true }],
66
+ "responses": {
67
+ "200": { "description": "OK" },
68
+ "400": { "description": "Bad Request" },
69
+ "404": { "description": "Not Found" },
70
+ "500": { "description": "Internal Server Error" }
71
+ }
72
+ }
73
+ },
74
+ "/consent/v1/user-id": {
75
+ "get": {
76
+ "tags": ["consent"],
77
+ "summary": "Get latest consent for a user",
78
+ "parameters": [{ "type": "string", "name": "user_id", "in": "query", "required": true }],
79
+ "responses": {
80
+ "200": { "description": "OK" },
81
+ "400": { "description": "Bad Request" },
82
+ "404": { "description": "Not Found" },
83
+ "500": { "description": "Internal Server Error" }
84
+ }
85
+ },
86
+ "post": {
87
+ "tags": ["consent"],
88
+ "summary": "Create user consent (account register)",
89
+ "description": "Creates consent for the authenticated user. Backend uses latest active ACCOUNT_REGISTER policy (Terms + Privacy in documents[]).",
90
+ "consumes": ["application/json"],
91
+ "produces": ["application/json"],
92
+ "parameters": [
93
+ {
94
+ "in": "body",
95
+ "name": "body",
96
+ "required": true,
97
+ "schema": { "$ref": "#/definitions/CreateUserConsentUpsertDTO" }
98
+ }
99
+ ],
100
+ "responses": {
101
+ "201": {
102
+ "description": "Created",
103
+ "schema": { "$ref": "#/definitions/ConsentLogDetailDTO" }
104
+ },
105
+ "400": { "description": "Bad Request (invalid body, invalid consent status)" },
106
+ "404": { "description": "Not Found (no active account register policy)" },
107
+ "500": { "description": "Internal Server Error" }
108
+ }
109
+ }
110
+ },
111
+ "/consent/v1/cookies/device-id": {
112
+ "get": {
113
+ "tags": ["consent"],
114
+ "summary": "Get latest cookie consent for a device",
115
+ "parameters": [{ "type": "string", "name": "device_id", "in": "query", "required": true }],
116
+ "responses": {
117
+ "200": { "description": "OK" },
118
+ "400": { "description": "Bad Request" },
119
+ "404": { "description": "Not Found" },
120
+ "500": { "description": "Internal Server Error" }
121
+ }
122
+ },
123
+ "post": {
124
+ "tags": ["consent"],
125
+ "summary": "Create device cookie consent",
126
+ "description": "Creates cookie consent for anonymous user (device).",
127
+ "consumes": ["application/json"],
128
+ "produces": ["application/json"],
129
+ "parameters": [
130
+ {
131
+ "in": "body",
132
+ "name": "body",
133
+ "required": true,
134
+ "schema": { "$ref": "#/definitions/CreateDeviceCookieConsentUpsertDTO" }
135
+ }
136
+ ],
137
+ "responses": {
138
+ "201": {
139
+ "description": "Created",
140
+ "schema": { "$ref": "#/definitions/ConsentLogDetailDTO" }
141
+ },
142
+ "400": {
143
+ "description": "Bad Request (invalid body, missing essential preference, invalid status)"
144
+ },
145
+ "404": { "description": "Not Found (no active cookie preference policy)" },
146
+ "500": { "description": "Internal Server Error" }
147
+ }
148
+ }
149
+ },
150
+ "/consent/v1/policy": {
151
+ "get": {
152
+ "tags": ["policy"],
153
+ "summary": "Get policies",
154
+ "description": "Get all policies with optional filters (type, version, status)",
155
+ "produces": ["application/json"],
156
+ "parameters": [
157
+ {
158
+ "type": "string",
159
+ "name": "type",
160
+ "in": "query",
161
+ "description": "Filter by policy type (ACCOUNT_REGISTER | COOKIE_PREFERENCE)"
162
+ },
163
+ {
164
+ "type": "string",
165
+ "name": "version",
166
+ "in": "query",
167
+ "description": "Filter by version"
168
+ },
169
+ {
170
+ "type": "string",
171
+ "name": "status",
172
+ "in": "query",
173
+ "enum": ["ACTIVE", "INACTIVE"],
174
+ "description": "Filter by status"
175
+ }
176
+ ],
177
+ "responses": {
178
+ "200": {
179
+ "description": "OK",
180
+ "schema": { "type": "array", "items": { "$ref": "#/definitions/PolicyDetailDTO" } }
181
+ },
182
+ "400": { "description": "Bad Request (invalid query or invalid policy type)" },
183
+ "500": { "description": "Internal Server Error" }
184
+ }
185
+ }
186
+ }
187
+ },
188
+ "definitions": {
189
+ "CreateUserConsentUpsertDTO": {
190
+ "type": "object",
191
+ "required": ["status"],
192
+ "properties": {
193
+ "user_id": { "type": "string", "description": "Hashed user ID (optional)" },
194
+ "device_id": { "type": "string", "description": "Hashed device ID (optional for user-id)" },
195
+ "selected_preferences": {
196
+ "type": "array",
197
+ "items": { "type": "string" },
198
+ "description": "Optional for account register"
45
199
  },
46
- "/consent/v1/consent/{id}": {
47
- "get": {
48
- "tags": ["consent"],
49
- "summary": "Get consent log by ID",
50
- "parameters": [
51
- { "type": "string", "name": "id", "in": "path", "required": true }
52
- ],
53
- "responses": {
54
- "200": { "description": "OK" },
55
- "400": { "description": "Bad Request" },
56
- "404": { "description": "Not Found" },
57
- "500": { "description": "Internal Server Error" }
58
- }
59
- }
200
+ "status": { "type": "string", "enum": ["ACCEPTED", "REJECTED"] },
201
+ "user_agent": {
202
+ "type": "string",
203
+ "description": "Client User-Agent when consent was given"
60
204
  },
61
- "/consent/v1/user-id": {
62
- "get": {
63
- "tags": ["consent"],
64
- "summary": "Get latest consent for a user",
65
- "parameters": [
66
- { "type": "string", "name": "user_id", "in": "query", "required": true }
67
- ],
68
- "responses": {
69
- "200": { "description": "OK" },
70
- "400": { "description": "Bad Request" },
71
- "404": { "description": "Not Found" },
72
- "500": { "description": "Internal Server Error" }
73
- }
74
- },
75
- "post": {
76
- "tags": ["consent"],
77
- "summary": "Create user consent (account register)",
78
- "description": "Creates consent for the authenticated user. Backend uses latest active ACCOUNT_REGISTER policy (Terms + Privacy in documents[]).",
79
- "consumes": ["application/json"],
80
- "produces": ["application/json"],
81
- "parameters": [
82
- { "in": "body", "name": "body", "required": true, "schema": { "$ref": "#/definitions/CreateUserConsentUpsertDTO" } }
83
- ],
84
- "responses": {
85
- "201": { "description": "Created", "schema": { "$ref": "#/definitions/ConsentLogDetailDTO" } },
86
- "400": { "description": "Bad Request (invalid body, invalid consent status)" },
87
- "404": { "description": "Not Found (no active account register policy)" },
88
- "500": { "description": "Internal Server Error" }
89
- }
90
- }
205
+ "page_url": { "type": "string", "description": "Page URL where consent was given" }
206
+ }
207
+ },
208
+ "CreateDeviceCookieConsentUpsertDTO": {
209
+ "type": "object",
210
+ "required": ["device_id", "status"],
211
+ "properties": {
212
+ "device_id": { "type": "string", "description": "Hashed device ID" },
213
+ "selected_preferences": {
214
+ "type": "array",
215
+ "items": { "type": "string" },
216
+ "description": "Must include \"essential\""
91
217
  },
92
- "/consent/v1/cookies/device-id": {
93
- "get": {
94
- "tags": ["consent"],
95
- "summary": "Get latest cookie consent for a device",
96
- "parameters": [
97
- { "type": "string", "name": "device_id", "in": "query", "required": true }
98
- ],
99
- "responses": {
100
- "200": { "description": "OK" },
101
- "400": { "description": "Bad Request" },
102
- "404": { "description": "Not Found" },
103
- "500": { "description": "Internal Server Error" }
104
- }
105
- },
106
- "post": {
107
- "tags": ["consent"],
108
- "summary": "Create device cookie consent",
109
- "description": "Creates cookie consent for anonymous user (device).",
110
- "consumes": ["application/json"],
111
- "produces": ["application/json"],
112
- "parameters": [
113
- { "in": "body", "name": "body", "required": true, "schema": { "$ref": "#/definitions/CreateDeviceCookieConsentUpsertDTO" } }
114
- ],
115
- "responses": {
116
- "201": { "description": "Created", "schema": { "$ref": "#/definitions/ConsentLogDetailDTO" } },
117
- "400": { "description": "Bad Request (invalid body, missing essential preference, invalid status)" },
118
- "404": { "description": "Not Found (no active cookie preference policy)" },
119
- "500": { "description": "Internal Server Error" }
120
- }
121
- }
218
+ "status": { "type": "string", "enum": ["ACCEPTED", "REJECTED"] },
219
+ "user_agent": {
220
+ "type": "string",
221
+ "description": "Client User-Agent when consent was given"
122
222
  },
123
- "/consent/v1/policy": {
124
- "get": {
125
- "tags": ["policy"],
126
- "summary": "Get policies",
127
- "description": "Get all policies with optional filters (type, version, status)",
128
- "produces": ["application/json"],
129
- "parameters": [
130
- { "type": "string", "name": "type", "in": "query", "description": "Filter by policy type (ACCOUNT_REGISTER | COOKIE_PREFERENCE)" },
131
- { "type": "string", "name": "version", "in": "query", "description": "Filter by version" },
132
- { "type": "string", "name": "status", "in": "query", "enum": ["ACTIVE", "INACTIVE"], "description": "Filter by status" }
133
- ],
134
- "responses": {
135
- "200": { "description": "OK", "schema": { "type": "array", "items": { "$ref": "#/definitions/PolicyDetailDTO" } } },
136
- "400": { "description": "Bad Request (invalid query or invalid policy type)" },
137
- "500": { "description": "Internal Server Error" }
138
- }
139
- }
140
- }
223
+ "page_url": { "type": "string", "description": "Page URL where consent was given" }
224
+ }
141
225
  },
142
- "definitions": {
143
- "CreateUserConsentUpsertDTO": {
144
- "type": "object",
145
- "required": ["status"],
146
- "properties": {
147
- "user_id": { "type": "string", "description": "Hashed user ID (optional)" },
148
- "device_id": { "type": "string", "description": "Hashed device ID (optional for user-id)" },
149
- "selected_preferences": { "type": "array", "items": { "type": "string" }, "description": "Optional for account register" },
150
- "status": { "type": "string", "enum": ["ACCEPTED", "REJECTED"] },
151
- "user_agent": { "type": "string", "description": "Client User-Agent when consent was given" },
152
- "page_url": { "type": "string", "description": "Page URL where consent was given" }
153
- }
154
- },
155
- "CreateDeviceCookieConsentUpsertDTO": {
156
- "type": "object",
157
- "required": ["device_id", "status"],
158
- "properties": {
159
- "device_id": { "type": "string", "description": "Hashed device ID" },
160
- "selected_preferences": { "type": "array", "items": { "type": "string" }, "description": "Must include \"essential\"" },
161
- "status": { "type": "string", "enum": ["ACCEPTED", "REJECTED"] },
162
- "user_agent": { "type": "string", "description": "Client User-Agent when consent was given" },
163
- "page_url": { "type": "string", "description": "Page URL where consent was given" }
164
- }
226
+ "ConsentLogDetailDTO": {
227
+ "type": "object",
228
+ "properties": {
229
+ "id": { "type": "string" },
230
+ "user_id": { "type": "string" },
231
+ "device_uid": { "type": "string" },
232
+ "policy_id": { "type": "string" },
233
+ "policy": {
234
+ "$ref": "#/definitions/PolicyDetailDTO",
235
+ "description": "Full policy (joined); all fields from policy"
165
236
  },
166
- "ConsentLogDetailDTO": {
167
- "type": "object",
168
- "properties": {
169
- "id": { "type": "string" },
170
- "user_id": { "type": "string" },
171
- "device_uid": { "type": "string" },
172
- "policy_id": { "type": "string" },
173
- "policy": { "$ref": "#/definitions/PolicyDetailDTO", "description": "Full policy (joined); all fields from policy" },
174
- "selected_preferences": { "type": "array", "items": { "type": "string" }, "description": "Only present when policy.type is COOKIE_PREFERENCE" },
175
- "status": { "type": "string", "enum": ["ACCEPTED", "REJECTED"] },
176
- "user_agent": { "type": "string", "description": "Client User-Agent when consent was given" },
177
- "page_url": { "type": "string", "description": "Page URL where consent was given" },
178
- "created_at": { "type": "string", "format": "date-time" }
179
- }
237
+ "selected_preferences": {
238
+ "type": "array",
239
+ "items": { "type": "string" },
240
+ "description": "Only present when policy.type is COOKIE_PREFERENCE"
180
241
  },
181
- "PolicyDetailDTO": {
182
- "type": "object",
183
- "properties": {
184
- "id": { "type": "string" },
185
- "name": { "type": "string" },
186
- "description": { "type": "string" },
187
- "type": { "type": "string", "enum": ["ACCOUNT_REGISTER", "COOKIE_PREFERENCE"] },
188
- "documents": { "type": "array", "items": { "$ref": "#/definitions/PolicyDocument" }, "description": "For ACCOUNT_REGISTER: Terms of Service, Privacy Policy, etc." },
189
- "preferences": { "type": "array", "items": { "$ref": "#/definitions/PolicyPreference" } },
190
- "version": { "type": "string" },
191
- "meta_data": { "type": "object" },
192
- "created_at": { "type": "string", "format": "date-time" },
193
- "updated_at": { "type": "string", "format": "date-time" },
194
- "status": { "type": "string", "enum": ["ACTIVE", "INACTIVE"] }
195
- }
242
+ "status": { "type": "string", "enum": ["ACCEPTED", "REJECTED"] },
243
+ "user_agent": {
244
+ "type": "string",
245
+ "description": "Client User-Agent when consent was given"
196
246
  },
197
- "PolicyDocument": {
198
- "type": "object",
199
- "description": "Document within a policy (e.g. Terms of Service, Privacy Policy)",
200
- "properties": {
201
- "name": { "type": "string" },
202
- "version": { "type": "string" },
203
- "effective_date": { "type": "string", "format": "date-time" },
204
- "last_updated": { "type": "string", "format": "date-time" },
205
- "meta_data": { "type": "object" }
206
- }
247
+ "page_url": { "type": "string", "description": "Page URL where consent was given" },
248
+ "created_at": { "type": "string", "format": "date-time" }
249
+ }
250
+ },
251
+ "PolicyDetailDTO": {
252
+ "type": "object",
253
+ "properties": {
254
+ "id": { "type": "string" },
255
+ "name": { "type": "string" },
256
+ "description": { "type": "string" },
257
+ "type": { "type": "string", "enum": ["ACCOUNT_REGISTER", "COOKIE_PREFERENCE"] },
258
+ "documents": {
259
+ "type": "array",
260
+ "items": { "$ref": "#/definitions/PolicyDocument" },
261
+ "description": "For ACCOUNT_REGISTER: Terms of Service, Privacy Policy, etc."
207
262
  },
208
- "PolicyPreference": {
209
- "type": "object",
210
- "properties": {
211
- "id": { "type": "string" },
212
- "name": { "type": "string" },
213
- "description": { "type": "string" },
214
- "is_mandatory": { "type": "boolean" }
215
- }
216
- }
263
+ "preferences": { "type": "array", "items": { "$ref": "#/definitions/PolicyPreference" } },
264
+ "version": { "type": "string" },
265
+ "meta_data": { "type": "object" },
266
+ "created_at": { "type": "string", "format": "date-time" },
267
+ "updated_at": { "type": "string", "format": "date-time" },
268
+ "status": { "type": "string", "enum": ["ACTIVE", "INACTIVE"] }
269
+ }
270
+ },
271
+ "PolicyDocument": {
272
+ "type": "object",
273
+ "description": "Document within a policy (e.g. Terms of Service, Privacy Policy)",
274
+ "properties": {
275
+ "name": { "type": "string" },
276
+ "version": { "type": "string" },
277
+ "effective_date": { "type": "string", "format": "date-time" },
278
+ "last_updated": { "type": "string", "format": "date-time" },
279
+ "meta_data": { "type": "object" }
280
+ }
281
+ },
282
+ "PolicyPreference": {
283
+ "type": "object",
284
+ "properties": {
285
+ "id": { "type": "string" },
286
+ "name": { "type": "string" },
287
+ "description": { "type": "string" },
288
+ "is_mandatory": { "type": "boolean" }
289
+ }
217
290
  }
218
- }
291
+ }
292
+ }
@@ -73,31 +73,20 @@ export function PolicyPopup({
73
73
  <>
74
74
  {/* Policy modal */}
75
75
  <div
76
- role="dialog"
77
- aria-modal="true"
78
- aria-label="Chính sách bảo mật"
79
76
  style={{
80
77
  display: "flex",
81
78
  alignItems: "center",
82
79
  justifyContent: "center",
83
- backgroundColor: "rgba(0,0,0,0.5)",
84
- padding: "1rem",
85
80
  }}
86
81
  >
87
82
  <div
88
- className="consent:bg-white consent:rounded-xl consent:border consent:border-gray-200 consent:shadow-lg consent:max-h-[90vh] consent:overflow-hidden consent:flex consent:flex-col"
83
+ className="consent:overflow-hidden consent:flex consent:flex-col"
89
84
  style={{
90
- backgroundColor: "#fff",
91
- borderRadius: "0.75rem",
92
- border: "1px solid #e5e7eb",
93
- boxShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1)",
94
- maxWidth: "28rem",
95
85
  width: "100%",
96
- maxHeight: "90vh",
86
+ height: "100%",
97
87
  overflow: "hidden",
98
88
  display: "flex",
99
89
  flexDirection: "column",
100
- position: "relative",
101
90
  }}
102
91
  onClick={(e) => e.stopPropagation()}
103
92
  >
@@ -124,7 +113,7 @@ export function PolicyPopup({
124
113
  </button> */}
125
114
  <h2
126
115
  style={{
127
- fontSize: "18px",
116
+ fontSize: "20px",
128
117
  fontWeight: 600,
129
118
  color: "#000",
130
119
  padding: "20px 2.5rem 12px 20px",
@@ -210,7 +199,7 @@ export function PolicyPopup({
210
199
  borderRadius: "0.5rem",
211
200
  background: agreed ? "#111827" : "#e5e7eb",
212
201
  padding: "0.5rem 1rem",
213
- fontSize: "0.875rem",
202
+ fontSize: "1rem",
214
203
  fontWeight: 500,
215
204
  color: agreed ? "#fff" : "#9ca3af",
216
205
  border: "none",
@@ -223,7 +212,7 @@ export function PolicyPopup({
223
212
  {createUserConsent.isError && (
224
213
  <p
225
214
  className="consent:text-sm consent:text-red-600"
226
- style={{ fontSize: "0.875rem", color: "#dc2626", margin: 0 }}
215
+ style={{ fontSize: "1rem", color: "#dc2626", margin: 0 }}
227
216
  >
228
217
  Đã xảy ra lỗi. Vui lòng thử lại.
229
218
  </p>
@@ -266,7 +255,7 @@ export function PolicyPopup({
266
255
  <p
267
256
  className="consent:text-sm consent:text-gray-700"
268
257
  style={{
269
- fontSize: "0.875rem",
258
+ fontSize: "1rem",
270
259
  color: "#374151",
271
260
  margin: "0 0 1rem 0",
272
261
  lineHeight: 1.5,