diff --git a/.db b/.db new file mode 100644 index 00000000..e69de29b diff --git a/api/certificate/acme_user.go b/api/certificate/acme_user.go index 13431dd9..9a8d8c8b 100644 --- a/api/certificate/acme_user.go +++ b/api/certificate/acme_user.go @@ -13,7 +13,7 @@ import ( func GetAcmeUser(c *gin.Context) { u := query.AcmeUser - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) user, err := u.FirstByID(id) if err != nil { api.ErrHandler(c, err) @@ -79,7 +79,7 @@ func RecoverAcmeUser(c *gin.Context) { } func RegisterAcmeUser(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) u := query.AcmeUser user, err := u.FirstByID(id) if err != nil { diff --git a/api/certificate/certificate.go b/api/certificate/certificate.go index f333cfc9..40031cac 100644 --- a/api/certificate/certificate.go +++ b/api/certificate/certificate.go @@ -71,7 +71,7 @@ func GetCertList(c *gin.Context) { func GetCert(c *gin.Context) { q := query.Cert - certModel, err := q.FirstByID(cast.ToInt(c.Param("id"))) + certModel, err := q.FirstByID(cast.ToUint64(c.Param("id"))) if err != nil { api.ErrHandler(c, err) @@ -89,9 +89,9 @@ type certJson struct { SSLCertificateKey string `json:"ssl_certificate_key" binding:"omitempty,privatekey"` KeyType certcrypto.KeyType `json:"key_type" binding:"omitempty,auto_cert_key_type"` ChallengeMethod string `json:"challenge_method"` - DnsCredentialID int `json:"dns_credential_id"` - ACMEUserID int `json:"acme_user_id"` - SyncNodeIds []int `json:"sync_node_ids"` + DnsCredentialID uint64 `json:"dns_credential_id"` + ACMEUserID uint64 `json:"acme_user_id"` + SyncNodeIds []uint64 `json:"sync_node_ids"` } func AddCert(c *gin.Context) { @@ -141,7 +141,7 @@ func AddCert(c *gin.Context) { } func ModifyCert(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) var json certJson diff --git a/api/certificate/dns_credential.go b/api/certificate/dns_credential.go index 0fec35f4..189d11aa 100644 --- a/api/certificate/dns_credential.go +++ b/api/certificate/dns_credential.go @@ -12,7 +12,7 @@ import ( ) func GetDnsCredential(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) d := query.DnsCredential @@ -70,7 +70,7 @@ func AddDnsCredential(c *gin.Context) { } func EditDnsCredential(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) var json DnsCredentialManageJson if !api.BindAndValid(c, &json) { diff --git a/api/cluster/environment.go b/api/cluster/environment.go index ca9f5310..9bcddaad 100644 --- a/api/cluster/environment.go +++ b/api/cluster/environment.go @@ -15,7 +15,7 @@ import ( ) func GetEnvironment(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) envQuery := query.Environment @@ -67,7 +67,7 @@ func EditEnvironment(c *gin.Context) { } func DeleteEnvironment(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) envQuery := query.Environment env, err := envQuery.FirstByID(id) diff --git a/api/cluster/router.go b/api/cluster/router.go index 8c61c79c..70b4babc 100644 --- a/api/cluster/router.go +++ b/api/cluster/router.go @@ -6,7 +6,7 @@ func InitRouter(r *gin.RouterGroup) { // Environment r.GET("environments", GetEnvironmentList) r.POST("environments/load_from_settings", LoadEnvironmentFromSettings) - envGroup := r.Group("environment") + envGroup := r.Group("environments") { envGroup.GET("/:id", GetEnvironment) envGroup.POST("", AddEnvironment) diff --git a/api/config/add.go b/api/config/add.go index 167a8e80..7b83cc8a 100644 --- a/api/config/add.go +++ b/api/config/add.go @@ -17,11 +17,11 @@ import ( func AddConfig(c *gin.Context) { var json struct { - Name string `json:"name" binding:"required"` - NewFilepath string `json:"new_filepath" binding:"required"` - Content string `json:"content"` - Overwrite bool `json:"overwrite"` - SyncNodeIds []int `json:"sync_node_ids"` + Name string `json:"name" binding:"required"` + NewFilepath string `json:"new_filepath" binding:"required"` + Content string `json:"content"` + Overwrite bool `json:"overwrite"` + SyncNodeIds []uint64 `json:"sync_node_ids"` } if !api.BindAndValid(c, &json) { diff --git a/api/config/get.go b/api/config/get.go index 2d47f621..a38758d6 100644 --- a/api/config/get.go +++ b/api/config/get.go @@ -14,8 +14,8 @@ import ( type APIConfigResp struct { config.Config - SyncNodeIds []int `json:"sync_node_ids" gorm:"serializer:json"` - SyncOverwrite bool `json:"sync_overwrite"` + SyncNodeIds []uint64 `json:"sync_node_ids" gorm:"serializer:json"` + SyncOverwrite bool `json:"sync_overwrite"` } func GetConfig(c *gin.Context) { diff --git a/api/config/modify.go b/api/config/modify.go index 190281d7..ed7298d5 100644 --- a/api/config/modify.go +++ b/api/config/modify.go @@ -21,12 +21,12 @@ type EditConfigJson struct { func EditConfig(c *gin.Context) { name := c.Param("name") var json struct { - Name string `json:"name" binding:"required"` - Filepath string `json:"filepath" binding:"required"` - NewFilepath string `json:"new_filepath" binding:"required"` - Content string `json:"content"` - SyncOverwrite bool `json:"sync_overwrite"` - SyncNodeIds []int `json:"sync_node_ids"` + Name string `json:"name" binding:"required"` + Filepath string `json:"filepath" binding:"required"` + NewFilepath string `json:"new_filepath" binding:"required"` + Content string `json:"content"` + SyncOverwrite bool `json:"sync_overwrite"` + SyncNodeIds []uint64 `json:"sync_node_ids"` } if !api.BindAndValid(c, &json) { return diff --git a/api/config/rename.go b/api/config/rename.go index fb78dd77..fa1facac 100644 --- a/api/config/rename.go +++ b/api/config/rename.go @@ -14,10 +14,10 @@ import ( func Rename(c *gin.Context) { var json struct { - BasePath string `json:"base_path"` - OrigName string `json:"orig_name"` - NewName string `json:"new_name"` - SyncNodeIds []int `json:"sync_node_ids" gorm:"serializer:json"` + BasePath string `json:"base_path"` + OrigName string `json:"orig_name"` + NewName string `json:"new_name"` + SyncNodeIds []uint64 `json:"sync_node_ids" gorm:"serializer:json"` } if !api.BindAndValid(c, &json) { return diff --git a/api/config/router.go b/api/config/router.go index f182b27c..2031a237 100644 --- a/api/config/router.go +++ b/api/config/router.go @@ -9,9 +9,9 @@ func InitRouter(r *gin.RouterGroup) { r.GET("config_base_path", GetBasePath) r.GET("configs", GetConfigs) - r.GET("config/*name", GetConfig) - r.POST("config", AddConfig) - r.POST("config/*name", EditConfig) + r.GET("configs/*name", GetConfig) + r.POST("configs", AddConfig) + r.POST("configs/*name", EditConfig) o := r.Group("", middleware.RequireSecureSession()) { diff --git a/api/notification/notification.go b/api/notification/notification.go index f0c02304..cc5298c4 100644 --- a/api/notification/notification.go +++ b/api/notification/notification.go @@ -13,7 +13,7 @@ import ( func Get(c *gin.Context) { n := query.Notification - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) data, err := n.FirstByID(id) diff --git a/api/notification/router.go b/api/notification/router.go index 13d6c256..87c3d166 100644 --- a/api/notification/router.go +++ b/api/notification/router.go @@ -4,7 +4,7 @@ import "github.com/gin-gonic/gin" func InitRouter(r *gin.RouterGroup) { r.GET("notifications", GetList) - r.GET("notification/:id", Get) - r.DELETE("notification/:id", Destroy) + r.GET("notifications/:id", Get) + r.DELETE("notifications/:id", Destroy) r.DELETE("notifications", DestroyAll) } diff --git a/api/sites/auto_cert.go b/api/sites/auto_cert.go index 9348f205..74b39d85 100644 --- a/api/sites/auto_cert.go +++ b/api/sites/auto_cert.go @@ -13,7 +13,7 @@ func AddDomainToAutoCert(c *gin.Context) { name := c.Param("name") var json struct { - DnsCredentialID int `json:"dns_credential_id"` + DnsCredentialID uint64 `json:"dns_credential_id"` ChallengeMethod string `json:"challenge_method"` Domains []string `json:"domains"` KeyType certcrypto.KeyType `json:"key_type"` diff --git a/api/sites/category.go b/api/sites/category.go index d8ded05d..8f3ed9ba 100644 --- a/api/sites/category.go +++ b/api/sites/category.go @@ -7,7 +7,7 @@ import ( ) func GetCategory(c *gin.Context) { - + cosy.Core[model.SiteCategory](c).Get() } func GetCategoryList(c *gin.Context) { diff --git a/api/sites/router.go b/api/sites/router.go index a604e77c..ba33248a 100644 --- a/api/sites/router.go +++ b/api/sites/router.go @@ -4,22 +4,22 @@ import "github.com/gin-gonic/gin" func InitRouter(r *gin.RouterGroup) { r.GET("domains", GetSiteList) - r.GET("domain/:name", GetSite) - r.POST("domain/:name", SaveSite) - r.POST("domain/:name/enable", EnableSite) - r.POST("domain/:name/disable", DisableSite) - r.POST("domain/:name/advance", DomainEditByAdvancedMode) - r.DELETE("domain/:name", DeleteSite) - r.POST("domain/:name/duplicate", DuplicateSite) + r.GET("domains/:name", GetSite) + r.POST("domains/:name", SaveSite) + r.POST("domains/:name/enable", EnableSite) + r.POST("domains/:name/disable", DisableSite) + r.POST("domains/:name/advance", DomainEditByAdvancedMode) + r.DELETE("domains/:name", DeleteSite) + r.POST("domains/:name/duplicate", DuplicateSite) r.POST("auto_cert/:name", AddDomainToAutoCert) r.DELETE("auto_cert/:name", RemoveDomainFromAutoCert) } func InitCategoryRouter(r *gin.RouterGroup) { r.GET("site_categories", GetCategoryList) - r.GET("site_category/:id", GetCategory) - r.POST("site_category", AddCategory) - r.PUT("site_category/:id", ModifyCategory) - r.DELETE("site_category/:id", DeleteCategory) - r.POST("site_category/:id/recover", RecoverCategory) + r.GET("site_categories/:id", GetCategory) + r.POST("site_categories", AddCategory) + r.POST("site_categories/:id", ModifyCategory) + r.DELETE("site_categories/:id", DeleteCategory) + r.POST("site_categories/:id/recover", RecoverCategory) } diff --git a/api/streams/router.go b/api/streams/router.go index 52a2fc6b..4d0ce2dd 100644 --- a/api/streams/router.go +++ b/api/streams/router.go @@ -4,11 +4,11 @@ import "github.com/gin-gonic/gin" func InitRouter(r *gin.RouterGroup) { r.GET("streams", GetStreams) - r.GET("stream/:name", GetStream) - r.POST("stream/:name", SaveStream) - r.POST("stream/:name/enable", EnableStream) - r.POST("stream/:name/disable", DisableStream) - r.POST("stream/:name/advance", AdvancedEdit) - r.DELETE("stream/:name", DeleteStream) - r.POST("stream/:name/duplicate", Duplicate) + r.GET("streams/:name", GetStream) + r.POST("streams/:name", SaveStream) + r.POST("streams/:name/enable", EnableStream) + r.POST("streams/:name/disable", DisableStream) + r.POST("streams/:name/advance", AdvancedEdit) + r.DELETE("streams/:name", DeleteStream) + r.POST("streams/:name/duplicate", Duplicate) } diff --git a/api/template/router.go b/api/template/router.go index 0b58073a..a135a6bc 100644 --- a/api/template/router.go +++ b/api/template/router.go @@ -3,9 +3,9 @@ package template import "github.com/gin-gonic/gin" func InitRouter(r *gin.RouterGroup) { - r.GET("template", GetTemplate) - r.GET("template/configs", GetTemplateConfList) - r.GET("template/blocks", GetTemplateBlockList) - r.GET("template/block/:name", GetTemplateBlock) - r.POST("template/block/:name", GetTemplateBlock) + r.GET("templates", GetTemplate) + r.GET("templates/configs", GetTemplateConfList) + r.GET("templates/blocks", GetTemplateBlockList) + r.GET("templates/block/:name", GetTemplateBlock) + r.POST("templates/block/:name", GetTemplateBlock) } diff --git a/api/user/passkey.go b/api/user/passkey.go index 9df1d632..55bb1e8e 100644 --- a/api/user/passkey.go +++ b/api/user/passkey.go @@ -23,7 +23,7 @@ import ( const passkeyTimeout = 30 * time.Second -func buildCachePasskeyRegKey(id int) string { +func buildCachePasskeyRegKey(id uint64) string { return fmt.Sprintf("passkey-reg-%d", id) } @@ -130,7 +130,7 @@ func FinishPasskeyLogin(c *gin.Context) { LastUsedAt: time.Now().Unix(), }) - outUser, err = u.FirstByID(cast.ToInt(string(userHandle))) + outUser, err = u.FirstByID(cast.ToUint64(string(userHandle))) return outUser, err }, *sessionData, c.Request) if err != nil { diff --git a/api/user/router.go b/api/user/router.go index a53f34de..47704b3f 100644 --- a/api/user/router.go +++ b/api/user/router.go @@ -19,11 +19,11 @@ func InitAuthRouter(r *gin.RouterGroup) { func InitManageUserRouter(r *gin.RouterGroup) { r.GET("users", GetUsers) - r.GET("user/:id", GetUser) - r.POST("user", AddUser) - r.POST("user/:id", EditUser) - r.DELETE("user/:id", DeleteUser) - r.PATCH("user/:id", RecoverUser) + r.GET("users/:id", GetUser) + r.POST("users", AddUser) + r.POST("users/:id", EditUser) + r.DELETE("users/:id", DeleteUser) + r.PATCH("users/:id", RecoverUser) } func InitUserRouter(r *gin.RouterGroup) { diff --git a/api/user/user.go b/api/user/user.go index bfbe9ecc..f8e7a5bc 100644 --- a/api/user/user.go +++ b/api/user/user.go @@ -17,7 +17,7 @@ func GetUsers(c *gin.Context) { } func GetUser(c *gin.Context) { - id := cast.ToInt(c.Param("id")) + id := cast.ToUint64(c.Param("id")) u := query.User @@ -69,7 +69,7 @@ func AddUser(c *gin.Context) { } func EditUser(c *gin.Context) { - userId := cast.ToInt(c.Param("id")) + userId := cast.ToUint64(c.Param("id")) if settings.NodeSettings.Demo && userId == 1 { c.JSON(http.StatusNotAcceptable, gin.H{ diff --git a/app/src/api/acme_user.ts b/app/src/api/acme_user.ts index 76a7885a..242ee53e 100644 --- a/app/src/api/acme_user.ts +++ b/app/src/api/acme_user.ts @@ -11,7 +11,7 @@ export interface AcmeUser extends ModelBase { class ACMEUserCurd extends Curd { constructor() { - super('acme_user', 'acme_users') + super('acme_users') } public async register(id: number) { diff --git a/app/src/api/cert.ts b/app/src/api/cert.ts index c38ab6ee..3693f914 100644 --- a/app/src/api/cert.ts +++ b/app/src/api/cert.ts @@ -37,6 +37,6 @@ export interface CertificateResult { key_type: PrivateKeyType } -const cert: Curd = new Curd('/cert') +const cert: Curd = new Curd('/certs') export default cert diff --git a/app/src/api/config.ts b/app/src/api/config.ts index 567448a2..b43c65ef 100644 --- a/app/src/api/config.ts +++ b/app/src/api/config.ts @@ -14,7 +14,7 @@ export interface Config { class ConfigCurd extends Curd { constructor() { - super('/config') + super('/configs') } get_base_path() { diff --git a/app/src/api/curd.ts b/app/src/api/curd.ts index 33187ec2..c2af9d88 100644 --- a/app/src/api/curd.ts +++ b/app/src/api/curd.ts @@ -15,28 +15,31 @@ export interface Pagination { export interface GetListResponse { data: T[] - pagination: Pagination + pagination?: Pagination } class Curd { protected readonly baseUrl: string - protected readonly plural: string get_list = this._get_list.bind(this) get = this._get.bind(this) save = this._save.bind(this) + import = this._import.bind(this) + import_check = this._import_check.bind(this) destroy = this._destroy.bind(this) recover = this._recover.bind(this) update_order = this._update_order.bind(this) + batch_save = this._batch_save.bind(this) + batch_destroy = this._batch_destroy.bind(this) + batch_recover = this._batch_recover.bind(this) - constructor(baseUrl: string, plural: string | null = null) { + constructor(baseUrl: string) { this.baseUrl = baseUrl - this.plural = plural ?? `${this.baseUrl}s` } // eslint-disable-next-line ts/no-explicit-any _get_list(params: any = null): Promise> { - return http.get(this.plural, { params }) + return http.get(this.baseUrl, { params }) } // eslint-disable-next-line ts/no-explicit-any @@ -45,10 +48,25 @@ class Curd { } // eslint-disable-next-line ts/no-explicit-any - _save(id: any = null, data: any = undefined, config: any = undefined): Promise { + _save(id: any = null, data: any = {}, config: any = undefined): Promise { return http.post(this.baseUrl + (id ? `/${id}` : ''), data, config) } + // eslint-disable-next-line ts/no-explicit-any + _import_check(formData: FormData, config: any = {}): Promise { + return http.post(`${this.baseUrl}/import_check`, formData, { + headers: { + 'Content-Type': 'multipart/form-data;charset=UTF-8', + }, + ...config, + }) + } + + // eslint-disable-next-line ts/no-explicit-any + _import(data: any, config: any = {}): Promise { + return http.post(`${this.baseUrl}/import`, data, config) + } + // eslint-disable-next-line ts/no-explicit-any _destroy(id: any = null, params: any = {}) { return http.delete(`${this.baseUrl}/${id}`, { params }) @@ -59,12 +77,34 @@ class Curd { return http.patch(`${this.baseUrl}/${id}`) } - _update_order(data: { - target_id: number - direction: number - affected_ids: number[] - }) { - return http.post(`${this.plural}/order`, data) + _update_order(data: { target_id: number, direction: number, affected_ids: number[] }) { + return http.post(`${this.baseUrl}/order`, data) + } + + // eslint-disable-next-line ts/no-explicit-any + _batch_save(ids: any, data: any) { + return http.put(this.baseUrl, { + ids, + data, + }) + } + + // eslint-disable-next-line ts/no-explicit-any + _batch_destroy(ids?: (string | number)[], params: any = {}) { + return http.delete(this.baseUrl, { + params, + data: { + ids, + }, + }) + } + + _batch_recover(ids?: (string | number)[]) { + return http.patch(this.baseUrl, { + data: { + ids, + }, + }) } } diff --git a/app/src/api/dns_credential.ts b/app/src/api/dns_credential.ts index 7596b8cd..c06313be 100644 --- a/app/src/api/dns_credential.ts +++ b/app/src/api/dns_credential.ts @@ -17,6 +17,6 @@ export interface DnsCredential extends ModelBase { } } -const dns_credential: Curd = new Curd('/dns_credential') +const dns_credential: Curd = new Curd('/dns_credentials') export default dns_credential diff --git a/app/src/api/domain.ts b/app/src/api/domain.ts index 94e7d77d..5adcee30 100644 --- a/app/src/api/domain.ts +++ b/app/src/api/domain.ts @@ -56,6 +56,6 @@ class Domain extends Curd { } } -const domain = new Domain('/domain') +const domain = new Domain('/domains') export default domain diff --git a/app/src/api/environment.ts b/app/src/api/environment.ts index 5897c9df..47163a51 100644 --- a/app/src/api/environment.ts +++ b/app/src/api/environment.ts @@ -18,11 +18,11 @@ export interface Node { class EnvironmentCurd extends Curd { constructor() { - super('/environment') + super('/environments') } load_from_settings() { - return http.post(`${this.plural}/load_from_settings`) + return http.post(`${this.baseUrl}/load_from_settings`) } } diff --git a/app/src/api/notification.ts b/app/src/api/notification.ts index 0c9f2716..8ae96be9 100644 --- a/app/src/api/notification.ts +++ b/app/src/api/notification.ts @@ -10,10 +10,10 @@ export interface Notification extends ModelBase { class NotificationCurd extends Curd { public clear() { - return http.delete(this.plural) + return http.delete(this.baseUrl) } } -const notification = new NotificationCurd('/notification') +const notification = new NotificationCurd('/notifications') export default notification diff --git a/app/src/api/site_category.ts b/app/src/api/site_category.ts new file mode 100644 index 00000000..228a562f --- /dev/null +++ b/app/src/api/site_category.ts @@ -0,0 +1,11 @@ +import type { ModelBase } from '@/api/curd' +import Curd from '@/api/curd' + +export interface SiteCategory extends ModelBase { + name: string + sync_node_ids: number[] +} + +const site_category = new Curd('site_categories') + +export default site_category diff --git a/app/src/api/stream.ts b/app/src/api/stream.ts index e618b4d6..6516d0f6 100644 --- a/app/src/api/stream.ts +++ b/app/src/api/stream.ts @@ -33,6 +33,6 @@ class StreamCurd extends Curd { } } -const stream = new StreamCurd('/stream') +const stream = new StreamCurd('/streams') export default stream diff --git a/app/src/api/template.ts b/app/src/api/template.ts index 4cd4eafa..187a44e6 100644 --- a/app/src/api/template.ts +++ b/app/src/api/template.ts @@ -23,26 +23,26 @@ export interface Template extends NgxServer { class TemplateApi extends Curd