Merge pull request 'feat(licenses): plaintext key storage with copy buttons' (#342) from dev into main
Deploy MokoGitea / deploy (push) Failing after 3m35s
Deploy MokoGitea / deploy (push) Failing after 3m35s
This commit was merged in pull request #342.
This commit is contained in:
@@ -24,7 +24,8 @@ type LicenseKey struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
PackageID int64 `xorm:"INDEX NOT NULL"` // FK to license_package
|
||||
OwnerID int64 `xorm:"INDEX NOT NULL"` // org or user that issued it
|
||||
KeyHash string `xorm:"UNIQUE NOT NULL"` // SHA-256 of the raw key
|
||||
KeyHash string `xorm:"UNIQUE NOT NULL"` // SHA-256 of the raw key (for fast lookup)
|
||||
KeyRaw string `xorm:"TEXT"` // plaintext key (viewable by admins)
|
||||
KeyPrefix string `xorm:"NOT NULL"` // first 8 chars for display
|
||||
LicenseeName string `xorm:""` // customer name
|
||||
LicenseeEmail string `xorm:""` // customer email
|
||||
@@ -60,8 +61,7 @@ func HashKey(rawKey string) string {
|
||||
return hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
// CreateLicenseKey generates a new key, hashes it, stores it, and returns the raw key.
|
||||
// The raw key is only available at creation time.
|
||||
// CreateLicenseKey generates a new key, stores it in plaintext and hashed, and returns the raw key.
|
||||
func CreateLicenseKey(ctx context.Context, key *LicenseKey) (rawKey string, err error) {
|
||||
rawKey, err = GenerateKeyString()
|
||||
if err != nil {
|
||||
@@ -69,6 +69,7 @@ func CreateLicenseKey(ctx context.Context, key *LicenseKey) (rawKey string, err
|
||||
}
|
||||
|
||||
key.KeyHash = HashKey(rawKey)
|
||||
key.KeyRaw = rawKey
|
||||
key.KeyPrefix = rawKey[:12] + "..."
|
||||
|
||||
if _, err := db.GetEngine(ctx).Insert(key); err != nil {
|
||||
@@ -78,9 +79,9 @@ func CreateLicenseKey(ctx context.Context, key *LicenseKey) (rawKey string, err
|
||||
}
|
||||
|
||||
// CreateLicenseKeyCustom stores a key with a user-provided raw key string.
|
||||
// The raw key is hashed and stored — it will not be recoverable after this.
|
||||
func CreateLicenseKeyCustom(ctx context.Context, key *LicenseKey, rawKey string) error {
|
||||
key.KeyHash = HashKey(rawKey)
|
||||
key.KeyRaw = rawKey
|
||||
if len(rawKey) > 12 {
|
||||
key.KeyPrefix = rawKey[:12] + "..."
|
||||
} else {
|
||||
|
||||
@@ -2650,7 +2650,7 @@
|
||||
"repo.licenses.package_created": "License package created successfully.",
|
||||
"repo.licenses.generate_key": "Generate Key",
|
||||
"repo.licenses.key_created": "License Key Created",
|
||||
"repo.licenses.key_created_copy": "This key is hashed before storage and cannot be retrieved later. Copy and store it securely now.",
|
||||
"repo.licenses.key_created_copy": "Your new license key is shown below. You can also view and copy it from the keys table at any time.",
|
||||
"repo.licenses.revoke": "Revoke",
|
||||
"repo.licenses.edit_package": "Edit License Package",
|
||||
"repo.licenses.delete_package": "Delete Package",
|
||||
|
||||
@@ -150,7 +150,13 @@
|
||||
<tbody>
|
||||
{{range .LicenseKeys}}
|
||||
<tr>
|
||||
<td><code>{{.KeyPrefix}}</code>{{if .IsInternal}} <span class="ui tiny orange label">{{ctx.Locale.Tr "repo.licenses.master_label"}}</span>{{end}}</td>
|
||||
<td>
|
||||
<div class="tw-flex tw-items-center tw-gap-1">
|
||||
<code class="js-license-key-{{.ID}}">{{if .KeyRaw}}{{.KeyRaw}}{{else}}{{.KeyPrefix}}{{end}}</code>
|
||||
{{if .KeyRaw}}<button class="ui tiny icon button" data-clipboard-target=".js-license-key-{{.ID}}" data-tooltip-content="{{ctx.Locale.Tr "copy_url"}}">{{svg "octicon-copy" 12}}</button>{{end}}
|
||||
{{if .IsInternal}} <span class="ui tiny orange label">{{ctx.Locale.Tr "repo.licenses.master_label"}}</span>{{end}}
|
||||
</div>
|
||||
</td>
|
||||
<td>{{.LicenseeName}}{{if .LicenseeEmail}} <small>({{.LicenseeEmail}})</small>{{end}}</td>
|
||||
<td>{{if eq .ExpiresUnix 0}}{{ctx.Locale.Tr "repo.licenses.never"}}{{else}}{{DateUtils.AbsoluteShort .ExpiresUnix}}{{end}}</td>
|
||||
<td>{{if eq .LastHeartbeatUnix 0}}{{ctx.Locale.Tr "repo.licenses.never"}}{{else}}{{DateUtils.AbsoluteShort .LastHeartbeatUnix}}{{end}}</td>
|
||||
|
||||
@@ -156,7 +156,13 @@
|
||||
<tbody>
|
||||
{{range .LicenseKeys}}
|
||||
<tr>
|
||||
<td><code>{{.KeyPrefix}}</code>{{if .IsInternal}} <span class="ui tiny orange label">{{ctx.Locale.Tr "repo.licenses.master_label"}}</span>{{end}}</td>
|
||||
<td>
|
||||
<div class="tw-flex tw-items-center tw-gap-1">
|
||||
<code class="js-license-key-{{.ID}}">{{if .KeyRaw}}{{.KeyRaw}}{{else}}{{.KeyPrefix}}{{end}}</code>
|
||||
{{if .KeyRaw}}<button class="ui tiny icon button" data-clipboard-target=".js-license-key-{{.ID}}" data-tooltip-content="{{ctx.Locale.Tr "copy_url"}}">{{svg "octicon-copy" 12}}</button>{{end}}
|
||||
{{if .IsInternal}} <span class="ui tiny orange label">{{ctx.Locale.Tr "repo.licenses.master_label"}}</span>{{end}}
|
||||
</div>
|
||||
</td>
|
||||
<td>{{.LicenseeName}}{{if .LicenseeEmail}} <small>({{.LicenseeEmail}})</small>{{end}}</td>
|
||||
<td>{{if eq .ExpiresUnix 0}}{{ctx.Locale.Tr "repo.licenses.never"}}{{else}}{{DateUtils.AbsoluteShort .ExpiresUnix}}{{end}}</td>
|
||||
<td>{{if eq .LastHeartbeatUnix 0}}{{ctx.Locale.Tr "repo.licenses.never"}}{{else}}{{DateUtils.AbsoluteShort .LastHeartbeatUnix}}{{end}}</td>
|
||||
|
||||
Reference in New Issue
Block a user