Security questionnaire (DRAFT)
From code and tests only. Nothing has run live; no penetration test; no certification. Yes 27 · Partial 29 · No 7 · Needs a person 1 (of 64).
Download all answers as a CSV (for your own questionnaire; same draft, same limits).
Data residency statement (where data is kept, backups, support hours; written by the operator, with a .txt download).
Access control
Does each user have a separate login?Mỗi người dùng có tài khoản đăng nhập riêng không?PartialEach person gets their own link (owner, manager, agent, read-only; head-office people get named read-only links). No passwords; a person with an email can get a new link or a 6-digit code by email. Mock mail only.Mỗi người có một liên kết riêng (chủ doanh nghiệp, quản lý, nhân viên hỗ trợ, chỉ xem; người ở trụ sở chính có liên kết chỉ xem mang tên riêng). Không dùng mật khẩu; người có địa chỉ email có thể nhận liên kết mới hoặc mã 6 chữ số qua email. Mới thử với thư giả lập.
functions/api/login/signin.js · functions/_lib/hq.js · tests/staff.test.mjs
Are roles and least privilege supported?Có hỗ trợ phân quyền theo vai trò và đặc quyền tối thiểu không?PartialFour roles on /d/ with a server-side gate per endpoint; a table test fails if an endpoint is not classed. No custom roles.Bốn vai trò trên /d/, mỗi điểm truy cập (endpoint) có một lớp chặn phía máy chủ; một bài kiểm thử dạng bảng sẽ báo lỗi nếu có endpoint chưa được phân loại. Không có vai trò tùy chỉnh.
tests/staff-coverage.test.mjs · tests/staff.test.mjs
Single sign-on (SAML/OIDC) and SCIM?Đăng nhập một lần (SAML/OIDC) và SCIM?NoNot built. Sign-in is by emailed team link or password only.Chưa xây dựng. Chỉ đăng nhập bằng liên kết nhóm gửi qua email hoặc bằng mật khẩu.
Multi-factor authentication?Xác thực nhiều yếu tố?NoNo MFA. Operator can sit behind Cloudflare Access (off unless configured).Không có MFA. Nhà vận hành có thể đặt sau Cloudflare Access (tắt nếu chưa cấu hình).
functions/_lib/access.js
Are links revocable and do they expire?Liên kết có thu hồi được và có hết hạn không?PartialOwner and team links: issue, revoke, expiry, rotate with notice; head-office links: expiry, stop one or all. Node-tested, never live.Liên kết của chủ doanh nghiệp và của nhóm: cấp, thu hồi, hết hạn, đổi mới có báo trước; liên kết trụ sở chính: hết hạn, dừng một hoặc tất cả. Đã kiểm thử bằng Node, chưa chạy thật.
functions/_lib/access.js · functions/_lib/hq.js · tests/hq.test.mjs
Brute-force protection on tokens?Có chống dò mã đoán liên kết (brute-force) không?PartialRate limits on wrong tries per IP for operator, owner, head-office and code sign-in.Giới hạn số lần thử sai theo từng IP cho đăng nhập của nhà vận hành, chủ doanh nghiệp, trụ sở chính và đăng nhập bằng mã.
functions/_lib/access.js · functions/_lib/hq.js · tests/signin.test.mjs
Tenant isolation
Is one customer's data isolated from another's?Dữ liệu của khách hàng này có được tách biệt với khách hàng khác không?PartialEvery row carries a tenant id; widget key plus origin check; cross-tenant tests attack every /d/ and /api/op endpoint. Application-level isolation in one shared database; not tested on a live system.Mỗi dòng dữ liệu đều mang mã khách hàng (tenant id); khóa tiện ích chat cộng với kiểm tra nguồn gốc (origin); các bài kiểm thử chéo khách hàng tấn công mọi endpoint /d/ và /api/op. Tách biệt ở mức ứng dụng trong một cơ sở dữ liệu dùng chung; chưa kiểm thử trên hệ thống chạy thật.
tests/crosstenant.test.mjs · tests/gates.test.mjs
Are customer secrets encrypted at rest?Bí mật của khách hàng có được mã hóa khi lưu trữ không?PartialPer-tenant tokens sealed with AES-GCM when MASTER_KEY is set; otherwise stored plain (must be set before real clients).Mã thông báo (token) của từng khách hàng được niêm phong bằng AES-GCM khi đã đặt MASTER_KEY; nếu chưa đặt thì lưu dạng thường (phải đặt trước khi có khách thật).
functions/_lib/crypto.js
Logging and audit
Is there an audit log of who changed what?Có nhật ký kiểm toán ghi ai đã thay đổi gì không?PartialOperator actions and /d/ changes with who, old and new values for settings, team links, leads, bookings; owner can read and download it; pruned after 180 days. Chat replies not logged.Thao tác của nhà vận hành và thay đổi trên /d/ được ghi lại gồm người thực hiện, giá trị cũ và mới của cài đặt, liên kết nhóm, khách tiềm năng (lead), đặt chỗ; chủ doanh nghiệp có thể xem và tải về; tự xóa sau 180 ngày. Các câu trả lời trong chat không được ghi vào nhật ký này.
functions/_lib/audit.js · tests/audit.test.mjs · tests/activity.test.mjs
Can the customer export their logs?Khách hàng có xuất được nhật ký của mình không?YesOwner downloads the activity log as CSV (formula-safe). Node-tested.Chủ doanh nghiệp tải nhật ký hoạt động dạng CSV (an toàn với công thức bảng tính). Đã kiểm thử bằng Node.
tests/activity.test.mjs
Privacy
Can personal data be exported and erased per person?Có xuất và xóa được dữ liệu cá nhân theo từng người không?YesPer-person export and erase, logged by counts only.Có xuất và xóa theo từng người; nhật ký chỉ ghi số lượng.
functions/_lib/privacy.js
Are retention periods defined?Thời hạn lưu giữ dữ liệu đã được xác định chưa?YesYes, in code. Leads 365 days and unanswered questions 90 days (the owner may set 30 to 1095), live chat lines 30, optional chat log 30, working counters 2, switched-off client 30 days then a person decides. Same list on /security/residency.html.Có, trong mã nguồn. Khách tiềm năng 365 ngày và câu hỏi chưa được trả lời 90 ngày (chủ doanh nghiệp có thể đặt từ 30 đến 1095), dòng chat trực tiếp 30, nhật ký chat tùy chọn 30, bộ đếm làm việc 2, khách hàng đã tắt 30 ngày rồi do một người quyết định. Cùng danh sách này có trên /security/residency.html.
functions/_lib/privacy.js · functions/_lib/offboard.js · tests/retention-page.test.mjs
What happens to data when a customer leaves?Dữ liệu sẽ ra sao khi khách hàng ngừng sử dụng?PartialAfter 30 days switched off the client is listed as due and the operator is mailed on Monday; nothing is deleted automatically. A person presses Export and delete, and a 24-hour fresh export is required first. Not a certified deletion process.Sau 30 ngày tắt, khách hàng được liệt kê là đến hạn và nhà vận hành nhận thư vào thứ Hai; không có gì bị xóa tự động. Một người bấm Xuất và xóa, và trước đó phải có bản xuất mới trong vòng 24 giờ. Đây không phải quy trình xóa dữ liệu đã được chứng nhận.
functions/_lib/offboard.js · tests/retention-page.test.mjs
Does visitor text go to a third-party AI?Nội dung khách truy cập có được gửi cho AI của bên thứ ba không?PartialOnly if the operator turns AI on for that tenant (ANTHROPIC_API_KEY and a tenant switch); phones and emails are masked first. Owner can switch the staff AI helper off.Chỉ khi nhà vận hành bật AI cho khách hàng đó (ANTHROPIC_API_KEY và một công tắc theo khách hàng); số điện thoại và email được che trước. Chủ doanh nghiệp có thể tắt trợ lý AI cho nhân viên.
functions/_lib/copilot.js
Which outside services receive customer data?Những dịch vụ bên ngoài nào nhận dữ liệu của khách hàng?PartialListed with what is sent and whether optional: Cloudflare (hosting, database), Anthropic (only when the owner turns the AI on), Zalo, Messenger, Resend, the company sign-in provider and VietQR. A test fails if the code calls a host the list does not name. Sub-processor contracts are not reviewed (a lawyer must).Có danh sách ghi rõ gửi những gì và có tùy chọn hay không: Cloudflare (lưu trữ, cơ sở dữ liệu), Anthropic (chỉ khi chủ doanh nghiệp bật AI), Zalo, Messenger, Resend, nhà cung cấp đăng nhập của công ty và VietQR. Một bài kiểm thử sẽ báo lỗi nếu mã gọi tới máy chủ không có tên trong danh sách. Hợp đồng với các bên xử lý phụ (sub-processor) chưa được rà soát (cần luật sư).
scripts/_residency.mjs · tests/retention-page.test.mjs
Are payment card numbers stored?Có lưu số thẻ thanh toán không?YesNo. Payments are bank transfer (VietQR) matched by amount and note.Không. Thanh toán bằng chuyển khoản ngân hàng (VietQR), đối chiếu theo số tiền và nội dung chuyển.
Application security
Is the widget protected against abuse?Tiện ích chat có được bảo vệ khỏi bị lạm dụng không?PartialOrigin allow-list, CORS, per-IP and per-tenant limits, link and long-message guard.Danh sách nguồn được phép (origin allow-list), CORS, giới hạn theo từng IP và từng khách hàng, chặn liên kết và tin nhắn quá dài.
tests/crosstenant-widget.test.mjs
Are secret links kept out of referrers and logs?Liên kết bí mật có được giữ khỏi referrer và nhật ký không?YesNo-referrer and noindex headers on /d/, /hq/, /op/; head-office page sends the token in a header, CSV built in the page.Tiêu đề no-referrer và noindex trên /d/, /hq/, /op/; trang trụ sở chính gửi mã trong tiêu đề (header), CSV được tạo ngay trong trang.
public/_headers · scripts/preflight.mjs
Has a penetration test been done?Đã thực hiện kiểm thử xâm nhập chưa?NoNone.Chưa.
Change management
Can a customer preview a settings change before it goes live?Khách hàng có xem trước được thay đổi cài đặt trước khi áp dụng thật không?PartialBot answers, never-answer topics, tone, FAQ, prices and opening hours can be previewed side by side; nothing is saved. No full staging copy.Câu trả lời của bot, chủ đề không được trả lời, giọng điệu, câu hỏi thường gặp (FAQ), giá và giờ mở cửa có thể xem trước song song; không có gì được lưu. Không có bản thử nghiệm đầy đủ (staging).
tests/preview.test.mjs
Is the AI tested before go-live?AI có được kiểm thử trước khi đưa vào hoạt động không?Partial"Test my bot" report with replay of past chats and an advisory ready verdict; mock model.Báo cáo "Test my bot" (kiểm tra bot của tôi) với phát lại các cuộc chat cũ và một kết luận "sẵn sàng" mang tính tham khảo; dùng mô hình giả lập.
tests/botreport.test.mjs
Availability
Is there an uptime SLA or status page?Có cam kết thời gian hoạt động (SLA) hoặc trang trạng thái không?NoNone offered; nothing has run live.Không cung cấp; chưa có gì chạy thật.
Are backups tested?Bản sao lưu có được kiểm thử không?NoNot tested.Chưa kiểm thử.
Is there an incident response tool?Có công cụ ứng phó sự cố không?PartialKill switch, key rotation, revoke all links for one tenant or all (operator).Công tắc ngắt khẩn cấp, đổi khóa, thu hồi tất cả liên kết của một khách hàng hoặc của tất cả (nhà vận hành).
docs/RUNBOOK.md
Governance
SOC 2 or ISO 27001?SOC 2 hoặc ISO 27001?NoNo certification; not planned until a buyer pays for it.Không có chứng nhận; chưa dự định cho đến khi có khách hàng trả tiền cho việc này.
Is data residency selectable?Có chọn được nơi lưu dữ liệu không?NoNo choice. Region of the database is unconfirmed: a person must confirm it with the host.Không có lựa chọn. Khu vực đặt cơ sở dữ liệu chưa được xác nhận: cần một người xác nhận với nhà cung cấp lưu trữ.
docs/SECURITY-OVERVIEW.md
DPA, privacy policy and terms?DPA, chính sách quyền riêng tư và điều khoản?Needs a personMechanisms exist; the text has not been reviewed by a lawyer (PDPD, GDPR).Đã có cơ chế; nội dung văn bản chưa được luật sư rà soát (PDPD, GDPR).
Access control
Can the customer see who has access and when it was last used?Khách hàng có xem được ai đang có quyền truy cập và lần dùng gần nhất không?YesThe owner's Team links list shows every person, role and when their link was last used (on now, minutes, days ago, or not used yet). The owner can stop any link alone. No automatic access review reminder.Danh sách Liên kết nhóm của chủ doanh nghiệp hiển thị từng người, vai trò và lần gần nhất liên kết của họ được dùng (đang dùng, vài phút, vài ngày trước, hoặc chưa dùng). Chủ doanh nghiệp có thể tự dừng bất kỳ liên kết nào. Không có nhắc nhở tự động để rà soát quyền truy cập.
functions/api/d/staff.js · functions/_lib/tenant.js · tests/seen.test.mjs
Logging
Does the audit log avoid storing personal contact data?Nhật ký kiểm toán có tránh lưu thông tin liên hệ cá nhân không?PartialAudit rows hold who, what kind of change and the tenant. Lead and privacy rows store lead numbers and counts only, never phone, email or message text, and secret-like setting names show as hidden. Visitor text elsewhere (chat lines) is kept for the periods in the retention answer.Dòng nhật ký ghi người thực hiện, loại thay đổi và khách hàng. Dòng của khách tiềm năng và quyền riêng tư chỉ lưu số thứ tự và số lượng, không bao giờ lưu số điện thoại, email hay nội dung tin nhắn, và tên các cài đặt dạng bí mật được hiển thị là đã ẩn. Nội dung khách truy cập ở nơi khác (dòng chat) được giữ theo các thời hạn trong câu trả lời về lưu giữ dữ liệu.
functions/_lib/audit.js · tests/audit.test.mjs · tests/leadaudit.test.mjs
Application security
Is untrusted text escaped on public pages?Văn bản không đáng tin cậy có được xử lý (escape) trên các trang công khai không?PartialThe public help center escapes every owner string, sends a content security policy and uses no script for the owner's text. Checked by a test with hostile sample text; the status page and other pages are not covered by this answer. No outside scanner or penetration test has been run.Trung tâm trợ giúp công khai escape mọi chuỗi do chủ doanh nghiệp nhập, gửi chính sách bảo mật nội dung (CSP) và không dùng script cho văn bản của chủ doanh nghiệp. Đã kiểm tra bằng một bài kiểm thử với văn bản mẫu độc hại; trang trạng thái và các trang khác không nằm trong câu trả lời này. Chưa chạy trình quét bên ngoài hay kiểm thử xâm nhập.
functions/_lib/helpcenter.js · tests/helpcenter.test.mjs · functions/api/help.js
Change management
Are there automated tests for access and tenant isolation?Có kiểm thử tự động cho quyền truy cập và việc tách biệt giữa các khách hàng không?PartialCross-tenant attack tests and a table that must name every /d/ endpoint with its role gate run in npm test; a new endpoint without a gate fails the build. Tests use mock data and in-memory SQLite, never real deployed services.Các bài kiểm thử tấn công giữa các khách hàng và một bảng bắt buộc phải nêu tên mọi endpoint của /d/ cùng lớp chặn theo vai trò được chạy trong npm test; endpoint mới không có lớp chặn sẽ làm bản dựng thất bại. Các bài kiểm thử dùng dữ liệu giả lập và SQLite trong bộ nhớ, không bao giờ dùng dịch vụ thật đã triển khai.
tests/crosstenant.test.mjs · tests/staff-coverage.test.mjs · tests/gates.test.mjs
Access control
Can a view-only person change anything?Người chỉ được xem có thay đổi được gì không?PartialNo. A view-only link is refused on every write by the server (GET only, and no access to the privacy, team and activity screens), and the write buttons are also hidden on the page (b785). Node tests with mock data; never run live.Không. Máy chủ từ chối mọi thao tác ghi từ liên kết chỉ xem (chỉ GET, và không vào được các màn hình quyền riêng tư, nhóm và hoạt động), đồng thời các nút ghi cũng bị ẩn trên trang (b785). Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/tenant.js · public/d/role.js · tests/staff.test.mjs
Can the operator cut off a client's team sign-in at once?Nhà vận hành có thể cắt đăng nhập của nhóm một khách hàng ngay lập tức không?PartialPer person only: the operator can revoke a team member's link from /op/. There is no one-click cut-off for a whole client. Mock data only; never run live.Chỉ theo từng người: nhà vận hành có thể thu hồi liên kết của một thành viên trong nhóm từ /op/. Chưa có nút cắt một lần cho cả một khách hàng. Chỉ dùng dữ liệu giả lập; chưa chạy thật.
functions/api/op/tenants.js
Privacy
Are chat ratings stored without visitor text or contact?Đánh giá chat có được lưu mà không kèm nội dung hay thông tin liên hệ của khách truy cập không?YesA rating is kept as per-day counts (how many, sum, stars 1 to 5) for 31 days, plus a one-per-chat marker so a chat cannot be rated twice. No visitor text is kept with it. A 1 or 2 sends the owner one alert, which may name a contact the visitor already left in that chat. Node tests with mock data.Đánh giá được lưu dưới dạng số đếm theo ngày (bao nhiêu lượt, tổng, số sao 1 đến 5) trong 31 ngày, cùng một dấu mỗi chat một lần để một chat không bị đánh giá hai lần. Không lưu nội dung nào của khách truy cập kèm theo. Đánh giá 1 hoặc 2 sao gửi cho chủ doanh nghiệp một cảnh báo, có thể nêu thông tin liên hệ mà khách truy cập đã để lại trong chat đó. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/rating.js · tests/csat-prev.test.mjs
Access control
Can head-office access be limited to one group and stopped per person?Quyền truy cập của trụ sở chính có thể giới hạn trong một nhóm và dừng theo từng người không?PartialEach head-office person has their own named read link for ONE group, with an expiry and a last-used time; the operator can stop one person or all of them. A link sees only that group's locations. Node tests with mock data; never run live.Mỗi người ở trụ sở chính có một liên kết xem riêng mang tên họ, chỉ cho MỘT nhóm (ONE group), có ngày hết hạn và thời điểm dùng gần nhất; nhà vận hành có thể dừng một người hoặc tất cả. Một liên kết chỉ thấy các điểm kinh doanh của nhóm đó. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/hq.js · functions/api/hq/report.js · tests/hq.test.mjs · tests/hq-signin.test.mjs
Is the head-office view read-only?Màn hình của trụ sở chính có chỉ để xem không?PartialYes except one setting: a head-office person can set or clear their own group's first-reply standard (a yardstick, nothing is blocked or sent), and that change is written to the audit log with the person's link name. Counts only; no chat text. Node tests with mock data.Có, trừ một thiết lập: người ở trụ sở chính có thể đặt hoặc xóa chuẩn thời gian trả lời đầu tiên của nhóm mình (chỉ là thước đo, không chặn hay gửi gì), và thay đổi đó được ghi vào nhật ký kiểm toán kèm tên liên kết của người đó. Chỉ có số đếm; không có nội dung chat. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/api/hq/report.js · tests/hq.test.mjs · tests/hq-rating.test.mjs
Change management
Does the Test my bot screen change or send anything?Màn hình Test my bot có thay đổi hay gửi gì không?YesNo. It runs the real answer engine in a sandbox on the customer's own facts: nothing is saved, nothing is sent to a visitor, and no AI model is called. It is limited per hour and refused for view-only links. Node tests with mock data.Không. Màn hình này chạy bộ máy trả lời thật trong môi trường thử (sandbox) trên chính thông tin của khách hàng: không lưu gì, không gửi gì cho khách truy cập, và không gọi mô hình AI nào. Có giới hạn số lần mỗi giờ và bị từ chối với liên kết chỉ xem. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/botreport.js · functions/api/d/botreport.js · tests/botreport.test.mjs
Application security
Is the head-office token kept out of web addresses?Mã (token) của trụ sở chính có được giữ ngoài địa chỉ web không?YesThe /hq/ page sends the token in a request header, not in the address of a data request, and builds its CSV in the page so no download address carries it. A link the operator mails does carry the token once, to open the page. Node tests with mock data.Trang /hq/ gửi mã trong tiêu đề (header) của yêu cầu, không đặt trong địa chỉ của yêu cầu dữ liệu, và tạo CSV ngay trong trang nên không có địa chỉ tải xuống nào mang mã. Liên kết do nhà vận hành gửi qua thư thì có mang mã một lần, để mở trang. Đã kiểm thử bằng Node với dữ liệu giả lập.
public/hq/hq.js · functions/api/hq/report.js · tests/hqasked.test.mjs
Change management
Can the bot be held back until it has passed a test?Có thể giữ bot lại cho đến khi nó vượt qua một bài kiểm tra không?PartialThe owner can switch on a go-live hold: the bot gives no automatic answers (every line goes to a person) until the last Test my bot run says Ready and the settings are unchanged since. Off by default; it is the owner's own switch, not a vendor-enforced release gate. Node tests with mock data, never live.Chủ doanh nghiệp có thể bật chế độ giữ trước khi chạy thật (go-live hold): bot không tự động trả lời (mọi dòng đều chuyển cho một người) cho đến khi lần chạy Test my bot gần nhất báo Ready và các thiết lập không đổi kể từ đó. Mặc định tắt; đây là công tắc riêng của chủ doanh nghiệp, không phải cổng phát hành do nhà cung cấp bắt buộc. Đã kiểm thử bằng Node với dữ liệu giả lập, chưa chạy thật.
functions/_lib/botreport.js · tests/botreport.test.mjs
Privacy
Does the Inbox urgency ranking store or send visitor text?Việc xếp hạng độ khẩn cấp trong Inbox có lưu hoặc gửi nội dung của khách truy cập không?YesThe ranking is plain rules computed when the list is opened: no model, nothing stored, and the visitor's words are dropped before the list leaves the server; only fixed reason words (for example "waiting 15 minutes or more") are shown. A reminder to the owner may quote up to 160 characters of the visitor's last line on the owner's own alert channels. Node tests with mock data.Việc xếp hạng chỉ dùng các quy tắc đơn giản, tính khi danh sách được mở: không dùng mô hình, không lưu gì, và lời của khách truy cập bị bỏ đi trước khi danh sách rời máy chủ; chỉ hiện các từ lý do cố định (ví dụ "chờ 15 phút trở lên"). Một lời nhắc gửi chủ doanh nghiệp có thể trích tối đa 160 ký tự của dòng cuối cùng của khách truy cập, trên các kênh cảnh báo riêng của chủ doanh nghiệp. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/live.js · tests/urgency.test.mjs
Access control
Who can change a brand's look, greeting and chat button text?Ai có thể thay đổi giao diện, lời chào và chữ trên nút chat của một thương hiệu?YesOnly the platform operator, through the operator action brand_look behind the operator token. An owner or a head-office link cannot set it. Locations of other groups and other brands are not touched; the settings sit under one key per group and brand. Node tests with mock data.Chỉ nhà vận hành nền tảng, thông qua thao tác brand_look của nhà vận hành đặt sau mã của nhà vận hành. Liên kết của chủ doanh nghiệp hoặc của trụ sở chính không đặt được. Các điểm kinh doanh của nhóm khác và thương hiệu khác không bị đụng tới; các thiết lập nằm dưới một khóa riêng cho mỗi nhóm và thương hiệu. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/api/op/tenants.js · functions/_lib/hq.js · tests/brand-greeting.test.mjs
Privacy
Is the note in a visitor's own language written without a model call?Ghi chú bằng ngôn ngữ của khách truy cập có được viết mà không gọi mô hình không?YesYes. When a visitor writes in another language, the hand-off note is a fixed sentence picked by two marker words, so the visitor's line is not sent to a model for it. The wording of the Dutch, Turkish and Polish notes has not been checked by a native speaker. Node tests with mock data.Có. Khi khách truy cập viết bằng ngôn ngữ khác, ghi chú chuyển cho người là một câu cố định, chọn theo hai từ nhận diện, nên dòng của khách truy cập không bị gửi đến mô hình cho việc này. Lời của các ghi chú tiếng Hà Lan, tiếng Thổ Nhĩ Kỳ và tiếng Ba Lan chưa được người bản ngữ kiểm tra. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/engine.js · tests/dutch.test.mjs
Is visitor text kept out of the head-office CSV?Nội dung của khách truy cập có được giữ ngoài tệp CSV của trụ sở chính không?YesThe /hq/ CSV is built in the page from numbers already loaded: location, day, counts, reply times, rating count and average, brand, group standard. It holds no visitor line, name or contact. Node tests with mock data.Tệp CSV của /hq/ được tạo ngay trong trang từ các con số đã tải sẵn: điểm kinh doanh, ngày, số đếm, thời gian trả lời, số lượt và điểm trung bình của đánh giá, thương hiệu, chuẩn của nhóm. Không có dòng chat, tên hay thông tin liên hệ của khách truy cập. Đã kiểm thử bằng Node với dữ liệu giả lập.
public/hq/hq.js · tests/hqasked.test.mjs
Application security
Are the brand texts shown on the visitor widget cleaned first?Chữ thương hiệu hiện trên khung chat của khách truy cập có được làm sạch trước không?YesA brand's title, bot name, greeting, chat button text and welcome-back line lose angle brackets and control characters and are length-limited (2 to 200 characters) before they are saved and again before they are sent to the widget. Node tests with mock data.Tiêu đề, tên bot, lời chào, chữ trên nút chat và dòng chào mừng trở lại của một thương hiệu bị bỏ dấu ngoặc nhọn và ký tự điều khiển, đồng thời bị giới hạn độ dài (2 đến 200 ký tự), trước khi được lưu và một lần nữa trước khi gửi đến khung chat. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/hq.js · functions/api/w/config.js · tests/brand-back.test.mjs
Do the owner's never-answer words ever reach an AI model?Những từ cấm trả lời của chủ doanh nghiệp có bao giờ đến được mô hình AI không?YesThe owner's never-answer words are only matched against the visitor's line on the server. They are never put into a prompt, and a matching line gets one fixed polite line with no FAQ, quote or AI call. The tone setting is chosen from a fixed table, never owner free text. Node tests with a mock model.Các từ cấm trả lời của chủ doanh nghiệp chỉ được đối chiếu với dòng của khách truy cập trên máy chủ. Chúng không bao giờ được đưa vào prompt, và một dòng khớp chỉ nhận một câu lịch sự cố định, không có FAQ, báo giá hay lệnh gọi AI. Thiết lập giọng điệu được chọn từ một bảng cố định, không bao giờ từ văn bản tự do của chủ doanh nghiệp. Đã kiểm thử bằng Node với mô hình giả lập.
functions/_lib/guard.js · tests/guard.test.mjs
Privacy
Is the public help center built only from the owner's own text?Trang trung tâm trợ giúp công khai có chỉ được tạo từ văn bản của chính chủ doanh nghiệp không?YesThe help center page is generated only from that owner's own FAQ and services: no AI, no other client's data. It is off unless the owner switched it on, every owner string is escaped and the page runs no script. Node tests with mock data; never run live.Trang trung tâm trợ giúp chỉ được tạo từ FAQ và dịch vụ của chính chủ doanh nghiệp đó: không có AI, không có dữ liệu của khách hàng khác. Trang tắt trừ khi chủ doanh nghiệp bật lên, mọi chuỗi văn bản của chủ doanh nghiệp đều được escape và trang không chạy script nào. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/helpcenter.js · functions/api/help.js · tests/helpcenter.test.mjs
Does the chat quality score read or keep visitor text?Điểm chất lượng cuộc trò chuyện có đọc hoặc lưu văn bản của khách truy cập không?YesNo. The score uses only who wrote, when, and the bot's short source label (never the text). The report returns a score, short reason words and a chat tag, and no model is involved. Node tests with mock data check that a planted secret never appears.Không. Điểm chỉ dùng ai là người viết, viết khi nào và nhãn nguồn ngắn của bot (không bao giờ dùng văn bản). Báo cáo trả về một điểm, vài từ lý do ngắn và một thẻ cuộc trò chuyện, và không có mô hình nào tham gia. Các bài kiểm thử Node với dữ liệu giả lập xác nhận rằng một bí mật được cài sẵn không bao giờ xuất hiện.
functions/_lib/qa.js · tests/qa-bot.test.mjs
Application security
Are topics the owner blocked kept off the public help page?Các chủ đề chủ doanh nghiệp đã chặn có được giữ ngoài trang trợ giúp công khai không?YesA FAQ item or service that matches one of the owner's never-answer topics is left off the public help page, and the numbered links of the other answers do not change. Node tests with mock data; never run live.Một mục FAQ hoặc dịch vụ khớp với một trong các chủ đề cấm trả lời của chủ doanh nghiệp sẽ không được đưa lên trang trợ giúp công khai, và các liên kết đánh số của những câu trả lời khác không thay đổi. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/helpcenter.js · tests/help-guard.test.mjs · tests/help-stable.test.mjs
Are urgent chats ranked by a model?Các cuộc trò chuyện khẩn có được xếp hạng bằng mô hình không?YesNo. The Inbox urgency ranking uses plain rules (waiting time, an unhappy-visitor flag, a fixed list of urgent words and the owner's own words); no model is called and the reason shown holds none of the visitor's words. Node tests with mock data.Không. Bảng xếp hạng độ khẩn trong Inbox dùng các quy tắc đơn giản (thời gian chờ, cờ khách truy cập không hài lòng, một danh sách cố định các từ khẩn và các từ riêng của chủ doanh nghiệp); không có mô hình nào được gọi và lý do hiển thị không chứa từ nào của khách truy cập. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/live.js · tests/urgency.test.mjs
Privacy
Is an empty public help page kept out of search engines?Trang trợ giúp trống có được giữ ngoài công cụ tìm kiếm không?YesA help page with no FAQ items and no services asks search engines not to index it. Pages with content are indexable only when the owner switched the help center on; otherwise the page does not exist. Node tests with mock data; never run live.Một trang trợ giúp không có mục FAQ và không có dịch vụ sẽ yêu cầu công cụ tìm kiếm không lập chỉ mục. Các trang có nội dung chỉ được lập chỉ mục khi chủ doanh nghiệp đã bật trung tâm trợ giúp; nếu không thì trang không tồn tại. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/helpcenter.js · tests/help-empty.test.mjs
Application security
Are the owner's word lists cleaned and limited?Danh sách từ của chủ doanh nghiệp có được làm sạch và giới hạn không?YesThe owner's never-answer and urgent words lose angle brackets and control characters, must be 3 to 40 characters, repeats are dropped, and at most 10 are kept. They are only matched against the visitor's line, never run as code or sent to a model. Node tests with mock data.Các từ cấm trả lời và từ khẩn của chủ doanh nghiệp bị loại dấu ngoặc nhọn và ký tự điều khiển, phải dài từ 3 đến 40 ký tự, từ lặp bị bỏ và tối đa 10 từ được giữ lại. Chúng chỉ được đối chiếu với dòng của khách truy cập, không bao giờ chạy như mã hay gửi cho mô hình. Đã kiểm thử bằng Node với dữ liệu giả lập.
functions/_lib/guard.js · tests/help-empty.test.mjs · tests/guard.test.mjs
Can the bot offer a quick question or suggestion on a blocked topic?Bot có thể gợi ý một câu hỏi nhanh hoặc đề xuất về chủ đề bị chặn không?YesNo. Quick-question buttons and "did you mean" suggestions skip anything that matches the owner's never-answer topics, so the bot does not offer what it would then refuse. Node tests with mock data; never run live.Không. Các nút câu hỏi nhanh và gợi ý "ý bạn là" bỏ qua mọi thứ khớp với chủ đề cấm trả lời của chủ doanh nghiệp, nên bot không đề nghị điều mà sau đó nó sẽ từ chối. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/api/w/config.js · functions/_lib/engine.js · tests/guard-offers.test.mjs
Can the AI fallback see text the owner blocked?AI dự phòng có thể thấy văn bản mà chủ doanh nghiệp đã chặn không?YesNo. Before the facts are given to the model, every service and FAQ answer that touches one of the owner's never-answer topics is removed, so a visitor who words a question differently cannot get a blocked answer back. Node tests with a mock model; never run live.Không. Trước khi các thông tin được đưa cho mô hình, mọi câu trả lời dịch vụ và FAQ liên quan đến một chủ đề cấm trả lời của chủ doanh nghiệp đều bị loại bỏ, nên khách truy cập diễn đạt câu hỏi theo cách khác cũng không thể nhận lại câu trả lời bị chặn. Đã kiểm thử bằng Node với mô hình giả lập; chưa chạy thật.
functions/_lib/ai.js · tests/guard-facts.test.mjs
Can a blocked FAQ answer be sent or offered as a follow-up?Một câu trả lời FAQ bị chặn có thể được gửi đi hoặc gợi ý như câu hỏi tiếp theo không?YesNo. An FAQ answer that touches an owner never-answer topic is not sent even when the visitor words the question without the blocked word, and follow-up buttons never offer it. Node tests with mock data; never run live.Không. Một câu trả lời FAQ liên quan đến chủ đề cấm trả lời của chủ doanh nghiệp sẽ không được gửi, ngay cả khi khách truy cập diễn đạt câu hỏi mà không dùng từ bị chặn, và các nút câu hỏi tiếp theo không bao giờ đề nghị nó. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/engine.js · tests/guard-followups.test.mjs · tests/guard-faq.test.mjs
Can a blocked service or offer be reached with other words?Có thể truy cập một dịch vụ hoặc ưu đãi bị chặn bằng những từ khác không?YesNo. A service or cross-sell offer whose own text touches an owner never-answer topic is taken out of that chat's facts before any step runs (price, quote, menu, offer line), and the first-buttons list and the Test my bot probes skip it too. Node tests with mock data; never run live.Không. Một dịch vụ hoặc ưu đãi bán kèm mà chính văn bản của nó liên quan đến chủ đề cấm trả lời của chủ doanh nghiệp sẽ bị lấy ra khỏi thông tin của cuộc trò chuyện đó trước khi bất kỳ bước nào chạy (giá, báo giá, thực đơn, dòng ưu đãi), và danh sách nút đầu tiên cũng như các câu thăm dò của Test my bot cũng bỏ qua nó. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy thật.
functions/_lib/engine.js · functions/api/w/config.js · functions/_lib/botreport.js · tests/guard-services.test.mjs
Privacy
Are the visitor's own words ever used to build a blocked answer?Lời của chính khách truy cập có bao giờ được dùng để dựng nên một câu trả lời bị chặn không?YesNo. Blocking is checked on the owner's own text (services, FAQ, offers) and on the visitor's line, with the same plain word match and no model; a blocked item is not sent, suggested, listed or given to the AI fallback. Node tests with mock data and a mock model.Không. Việc chặn được kiểm tra trên văn bản của chính chủ doanh nghiệp (dịch vụ, FAQ, ưu đãi) và trên dòng của khách truy cập, bằng cùng một cách đối chiếu từ đơn giản và không có mô hình; một mục bị chặn sẽ không được gửi, gợi ý, liệt kê hay đưa cho AI dự phòng. Đã kiểm thử bằng Node với dữ liệu giả lập và mô hình giả lập.
functions/_lib/guard.js · tests/guard-faq.test.mjs · tests/guard-facts.test.mjs · tests/guard-services.test.mjs
Application security
Do all chat channels apply the owner's blocked topics?Tất cả các kênh chat có áp dụng chủ đề bị chặn của chủ doanh nghiệp không?YesThe website chat, Zalo, WhatsApp and Messenger inbound all call the same bot engine, where the blocked-topic step runs before any answer, quote or AI call. Checked in code; the Node test covers the engine with mock data, not each channel's own webhook; never run live.Chat trên website, tin nhắn đến từ Zalo, WhatsApp và Messenger đều gọi cùng một bộ máy bot, nơi bước chủ đề bị chặn chạy trước mọi câu trả lời, báo giá hay lệnh gọi AI. Đã kiểm tra trong mã; bài kiểm thử Node bao phủ bộ máy với dữ liệu giả lập, không bao phủ webhook riêng của từng kênh; chưa chạy thật.
functions/_lib/engine.js · functions/api/w/chat.js · functions/api/zalo/inbound.js · functions/api/wa/inbound.js · functions/api/fb/inbound.js · tests/guard.test.mjs
Does Test my bot check every blocked topic and the legal-advice refusal?Test my bot có kiểm tra mọi chủ đề bị chặn và việc từ chối tư vấn pháp lý không?PartialTest my bot now asks about each of the owner's blocked topics (up to 10) and about a medical, a legal and a weather question, and fails any that the bot answers from the facts. Node tests with mock data; never run on a real tenant's facts.Test my bot giờ hỏi về từng chủ đề bị chặn của chủ doanh nghiệp (tối đa 10) và về một câu hỏi y tế, một câu hỏi pháp lý và một câu hỏi thời tiết, rồi đánh dấu thất bại với bất kỳ câu nào mà bot trả lời từ các thông tin có sẵn. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy trên thông tin của khách hàng thật.
functions/_lib/botreport.js · tests/botreport.test.mjs
Access control
How are team passwords stored, and what happens after wrong tries?Mật khẩu của nhóm được lưu như thế nào và điều gì xảy ra sau khi nhập sai?PartialA team member with an email on their link may set a password. It is stored only as a PBKDF2-SHA256 hash with a random salt (100000 rounds), never as text. Every failed sign-in looks the same (unknown address, no password, wrong password, ended link). Five wrong tries lock that address for 15 minutes and 20 tries an hour lock the IP. The owner can see who has a password and remove it, never read it. Node tests with mock data; never run on a real tenant.Một thành viên nhóm có email trên liên kết của mình có thể đặt mật khẩu. Mật khẩu chỉ được lưu dưới dạng băm PBKDF2-SHA256 với salt ngẫu nhiên (100000 vòng), không bao giờ lưu dưới dạng văn bản. Mọi lần đăng nhập thất bại đều trông giống nhau (địa chỉ không tồn tại, chưa có mật khẩu, sai mật khẩu, liên kết đã hết hạn). Năm lần nhập sai sẽ khóa địa chỉ đó trong 15 phút và 20 lần trong một giờ sẽ khóa IP. Chủ doanh nghiệp có thể thấy ai đã có mật khẩu và xóa nó, nhưng không bao giờ đọc được. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy trên khách hàng thật.
functions/_lib/staffpw.js · functions/api/login/password.js · tests/staffpw.test.mjs
Can a head-office link be view-only?Liên kết của trụ sở chính có thể chỉ xem không?PartialA head-office link is a viewer (looks only) or a manager (may also set the group first-reply standard). A viewer's change is refused with 403, and the page hides the editor. A link made before roles existed counts as manager. Head office never changes a location's own settings. Node tests with mock data; never run on a real tenant.Một liên kết của trụ sở chính là người xem (chỉ xem) hoặc quản lý (còn được đặt tiêu chuẩn trả lời đầu tiên của nhóm). Thay đổi của người xem bị từ chối với mã 403, và trang ẩn phần chỉnh sửa. Một liên kết tạo trước khi có vai trò được tính là quản lý. Trụ sở chính không bao giờ thay đổi thiết lập riêng của một chi nhánh. Đã kiểm thử bằng Node với dữ liệu giả lập; chưa chạy trên khách hàng thật.
functions/_lib/hq.js · functions/api/hq/report.js · tests/hq-role.test.mjs
Privacy
How are the email addresses of people who follow incident updates handled?Địa chỉ email của những người theo dõi cập nhật sự cố được xử lý như thế nào?PartialAn address is used only to mail ZappBot incident updates. Nothing is sent until the person presses a confirm link; every mail has a stop link that deletes the address. The list holds at most 500 addresses, asking is limited to 5 times an hour per IP, and the operator screen shows counts only, never addresses. No tenant or visitor data is in these mails. Mock mail in Node tests; never run live.Địa chỉ chỉ được dùng để gửi email cập nhật sự cố của ZappBot. Không có gì được gửi cho đến khi người đó bấm liên kết xác nhận; mỗi email đều có liên kết dừng nhận để xóa địa chỉ. Danh sách chứa tối đa 500 địa chỉ, việc đăng ký bị giới hạn 5 lần mỗi giờ cho mỗi IP, và màn hình nhà vận hành chỉ hiển thị số lượng, không bao giờ hiển thị địa chỉ. Không có dữ liệu của khách hàng hay khách truy cập trong các email này. Email giả lập trong các bài kiểm thử Node; chưa chạy thật.
functions/_lib/statussub.js · functions/api/status/sub.js · tests/statussub.test.mjs
Access control
How does self-serve sign-up stop bots and mail abuse?Đăng ký tự phục vụ chặn bot và lạm dụng email như thế nào?PartialA new account needs a 6-digit code mailed to the address, or the one-tap link in the same mail (it works once and lasts 30 minutes; opening it only shows a button, so mail scanners cannot use it up). The code is stored only as a hash, works once, lasts 10 minutes and allows 5 tries. The reply is the same whether or not the address already has an account; a known address gets a one-tap sign-in link (30 minutes, one use) instead of a code. Limits: 10 requests per IP per hour, 1 mail per address per 10 minutes, 300 sign-up mails a day for the whole site, 30 code checks per IP per hour, and a hidden form field that a person never fills. One account per address. Node tests with mock mail and a mock database; never run live.Tài khoản mới cần một mã 6 chữ số gửi đến địa chỉ email, hoặc đường link bấm một lần trong cùng email (dùng được một lần, có hiệu lực 30 phút; mở link chỉ hiện một nút bấm nên công cụ quét email không thể dùng hết link). Mã chỉ được lưu dưới dạng băm, dùng được một lần, có hiệu lực 10 phút và cho phép thử 5 lần. Câu trả lời giống nhau dù địa chỉ đã có tài khoản hay chưa; địa chỉ đã có sẽ nhận một link đăng nhập bấm một lần (30 phút) thay vì mã. Giới hạn: 10 yêu cầu mỗi IP mỗi giờ, 1 email mỗi địa chỉ mỗi 10 phút, 300 email đăng ký mỗi ngày cho cả trang, 30 lần kiểm tra mã mỗi IP mỗi giờ, và một ô ẩn mà người thật không bao giờ điền. Mỗi địa chỉ chỉ một tài khoản. Kiểm thử Node với email và cơ sở dữ liệu giả lập; chưa chạy thật.
functions/api/login/signup.js · tests/signup-b956.test.mjs · tests/signup-b957.test.mjs
What does a self-serve sign-up create, and can it be switched off?Đăng ký tự phục vụ tạo ra gì, và có thể tắt được không?PartialA correct code creates one 14-day trial account, adds that person as its admin, and writes a line in the Activity log. The dashboard link is returned once in the reply. No card or payment details are asked for. The operator can close both sign-up steps at once with the setting SIGNUP_OFF=1 (the page then says sign-up is not open yet). Node tests with a mock database; never run on a real tenant.Mã đúng sẽ tạo một tài khoản dùng thử 14 ngày, thêm người đó làm quản trị viên và ghi một dòng vào nhật ký hoạt động. Liên kết bảng điều khiển chỉ được trả về một lần trong phản hồi. Không yêu cầu thẻ hay thông tin thanh toán. Nhà vận hành có thể đóng cả hai bước đăng ký cùng lúc bằng cài đặt SIGNUP_OFF=1 (trang sẽ báo đăng ký chưa mở). Kiểm thử Node với cơ sở dữ liệu giả lập; chưa chạy trên khách hàng thật.
functions/api/login/signup.js · tests/signup-b957.test.mjs
Can the owner change a team member's role or extend their link, and is it recorded?Chủ doanh nghiệp có thể đổi vai trò hoặc gia hạn liên kết của một thành viên không, và có được ghi lại không?PartialYes, from the owner link only. The owner changes one person's role (admin, manager, agent or read-only) or sets the end date to 1 to 365 days from now, on the same link, so no new link is handed out. A role change applies on the next request, because the role is read from the database each time. A stopped or ended link cannot be edited or revived. Each change writes a line in the Activity log with the name and the role or end date only, never the link or the email. Node tests with a mock database; never run on a real tenant.Có, chỉ từ liên kết của chủ doanh nghiệp. Chủ có thể đổi vai trò của một người (quản trị viên, quản lý, nhân viên trực chat hoặc chỉ xem) hoặc đặt ngày hết hạn từ 1 đến 365 ngày kể từ hôm nay, trên cùng một liên kết nên không phải gửi liên kết mới. Đổi vai trò có hiệu lực ngay ở yêu cầu kế tiếp, vì vai trò được đọc từ cơ sở dữ liệu mỗi lần. Liên kết đã dừng hoặc đã hết hạn không thể sửa hay khôi phục. Mỗi thay đổi ghi một dòng vào nhật ký hoạt động, chỉ gồm tên và vai trò hoặc ngày hết hạn, không bao giờ có liên kết hay email. Kiểm thử Node với cơ sở dữ liệu giả lập; chưa chạy trên khách hàng thật.
functions/api/d/staff.js · tests/staff-edit-b963.test.mjs