Giao thức CLV1 đã công khaiĐọc đặc tả
Mục lục thư viện

Thư viện tài liệuPhát hành

Bản phát hành có ký và cập nhật

Bản phát hành giúp bạn đưa bản build mới tới đúng người đang có license: server băm và ký từng file, phần mềm nhận manifest có chữ ký cùng link tải ngắn hạn, còn bạn có trong tay các đòn bẩy để ép cập nhật, chặn bản lỗi, tạm dừng đăng nhập khi bảo trì và phát hiện bản build lạ.

11 phút đọc

Trước khi bắt đầu

  • Mọi thao tác nằm ở Phát hành & bản quyền › Bản phát hành của từng ứng dụng.
  • Chủ sở hữu và Quản trị được tạo, phát hành, chặn bản và đổi cài đặt phát hành. Thành viên chỉ xem và tải file về.
  • Dung lượng phát hành tính chung cho cả workspace, cộng mọi file của mọi ứng dụng. Mặc định Basic có 500 MB, Premium có 20.480 MB; con số áp cho workspace của bạn hiện ở Tài khoản & tổ chức › Gói & sử dụng và trên đồng hồ Dung lượng (MB) của trang. Bất kể gói nào, mỗi file tối đa 2 GB.

Tạo một bản phát hành

  1. Mở Phát hành & bản quyền › Bản phát hành và bấm Bản phát hành mới.
  2. Nhập Phiên bản theo dạng semver: ba số, có thể kèm nhãn pre-release, ví dụ 1.2.0 hoặc 1.3.0-beta.1. Không thêm tiền tố v.
  3. Chọn Kênh: stable (mặc định), beta, canary, cùng các kênh mà bản phát hành cũ đã dùng.
  4. Viết Ghi chú thay đổi (không bắt buộc, tối đa 20.000 ký tự). Ghi chú hiện trên thẻ bản phát hành và được gửi kèm manifest tới phần mềm.
  5. Kéo file vào ô Kéo file vào đây hoặc bấm để chọn, rồi kiểm tra Nền tảng của từng file.
  6. Bấm Lưu nháp để giữ lại xem trước, hoặc Phát hành để phát ngay.
Nền tảngDashboard tự đoán khi tên file
win-x64kết thúc bằng .exe, .msi, .msix
mac-arm64kết thúc bằng .dmg, hoặc chứa arm64 cùng mac/darwin
linux-x64kết thúc bằng .AppImage, .deb, .rpm, .tar.gz
anykhông khớp mẫu nào ở trên
win-arm64, mac-x64, linux-arm64không tự đoán, bạn chọn tay

Nếu nền tảng đoán được đã có file khác giữ, dashboard gán nền tảng còn trống đầu tiên, nên hãy xem lại ô chọn trước khi gửi.

Quy tắc cần nhớ:

  • Mỗi phiên bản chỉ xuất hiện một lần trên một kênh. Cùng số phiên bản ở hai kênh khác nhau thì được.
  • Mỗi nền tảng chỉ có một file trong một bản phát hành; hai file cùng nền tảng thì file tải sau thay file trước. Tên file tối đa 200 ký tự, không chứa / hay \. File rỗng bị từ chối.
  • Trong lúc file được tải lên, server tự tính sha256 và kích thước rồi ký bằng khoá của ứng dụng. Thẻ bản phát hành hiện nền tảng, tên file, kích thước và 10 ký tự đầu của sha256 kèm nút sao chép mã đầy đủ.

Khi hết dung lượng

Nếu dung lượng đã đầy, server trả plan_limit. Nếu file lớn hơn phần còn lại, việc tải lên dừng với too_large. Khi một file tải lỗi giữa chừng, bản nháp đã được tạo vẫn nằm trong danh sách với những file đã lên. Hãy bấm Xoá bản nháp rồi tạo lại, vì cùng phiên bản trên cùng kênh sẽ bị báo trùng cho tới khi bản nháp cũ được xoá.

Vòng đời: nháp, phát hành, chặn

