mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 17:31:55 +08:00
add cloudflare provider
This commit is contained in:
parent
2b8fb9314f
commit
52cca47ec8
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,7 +2,7 @@ __debug_bin*
|
|||||||
vendor
|
vendor
|
||||||
pb_data
|
pb_data
|
||||||
main
|
main
|
||||||
certimate
|
./certimate
|
||||||
build
|
build
|
||||||
/docker/data
|
/docker/data
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
configTypeTencent = "tencent"
|
configTypeTencent = "tencent"
|
||||||
configTypeAliyun = "aliyun"
|
configTypeAliyun = "aliyun"
|
||||||
|
configTypeCloudflare = "cloudflare"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
@ -67,6 +68,8 @@ func Get(record *models.Record) (Applicant, error) {
|
|||||||
return NewTencent(option), nil
|
return NewTencent(option), nil
|
||||||
case configTypeAliyun:
|
case configTypeAliyun:
|
||||||
return NewAliyun(option), nil
|
return NewAliyun(option), nil
|
||||||
|
case configTypeCloudflare:
|
||||||
|
return NewCloudflare(option), nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("unknown config type")
|
return nil, errors.New("unknown config type")
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ func (c *cloudflare) Apply() (*Certificate, error) {
|
|||||||
access := &domain.CloudflareAccess{}
|
access := &domain.CloudflareAccess{}
|
||||||
json.Unmarshal([]byte(c.option.Access), access)
|
json.Unmarshal([]byte(c.option.Access), access)
|
||||||
|
|
||||||
os.Setenv("CLOUDFLARE_DNS_API_TOKEN", access.CloudflareDnsApiToken)
|
os.Setenv("CLOUDFLARE_DNS_API_TOKEN", access.DnsApiToken)
|
||||||
|
|
||||||
provider, err := cf.NewDNSProvider()
|
provider, err := cf.NewDNSProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -11,5 +11,5 @@ type TencentAccess struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CloudflareAccess struct {
|
type CloudflareAccess struct {
|
||||||
CloudflareDnsApiToken string `json:"cloudflareDnsApiToken"`
|
DnsApiToken string `json:"dnsApiToken"`
|
||||||
}
|
}
|
||||||
|
505
migrations/1725258856_collections_snapshot.go
Normal file
505
migrations/1725258856_collections_snapshot.go
Normal file
@ -0,0 +1,505 @@
|
|||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/pocketbase/dbx"
|
||||||
|
"github.com/pocketbase/pocketbase/daos"
|
||||||
|
m "github.com/pocketbase/pocketbase/migrations"
|
||||||
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
m.Register(func(db dbx.Builder) error {
|
||||||
|
jsonData := `[
|
||||||
|
{
|
||||||
|
"id": "_pb_users_auth_",
|
||||||
|
"created": "2024-07-29 09:44:56.398Z",
|
||||||
|
"updated": "2024-08-30 03:19:22.095Z",
|
||||||
|
"name": "users",
|
||||||
|
"type": "auth",
|
||||||
|
"system": false,
|
||||||
|
"schema": [
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "users_name",
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "users_avatar",
|
||||||
|
"name": "avatar",
|
||||||
|
"type": "file",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"mimeTypes": [
|
||||||
|
"image/jpeg",
|
||||||
|
"image/png",
|
||||||
|
"image/svg+xml",
|
||||||
|
"image/gif",
|
||||||
|
"image/webp"
|
||||||
|
],
|
||||||
|
"thumbs": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"maxSize": 5242880,
|
||||||
|
"protected": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [],
|
||||||
|
"listRule": "id = @request.auth.id",
|
||||||
|
"viewRule": "id = @request.auth.id",
|
||||||
|
"createRule": "",
|
||||||
|
"updateRule": "id = @request.auth.id",
|
||||||
|
"deleteRule": "id = @request.auth.id",
|
||||||
|
"options": {
|
||||||
|
"allowEmailAuth": true,
|
||||||
|
"allowOAuth2Auth": true,
|
||||||
|
"allowUsernameAuth": true,
|
||||||
|
"exceptEmailDomains": null,
|
||||||
|
"manageRule": null,
|
||||||
|
"minPasswordLength": 8,
|
||||||
|
"onlyEmailDomains": null,
|
||||||
|
"onlyVerified": false,
|
||||||
|
"requireEmail": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "z3p974ainxjqlvs",
|
||||||
|
"created": "2024-07-29 10:02:48.334Z",
|
||||||
|
"updated": "2024-08-30 03:19:22.096Z",
|
||||||
|
"name": "domains",
|
||||||
|
"type": "base",
|
||||||
|
"system": false,
|
||||||
|
"schema": [
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "iuaerpl2",
|
||||||
|
"name": "domain",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "v98eebqq",
|
||||||
|
"name": "crontab",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "alc8e9ow",
|
||||||
|
"name": "access",
|
||||||
|
"type": "relation",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"collectionId": "4yzbv8urny5ja1e",
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"minSelect": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"displayFields": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "topsc9bj",
|
||||||
|
"name": "certUrl",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "vixgq072",
|
||||||
|
"name": "certStableUrl",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "g3a3sza5",
|
||||||
|
"name": "privateKey",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "gr6iouny",
|
||||||
|
"name": "certificate",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "tk6vnrmn",
|
||||||
|
"name": "issuerCertificate",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "sjo6ibse",
|
||||||
|
"name": "csr",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "x03n1bkj",
|
||||||
|
"name": "expiredAt",
|
||||||
|
"type": "date",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": "",
|
||||||
|
"max": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "srybpixz",
|
||||||
|
"name": "targetType",
|
||||||
|
"type": "select",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"maxSelect": 1,
|
||||||
|
"values": [
|
||||||
|
"aliyun-oss",
|
||||||
|
"aliyun-cdn",
|
||||||
|
"ssh",
|
||||||
|
"webhook",
|
||||||
|
"tencent-cdn"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "xy7yk0mb",
|
||||||
|
"name": "targetAccess",
|
||||||
|
"type": "relation",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"collectionId": "4yzbv8urny5ja1e",
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"minSelect": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"displayFields": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "6jqeyggw",
|
||||||
|
"name": "enabled",
|
||||||
|
"type": "bool",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "hdsjcchf",
|
||||||
|
"name": "deployed",
|
||||||
|
"type": "bool",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "aiya3rev",
|
||||||
|
"name": "rightnow",
|
||||||
|
"type": "bool",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "ixznmhzc",
|
||||||
|
"name": "lastDeployedAt",
|
||||||
|
"type": "date",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": "",
|
||||||
|
"max": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "ghtlkn5j",
|
||||||
|
"name": "lastDeployment",
|
||||||
|
"type": "relation",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"collectionId": "0a1o4e6sstp694f",
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"minSelect": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"displayFields": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"CREATE UNIQUE INDEX ` + "`" + `idx_4ABO6EQ` + "`" + ` ON ` + "`" + `domains` + "`" + ` (` + "`" + `domain` + "`" + `)"
|
||||||
|
],
|
||||||
|
"listRule": null,
|
||||||
|
"viewRule": null,
|
||||||
|
"createRule": null,
|
||||||
|
"updateRule": null,
|
||||||
|
"deleteRule": null,
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4yzbv8urny5ja1e",
|
||||||
|
"created": "2024-07-29 10:04:39.685Z",
|
||||||
|
"updated": "2024-09-02 06:05:30.075Z",
|
||||||
|
"name": "access",
|
||||||
|
"type": "base",
|
||||||
|
"system": false,
|
||||||
|
"schema": [
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "geeur58v",
|
||||||
|
"name": "name",
|
||||||
|
"type": "text",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": null,
|
||||||
|
"max": null,
|
||||||
|
"pattern": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "iql7jpwx",
|
||||||
|
"name": "config",
|
||||||
|
"type": "json",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"maxSize": 2000000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "hwy7m03o",
|
||||||
|
"name": "configType",
|
||||||
|
"type": "select",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"maxSelect": 1,
|
||||||
|
"values": [
|
||||||
|
"aliyun",
|
||||||
|
"tencent",
|
||||||
|
"ssh",
|
||||||
|
"webhook",
|
||||||
|
"cloudflare"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "lr33hiwg",
|
||||||
|
"name": "deleted",
|
||||||
|
"type": "date",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": "",
|
||||||
|
"max": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
"CREATE UNIQUE INDEX ` + "`" + `idx_wkoST0j` + "`" + ` ON ` + "`" + `access` + "`" + ` (` + "`" + `name` + "`" + `)"
|
||||||
|
],
|
||||||
|
"listRule": null,
|
||||||
|
"viewRule": null,
|
||||||
|
"createRule": null,
|
||||||
|
"updateRule": null,
|
||||||
|
"deleteRule": null,
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "0a1o4e6sstp694f",
|
||||||
|
"created": "2024-07-30 06:30:27.801Z",
|
||||||
|
"updated": "2024-08-30 03:19:22.096Z",
|
||||||
|
"name": "deployments",
|
||||||
|
"type": "base",
|
||||||
|
"system": false,
|
||||||
|
"schema": [
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "farvlzk7",
|
||||||
|
"name": "domain",
|
||||||
|
"type": "relation",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"collectionId": "z3p974ainxjqlvs",
|
||||||
|
"cascadeDelete": false,
|
||||||
|
"minSelect": null,
|
||||||
|
"maxSelect": 1,
|
||||||
|
"displayFields": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "jx5f69i3",
|
||||||
|
"name": "log",
|
||||||
|
"type": "json",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"maxSize": 2000000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "qbxdtg9q",
|
||||||
|
"name": "phase",
|
||||||
|
"type": "select",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"maxSelect": 1,
|
||||||
|
"values": [
|
||||||
|
"check",
|
||||||
|
"apply",
|
||||||
|
"deploy"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "rglrp1hz",
|
||||||
|
"name": "phaseSuccess",
|
||||||
|
"type": "bool",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"system": false,
|
||||||
|
"id": "lt1g1blu",
|
||||||
|
"name": "deployedAt",
|
||||||
|
"type": "date",
|
||||||
|
"required": false,
|
||||||
|
"presentable": false,
|
||||||
|
"unique": false,
|
||||||
|
"options": {
|
||||||
|
"min": "",
|
||||||
|
"max": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [],
|
||||||
|
"listRule": null,
|
||||||
|
"viewRule": null,
|
||||||
|
"createRule": null,
|
||||||
|
"updateRule": null,
|
||||||
|
"deleteRule": null,
|
||||||
|
"options": {}
|
||||||
|
}
|
||||||
|
]`
|
||||||
|
|
||||||
|
collections := []*models.Collection{}
|
||||||
|
if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return daos.New(db).ImportCollections(collections, true, nil)
|
||||||
|
}, func(db dbx.Builder) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
1
ui/dist/assets/index-DHLrqoj1.css
vendored
Normal file
1
ui/dist/assets/index-DHLrqoj1.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
ui/dist/assets/index-DK_EegWM.css
vendored
1
ui/dist/assets/index-DK_EegWM.css
vendored
File diff suppressed because one or more lines are too long
24
ui/dist/imgs/providers/cloudflare.svg
vendored
Normal file
24
ui/dist/imgs/providers/cloudflare.svg
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 -70 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||||
|
<g>
|
||||||
|
<g transform="translate(0.000000, -1.000000)">
|
||||||
|
<path
|
||||||
|
d="M202.3569,50.394 L197.0459,48.27 C172.0849,104.434 72.7859,70.289 66.8109,86.997 C65.8149,98.283 121.0379,89.143 160.5169,91.056 C172.5559,91.639 178.5929,100.727 173.4809,115.54 L183.5499,115.571 C195.1649,79.362 232.2329,97.841 233.7819,85.891 C231.2369,78.034 191.1809,85.891 202.3569,50.394 Z"
|
||||||
|
fill="#FFFFFF">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
d="M176.332,109.3483 C177.925,104.0373 177.394,98.7263 174.739,95.5393 C172.083,92.3523 168.365,90.2283 163.585,89.6973 L71.17,88.6343 C70.639,88.6343 70.108,88.1033 69.577,88.1033 C69.046,87.5723 69.046,87.0413 69.577,86.5103 C70.108,85.4483 70.639,84.9163 71.701,84.9163 L164.647,83.8543 C175.801,83.3233 187.486,74.2943 191.734,63.6723 L197.046,49.8633 C197.046,49.3313 197.577,48.8003 197.046,48.2693 C191.203,21.1823 166.772,0.9993 138.091,0.9993 C111.535,0.9993 88.697,17.9953 80.73,41.8963 C75.419,38.1783 69.046,36.0533 61.61,36.5853 C48.863,37.6473 38.772,48.2693 37.178,61.0163 C36.647,64.2033 37.178,67.3903 37.71,70.5763 C16.996,71.1073 0,88.1033 0,109.3483 C0,111.4723 0,113.0663 0.531,115.1903 C0.531,116.2533 1.593,116.7843 2.125,116.7843 L172.614,116.7843 C173.676,116.7843 174.739,116.2533 174.739,115.1903 L176.332,109.3483 Z"
|
||||||
|
fill="#F4811F">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
d="M205.5436,49.8628 L202.8876,49.8628 C202.3566,49.8628 201.8256,50.3938 201.2946,50.9248 L197.5766,63.6718 C195.9836,68.9828 196.5146,74.2948 199.1706,77.4808 C201.8256,80.6678 205.5436,82.7918 210.3236,83.3238 L229.9756,84.3858 C230.5066,84.3858 231.0376,84.9168 231.5686,84.9168 C232.0996,85.4478 232.0996,85.9788 231.5686,86.5098 C231.0376,87.5728 230.5066,88.1038 229.4436,88.1038 L209.2616,89.1658 C198.1076,89.6968 186.4236,98.7258 182.1746,109.3478 L181.1116,114.1288 C180.5806,114.6598 181.1116,115.7218 182.1746,115.7218 L252.2826,115.7218 C253.3446,115.7218 253.8756,115.1908 253.8756,114.1288 C254.9376,109.8798 255.9996,105.0998 255.9996,100.3188 C255.9996,72.7008 233.1616,49.8628 205.5436,49.8628"
|
||||||
|
fill="#FAAD3F">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
4
ui/dist/index.html
vendored
4
ui/dist/index.html
vendored
@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Certimate - Your Trusted SSL Automation Partner</title>
|
<title>Certimate - Your Trusted SSL Automation Partner</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DYbObph2.js"></script>
|
<script type="module" crossorigin src="/assets/index-C0ENR1vV.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DK_EegWM.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DHLrqoj1.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-background">
|
<body class="bg-background">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
24
ui/public/imgs/providers/cloudflare.svg
Normal file
24
ui/public/imgs/providers/cloudflare.svg
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg width="800px" height="800px" viewBox="0 -70 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||||
|
<g>
|
||||||
|
<g transform="translate(0.000000, -1.000000)">
|
||||||
|
<path
|
||||||
|
d="M202.3569,50.394 L197.0459,48.27 C172.0849,104.434 72.7859,70.289 66.8109,86.997 C65.8149,98.283 121.0379,89.143 160.5169,91.056 C172.5559,91.639 178.5929,100.727 173.4809,115.54 L183.5499,115.571 C195.1649,79.362 232.2329,97.841 233.7819,85.891 C231.2369,78.034 191.1809,85.891 202.3569,50.394 Z"
|
||||||
|
fill="#FFFFFF">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
d="M176.332,109.3483 C177.925,104.0373 177.394,98.7263 174.739,95.5393 C172.083,92.3523 168.365,90.2283 163.585,89.6973 L71.17,88.6343 C70.639,88.6343 70.108,88.1033 69.577,88.1033 C69.046,87.5723 69.046,87.0413 69.577,86.5103 C70.108,85.4483 70.639,84.9163 71.701,84.9163 L164.647,83.8543 C175.801,83.3233 187.486,74.2943 191.734,63.6723 L197.046,49.8633 C197.046,49.3313 197.577,48.8003 197.046,48.2693 C191.203,21.1823 166.772,0.9993 138.091,0.9993 C111.535,0.9993 88.697,17.9953 80.73,41.8963 C75.419,38.1783 69.046,36.0533 61.61,36.5853 C48.863,37.6473 38.772,48.2693 37.178,61.0163 C36.647,64.2033 37.178,67.3903 37.71,70.5763 C16.996,71.1073 0,88.1033 0,109.3483 C0,111.4723 0,113.0663 0.531,115.1903 C0.531,116.2533 1.593,116.7843 2.125,116.7843 L172.614,116.7843 C173.676,116.7843 174.739,116.2533 174.739,115.1903 L176.332,109.3483 Z"
|
||||||
|
fill="#F4811F">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
d="M205.5436,49.8628 L202.8876,49.8628 C202.3566,49.8628 201.8256,50.3938 201.2946,50.9248 L197.5766,63.6718 C195.9836,68.9828 196.5146,74.2948 199.1706,77.4808 C201.8256,80.6678 205.5436,82.7918 210.3236,83.3238 L229.9756,84.3858 C230.5066,84.3858 231.0376,84.9168 231.5686,84.9168 C232.0996,85.4478 232.0996,85.9788 231.5686,86.5098 C231.0376,87.5728 230.5066,88.1038 229.4436,88.1038 L209.2616,89.1658 C198.1076,89.6968 186.4236,98.7258 182.1746,109.3478 L181.1116,114.1288 C180.5806,114.6598 181.1116,115.7218 182.1746,115.7218 L252.2826,115.7218 C253.3446,115.7218 253.8756,115.1908 253.8756,114.1288 C254.9376,109.8798 255.9996,105.0998 255.9996,100.3188 C255.9996,72.7008 233.1616,49.8628 205.5436,49.8628"
|
||||||
|
fill="#FAAD3F">
|
||||||
|
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
173
ui/src/components/certimate/AccessCloudflareForm.tsx
Normal file
173
ui/src/components/certimate/AccessCloudflareForm.tsx
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
|
||||||
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
|
||||||
|
import z from "zod";
|
||||||
|
import {
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
} from "@/components/ui/form";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
|
import { Access, accessFormType, CloudflareConfig } from "@/domain/access";
|
||||||
|
import { save } from "@/repository/access";
|
||||||
|
import { useConfig } from "@/providers/config";
|
||||||
|
import { ClientResponseError } from "pocketbase";
|
||||||
|
import { PbErrorData } from "@/domain/base";
|
||||||
|
|
||||||
|
const AccessCloudflareForm = ({
|
||||||
|
data,
|
||||||
|
onAfterReq,
|
||||||
|
}: {
|
||||||
|
data?: Access;
|
||||||
|
onAfterReq: () => void;
|
||||||
|
}) => {
|
||||||
|
const { addAccess, updateAccess } = useConfig();
|
||||||
|
const formSchema = z.object({
|
||||||
|
id: z.string().optional(),
|
||||||
|
name: z.string().min(1).max(64),
|
||||||
|
configType: accessFormType,
|
||||||
|
dnsApiToken: z.string().min(1).max(64),
|
||||||
|
});
|
||||||
|
|
||||||
|
let config: CloudflareConfig = {
|
||||||
|
dnsApiToken: "",
|
||||||
|
};
|
||||||
|
if (data) config = data.config as CloudflareConfig;
|
||||||
|
|
||||||
|
const form = useForm<z.infer<typeof formSchema>>({
|
||||||
|
resolver: zodResolver(formSchema),
|
||||||
|
defaultValues: {
|
||||||
|
id: data?.id,
|
||||||
|
name: data?.name,
|
||||||
|
configType: "cloudflare",
|
||||||
|
dnsApiToken: config.dnsApiToken,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
||||||
|
console.log(data);
|
||||||
|
const req: Access = {
|
||||||
|
id: data.id as string,
|
||||||
|
name: data.name,
|
||||||
|
configType: data.configType,
|
||||||
|
config: {
|
||||||
|
dnsApiToken: data.dnsApiToken,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rs = await save(req);
|
||||||
|
|
||||||
|
onAfterReq();
|
||||||
|
|
||||||
|
req.id = rs.id;
|
||||||
|
req.created = rs.created;
|
||||||
|
req.updated = rs.updated;
|
||||||
|
if (data.id) {
|
||||||
|
updateAccess(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addAccess(req);
|
||||||
|
} catch (e) {
|
||||||
|
const err = e as ClientResponseError;
|
||||||
|
|
||||||
|
Object.entries(err.response.data as PbErrorData).forEach(
|
||||||
|
([key, value]) => {
|
||||||
|
form.setError(key as keyof z.infer<typeof formSchema>, {
|
||||||
|
type: "manual",
|
||||||
|
message: value.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="max-w-[35em] mx-auto mt-10">
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={(e) => {
|
||||||
|
console.log(e);
|
||||||
|
e.stopPropagation();
|
||||||
|
form.handleSubmit(onSubmit)(e);
|
||||||
|
}}
|
||||||
|
className="space-y-8"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>名称</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="请输入授权名称" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="id"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="hidden">
|
||||||
|
<FormLabel>配置类型</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="configType"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="hidden">
|
||||||
|
<FormLabel>配置类型</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="dnsApiToken"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>CLOUD_DNS_API_TOKEN</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="请输入CLOUD_DNS_API_TOKEN" {...field} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="flex justify-end">
|
||||||
|
<Button type="submit">保存</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AccessCloudflareForm;
|
@ -15,10 +15,19 @@ import { Label } from "../ui/label";
|
|||||||
import { Access, accessTypeMap } from "@/domain/access";
|
import { Access, accessTypeMap } from "@/domain/access";
|
||||||
import AccessAliyunForm from "./AccessAliyunForm";
|
import AccessAliyunForm from "./AccessAliyunForm";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { RadioGroup, RadioGroupItem } from "../ui/radio-group";
|
|
||||||
|
|
||||||
import AccessSSHForm from "./AccessSSHForm";
|
import AccessSSHForm from "./AccessSSHForm";
|
||||||
import WebhookForm from "./AccessWebhookFrom";
|
import WebhookForm from "./AccessWebhookFrom";
|
||||||
|
import {
|
||||||
|
Select,
|
||||||
|
SelectContent,
|
||||||
|
SelectGroup,
|
||||||
|
SelectItem,
|
||||||
|
SelectLabel,
|
||||||
|
SelectTrigger,
|
||||||
|
SelectValue,
|
||||||
|
} from "../ui/select";
|
||||||
|
import AccessCloudflareForm from "./AccessCloudflareForm";
|
||||||
|
|
||||||
type TargetConfigEditProps = {
|
type TargetConfigEditProps = {
|
||||||
op: "add" | "edit";
|
op: "add" | "edit";
|
||||||
@ -79,6 +88,17 @@ export function AccessEdit({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
break;
|
||||||
|
case "cloudflare":
|
||||||
|
form = (
|
||||||
|
<AccessCloudflareForm
|
||||||
|
data={data}
|
||||||
|
onAfterReq={() => {
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOptionCls = (val: string) => {
|
const getOptionCls = (val: string) => {
|
||||||
@ -96,31 +116,38 @@ export function AccessEdit({
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<Label>服务商</Label>
|
<Label>服务商</Label>
|
||||||
<RadioGroup
|
|
||||||
value={configType}
|
<Select
|
||||||
className="flex mt-3 space-x-2"
|
|
||||||
onValueChange={(val) => {
|
onValueChange={(val) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
setConfigType(val);
|
setConfigType(val);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<SelectTrigger className="mt-3">
|
||||||
|
<SelectValue placeholder="请选择服务商" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>服务商</SelectLabel>
|
||||||
{typeKeys.map((key) => (
|
{typeKeys.map((key) => (
|
||||||
<div className="flex items-center space-x-2" key={key}>
|
<SelectItem value={key}>
|
||||||
<Label>
|
|
||||||
<RadioGroupItem value={key} hidden />
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex items-center space-x-2 border p-2 rounded cursor-pointer",
|
"flex items-center space-x-2 rounded cursor-pointer",
|
||||||
getOptionCls(key)
|
getOptionCls(key)
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<img src={accessTypeMap.get(key)?.[1]} className="h-6" />
|
<img
|
||||||
|
src={accessTypeMap.get(key)?.[1]}
|
||||||
|
className="h-6 w-6"
|
||||||
|
/>
|
||||||
<div>{accessTypeMap.get(key)?.[0]}</div>
|
<div>{accessTypeMap.get(key)?.[0]}</div>
|
||||||
</div>
|
</div>
|
||||||
</Label>
|
</SelectItem>
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
|
||||||
{form}
|
{form}
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,6 +3,7 @@ import { z } from "zod";
|
|||||||
export const accessTypeMap: Map<string, [string, string]> = new Map([
|
export const accessTypeMap: Map<string, [string, string]> = new Map([
|
||||||
["tencent", ["腾讯云", "/imgs/providers/tencent.svg"]],
|
["tencent", ["腾讯云", "/imgs/providers/tencent.svg"]],
|
||||||
["aliyun", ["阿里云", "/imgs/providers/aliyun.svg"]],
|
["aliyun", ["阿里云", "/imgs/providers/aliyun.svg"]],
|
||||||
|
["cloudflare", ["Cloudflare", "/imgs/providers/cloudflare.svg"]],
|
||||||
["ssh", ["SSH部署", "/imgs/providers/ssh.svg"]],
|
["ssh", ["SSH部署", "/imgs/providers/ssh.svg"]],
|
||||||
["webhook", ["Webhook", "/imgs/providers/webhook.svg"]],
|
["webhook", ["Webhook", "/imgs/providers/webhook.svg"]],
|
||||||
]);
|
]);
|
||||||
@ -13,6 +14,7 @@ export const accessFormType = z.union(
|
|||||||
z.literal("tencent"),
|
z.literal("tencent"),
|
||||||
z.literal("ssh"),
|
z.literal("ssh"),
|
||||||
z.literal("webhook"),
|
z.literal("webhook"),
|
||||||
|
z.literal("cloudflare"),
|
||||||
],
|
],
|
||||||
{ message: "请选择云服务商" }
|
{ message: "请选择云服务商" }
|
||||||
);
|
);
|
||||||
@ -21,7 +23,12 @@ export type Access = {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
configType: string;
|
configType: string;
|
||||||
config: TencentConfig | AliyunConfig | SSHConfig | WebhookConfig;
|
config:
|
||||||
|
| TencentConfig
|
||||||
|
| AliyunConfig
|
||||||
|
| SSHConfig
|
||||||
|
| WebhookConfig
|
||||||
|
| CloudflareConfig;
|
||||||
deleted?: string;
|
deleted?: string;
|
||||||
created?: string;
|
created?: string;
|
||||||
updated?: string;
|
updated?: string;
|
||||||
@ -31,6 +38,10 @@ export type WebhookConfig = {
|
|||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type CloudflareConfig = {
|
||||||
|
dnsApiToken: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type TencentConfig = {
|
export type TencentConfig = {
|
||||||
secretId: string;
|
secretId: string;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
|
@ -194,7 +194,7 @@ export default function Dashboard() {
|
|||||||
href="https://github.com/usual2970/certimate/releases"
|
href="https://github.com/usual2970/certimate/releases"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Certimate v0.0.11
|
Certimate v0.0.13
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user