feat: add secure module marketplace runtime (#745)

This commit is contained in:
Darko Gjorgjijoski
2026-08-05 03:49:42 +02:00
committed by GitHub
parent f322c2b74d
commit 8579e4f85f
79 changed files with 2084 additions and 1762 deletions
+2 -6
View File
@@ -169,12 +169,8 @@ export const API = {
// Modules
MODULES: '/api/v1/modules',
MODULES_CHECK: '/api/v1/modules/check',
MODULES_DOWNLOAD: '/api/v1/modules/download',
MODULES_UPLOAD: '/api/v1/modules/upload',
MODULES_UNZIP: '/api/v1/modules/unzip',
MODULES_COPY: '/api/v1/modules/copy',
MODULES_COMPLETE: '/api/v1/modules/complete',
MODULES_INSTALL: '/api/v1/modules/install',
MODULES_PAIRING: '/api/v1/modules/pairing',
// Self Update
CHECK_UPDATE: '/api/v1/check/update',
-1
View File
@@ -104,7 +104,6 @@ export type {
ActiveProviderResponse,
Module,
ModuleInstallPayload,
ModuleCheckResponse,
Backup,
BackupListResponse,
CreateBackupPayload,
+1 -1
View File
@@ -52,7 +52,7 @@ export type { CreateTaxTypePayload } from './tax-type.service'
export type { CustomFieldListParams, CreateCustomFieldPayload } from './custom-field.service'
export type { CreateNotePayload } from './note.service'
export type { CreateExchangeRateProviderPayload, BulkUpdatePayload, ExchangeRateResponse, ActiveProviderResponse } from './exchange-rate.service'
export type { Module, ModuleInstallPayload, ModuleCheckResponse } from './module.service'
export type { Module, ModuleInstallPayload } from './module.service'
export type { Backup, BackupListResponse, CreateBackupPayload, DeleteBackupParams } from './backup.service'
export type { MailConfig, CompanyMailConfig, MailDriver, TestMailPayload } from '@/scripts/types/mail-config'
export type { PdfConfig, PdfConfigResponse, PdfDriver, DomPdfConfig, GotenbergConfig } from './pdf.service'
@@ -3,11 +3,21 @@ import { API } from '../endpoints'
import type { ApiResponse } from '@/scripts/types/api'
import type { Module } from '@/scripts/types/domain/module'
export interface ModuleCheckResponse {
error?: string
success?: boolean
authenticated?: boolean
premium?: boolean
export type { Module } from '@/scripts/types/domain/module'
export interface MarketplacePairingStatus {
paired: boolean
expired: boolean
paired_at: string | null
}
export interface MarketplacePairingCode {
device_code: string
user_code: string | null
verification_uri: string | null
verification_uri_complete: string | null
expires_in: number
interval: number
}
export interface ModuleDetailMeta {
@@ -16,10 +26,8 @@ export interface ModuleDetailMeta {
export interface ModuleInstallPayload {
slug: string
module_name: string
version: string
checksum_sha256?: string | null
path?: string
channel?: 'stable' | 'insider'
}
export interface ModuleDetailResponse {
@@ -38,8 +46,23 @@ export const moduleService = {
return data
},
async checkToken(apiToken: string): Promise<ModuleCheckResponse> {
const { data } = await client.get(`${API.MODULES_CHECK}?api_token=${apiToken}`)
async pairingStatus(): Promise<MarketplacePairingStatus> {
const { data } = await client.get(API.MODULES_PAIRING)
return data
},
async startPairing(): Promise<MarketplacePairingCode> {
const { data } = await client.post(`${API.MODULES_PAIRING}/start`)
return data
},
async pollPairing(): Promise<{ status: 'pending' | 'paired' }> {
const { data } = await client.post(`${API.MODULES_PAIRING}/poll`)
return data
},
async disconnectMarketplace(): Promise<{ success: boolean }> {
const { data } = await client.delete(API.MODULES_PAIRING)
return data
},
@@ -53,29 +76,8 @@ export const moduleService = {
return data
},
// Installation flow
async download(payload: ModuleInstallPayload): Promise<{ success: boolean }> {
const { data } = await client.post(API.MODULES_DOWNLOAD, payload)
return data
},
async upload(payload: FormData): Promise<{ success: boolean }> {
const { data } = await client.post(API.MODULES_UPLOAD, payload)
return data
},
async unzip(payload: ModuleInstallPayload): Promise<{ success: boolean }> {
const { data } = await client.post(API.MODULES_UNZIP, payload)
return data
},
async copy(payload: ModuleInstallPayload): Promise<{ success: boolean }> {
const { data } = await client.post(API.MODULES_COPY, payload)
return data
},
async complete(payload: ModuleInstallPayload): Promise<{ success: boolean }> {
const { data } = await client.post(API.MODULES_COMPLETE, payload)
async install(payload: ModuleInstallPayload): Promise<{ success: boolean; error?: string }> {
const { data } = await client.post(API.MODULES_INSTALL, payload)
return data
},
}