Trạng tháiPhần mềm của kháchBạn làm được gì
Bản nhápKhông thấy, không tải đượcPhát hành (cần ít nhất một file), Xoá bản nháp
Đã phát hànhNhận qua checkUpdates() nếu là bản cao nhất của kênhChặn bản này
Đã chặnMáy chạy bản này bị từ chối đăng nhập, link tải ngừng chạyBỏ chặn
  • Danh sách trên trang xếp theo số phiên bản, cao nhất ở trên.
  • Nút Phát hành trên thẻ nháp bị mờ khi bản chưa có file. Nút Xoá bản nháp (biểu tượng thùng rác) xoá ngay, không hỏi lại.
  • Sau khi phát hành, file và kênh bị khoá.
  • "Bản mới nhất" của một kênh là bản đã phát hành có số phiên bản cao nhất, không phải bản phát hành gần đây nhất. Phát hành 1.1.5 sau 1.2.0 không làm 1.1.5 thành bản cập nhật.
  • Nhãn pre-release xếp thấp hơn bản chính thức cùng số: 1.3.0-beta.1 thấp hơn 1.3.0.

Chặn một bản lỗi

  1. Trên thẻ của bản đã phát hành, bấm Chặn bản này.
  2. Nhập lý do ở ô Vì sao chặn bản này (không bắt buộc, tối đa 300 ký tự), rồi xác nhận.

Từ lúc đó:

  • Máy báo appVersion trùng số phiên bản này, ở bất kỳ kênh nào, hoặc báo buildHash trùng sha256 của một file trong bản này, bị từ chối đăng nhập với mã build_blocked.
  • Bản bị loại khỏi manifest; checkUpdates() trả bản đã phát hành cao nhất còn lại của kênh.
  • Mọi link tải file của bản này trả 404, kể cả link vừa cấp.
  • Phiên đang mở không bị cắt. Lệnh chặn áp dụng ở lần đăng nhập tiếp theo.

Thẻ bản bị chặn có viền đỏ và hiện lý do. Bấm Bỏ chặn để đưa bản về Đã phát hành.

Seller API cũng liệt kê, phát hành và chặn bản phát hành với quyền releases:read và releases:write; việc tạo bản và tải file lên hiện chỉ làm trong dashboard. Xem tham chiếu Seller API.

Kênh phát hành

Danh sách kênh trong hộp thoại gồm stable, beta, canary và mọi kênh đã có bản phát hành. Kênh một license được nhận do gói license của nó quyết định. Mặc định mọi gói chỉ nhận stable, và dashboard chưa có chỗ đổi danh sách này. Khi phần mềm xin một kênh gói không cho phép, server trả kênh đầu tiên gói được nhận. Vì vậy hiện tại checkUpdates() luôn trả bản của kênh stable; bạn vẫn dùng được beta, canary để chuẩn bị và lưu bản thử nghiệm.

Phiên bản tối thiểu (ép cập nhật)

  1. Trong khung Phiên bản tối thiểu, tìm dòng của kênh.
  2. Nhập phiên bản, ví dụ 1.2.0, rồi bấm Đặt.
  3. Muốn bỏ mức tối thiểu, xoá trống ô rồi bấm Đặt.

Cách hoạt động:

  • Ở mỗi lần activate, trial, register và login, server so appVersion mà SDK gửi với mức tối thiểu của kênh stable. Bản thấp hơn bị từ chối với HTTP 426, mã update_required.
  • SDK không gửi appVersion thì bước này bị bỏ qua, nên luôn khai báo phiên bản trong build.
  • Mức tối thiểu của các kênh khác không chặn đăng nhập; nó đi kèm manifest của kênh đó trong trường minVersion để phần mềm tự xử lý.
  • Phiên đang mở chạy tiếp cho tới lần đăng nhập sau. Thay đổi có hiệu lực ngay, các máy chủ khác cập nhật trong vòng 30 giây.

Bảo trì và thông báo

  • Bật Chế độ bảo trì để từ chối mọi lượt đăng nhập mới với HTTP 503, mã maintenance. Ô Lời nhắn khi bảo trì (tối đa 300 ký tự, lưu khi bạn rời ô) là nội dung khách nhìn thấy. Phiên đang mở không bị cắt.
  • Thông báo trong app (tối đa 500 ký tự) là một dòng ngắn trả về trong app.notice khi phần mềm gọi init(). Đây cũng chính là ô Thông báo cho người dùng ở Tích hợp › Cài đặt ứng dụng.

Thứ tự kiểm tra lúc đăng nhập và cách hiển thị từng mã được trình bày trong Chế độ đăng nhập và dùng thử.

Phát hiện bản build lạ

Khi SDK gửi buildHash (sha256 của file đang chạy, 64 ký tự hex viết thường), server tìm hash đó trong các file bạn đã tải lên cho ứng dụng:

  • Trùng file của một bản Đã chặn: từ chối với build_blocked.
  • Trùng một file khác: cho qua.
  • Không trùng file nào, và ứng dụng đã có ít nhất một bản Đã phát hành: đây là build lạ. Server ghi sự kiện Bản build lạ lên Protect 24/7, cộng vào điểm rủi ro.

Ở Bảo vệ Advanced, bật Kiểm tra toàn vẹn build (nhóm Bảo vệ code) trong Bảo mật ứng dụng › Bảo vệ, tab Phương pháp rồi chọn chế độ:

  • Chỉ cảnh báo: đăng nhập vẫn qua, bạn theo dõi sự kiện trên Protect 24/7.
  • Chặn: đăng nhập bị từ chối với HTTP 403, mã unknown_build.

Phía phần mềm: SDK JavaScript

Khai báo phiên bản và hash

import { ClavisClient, ClavisError } from "@clavisauh/sdk";
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";

const APP_VERSION = "1.2.0";
// sha256 của chính file đang chạy, đúng file bạn đã tải lên bản phát hành
const buildHash = createHash("sha256").update(readFileSync(process.execPath)).digest("hex");

const clavis = new ClavisClient({
  baseUrl: "https://api.example.com",
  appId: "app_…",
  appPublicKey,
  device,
  appVersion: APP_VERSION,
  buildHash,
});

SDK gửi appVersion và buildHash cùng mỗi lượt đăng nhập; init() cũng gửi chúng.

init() lúc khởi động

const { app } = await clavis.init();
if (app.maintenance) return showMaintenance(app.maintenance.message);
if (app.update?.required) return showUpdateScreen(app.update.minVersion, app.downloadUrl);
if (app.update?.latest) showBanner(`Đã có bản ${app.update.latest}`);
if (app.notice) showNotice(app.notice);
TrườngÝ nghĩa
app.versionBản stable cao nhất đã phát hành; chưa có bản nào thì là Phiên bản hiện tại trong Cài đặt ứng dụng
app.minVersionPhiên bản tối thiểu của kênh stable, hoặc null
app.update{ required: true, reason, minVersion } khi bản đang chạy bị ép cập nhật (update_required) hoặc bị chặn theo số phiên bản (build_blocked); { required: false, latest } khi có bản stable mới hơn; ngược lại null
app.maintenance{ message } khi đang bảo trì, ngược lại null
app.notice, app.forceUpdate, app.downloadUrlCác giá trị bạn đặt trong dashboard

init() chỉ xét số phiên bản; kiểm tra buildHash diễn ra ở lúc đăng nhập.

checkUpdates(): manifest có ký

checkUpdates({ channel?, platform? }) cần một phiên đang sống (sau activate, login...), nếu không sẽ nhận session_required hoặc session_expired; license cũng phải còn dùng được. Kết quả là null khi kênh chưa có bản nào được phát hành. Khi truyền platform, manifest chỉ giữ file của nền tảng đó và file any.

SDK chỉ trả manifest khi chữ ký hợp lệ với một khoá ứng dụng mà build tin (theo kid, xem Khoá ký và xoay vòng khoá), đúng appId và còn hạn. Manifest có hạn 10 phút kể từ lúc cấp. Sai bất kỳ điều kiện nào, SDK ném ClavisVerificationError với mã invalid_manifest.

Manifest gồm app, channel, version, notes, publishedAt, minVersion, files (mỗi file có platform, fileName, sizeBytes, sha256, url), issuedAt, expiresAt và kid. Manifest luôn là bản cao nhất của kênh, kể cả khi bằng bản đang chạy, nên bạn tự so phiên bản.

download(): tải và kiểm sha256

const manifest = await clavis.checkUpdates({ platform: "win-x64" });
// isNewer là hàm so semver của bạn
if (manifest && isNewer(manifest.version, APP_VERSION)) {
  const file = manifest.files[0];
  try {
    const bytes = await clavis.download(file);
    await writeFile(join(tmpdir(), file.fileName), bytes);
  } catch (err) {
    if (err instanceof ClavisError) showError(err.code); // download_failed, checksum_mismatch
  }
}

download() tải cả file vào bộ nhớ, tính sha256 và so với manifest. Lệch một byte là checksum_mismatch; HTTP lỗi là download_failed kèm mã trạng thái.

Mỗi url trong manifest sống 5 phút và gắn với phiên đã xin nó.

Tình huốngHTTPMã
Link quá 5 phút410link_expired
Link bị sửa403invalid_link
Phiên đã đăng xuất, hết hạn hoặc bị thu hồi401session_expired
Bản đã bị chặn hoặc file không còn404not_found
  • Manifest còn hạn 10 phút nhưng link chỉ 5 phút. Nếu người dùng chần chừ, gọi lại checkUpdates() để lấy link mới.
  • Mỗi lượt tải thành công của phần mềm cộng vào "lượt tải" trên thẻ bản phát hành và ghi sự kiện release.download vào Bảo mật ứng dụng › Nhật ký hoạt động. Mỗi lần checkUpdates() trả về manifest, nhật ký ghi thêm release.check.
  • Nút Tải về trên dashboard cấp cho bạn một link 5 phút không gắn phiên và không tính vào lượt tải.

Ai đang chạy bản nào

Khung Phiên bản đang chạy gom các máy hoạt động trong 7 ngày qua theo phiên bản chúng báo, tối đa 6 dòng; máy không báo phiên bản nằm ở dòng "không rõ". Mỗi thẻ bản phát hành hiện thêm tỷ lệ máy "đang chạy" bản đó và số lượt tải. Đây là chỗ để quyết định khi nào nâng Phiên bản tối thiểu mà không bỏ rơi quá nhiều khách.

Liên quan

Bạn cần giúp gì?

Câu hỏi thường gặp

ClavisAUH là gì?

Dịch vụ bản quyền và xác thực cho phần mềm desktop: license key, khoá thiết bị, đăng nhập người dùng và phản hồi có chữ ký. Tất cả quản lý trên một dashboard

Vì sao kẻ crack không làm giả được server?

SDK chỉ tin câu trả lời ký bằng khoá bí mật của ứng dụng. Khoá đó không bao giờ rời server của chúng tôi, nên server giả không ký được và bị từ chối

Trong file chạy của tôi có gì?

Mã ứng dụng và khoá công khai. Không có bí mật nào, vì mỗi thiết bị tự tạo cặp khoá riêng ở lần chạy đầu

Có chạy được khi offline không?

Có. Mọi gói đều có token offline có chữ ký dùng được 7 ngày, ứng dụng tự kiểm tra tại máy. Premium cho bạn chọn bao lâu. License đã thu hồi vẫn có thể chạy offline trong khoảng đó, trừ khi Chế độ chỉ online đang bật

Hỗ trợ những ngôn ngữ nào?

Hiện có JavaScript và TypeScript. Tiếp theo là C++, C# và Python, cùng một giao thức công khai

Gói Basic có miễn phí thật không?

Có. Không giới hạn thời gian, không cần thẻ. Cần nhiều hơn thì lên Premium

Liên hệ