Lint
This commit is contained in:
parent
1964148581
commit
c8fc67d230
|
@ -29,7 +29,7 @@ export const account = (partial: Partial<Account> = {}): Account => {
|
||||||
size: "10+",
|
size: "10+",
|
||||||
profession: "Software Engineer",
|
profession: "Software Engineer",
|
||||||
quotaUsage: quotas.usage(),
|
quotaUsage: quotas.usage(),
|
||||||
...partial
|
...partial,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * from "./platform"
|
export * from "./platform"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * as installation from "./installation"
|
export * as installation from "./installation"
|
||||||
|
|
|
@ -7,6 +7,6 @@ export function install(): Installation {
|
||||||
_id: "install",
|
_id: "install",
|
||||||
_rev: db.rev(),
|
_rev: db.rev(),
|
||||||
installId: generator.guid(),
|
installId: generator.guid(),
|
||||||
version: generator.string()
|
version: generator.string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,9 +138,7 @@ interface GenerateLicenseOpts {
|
||||||
billing?: Billing
|
billing?: Billing
|
||||||
}
|
}
|
||||||
|
|
||||||
export const license = (
|
export const license = (opts: GenerateLicenseOpts = {}): License => {
|
||||||
opts: GenerateLicenseOpts = {}
|
|
||||||
): License => {
|
|
||||||
return {
|
return {
|
||||||
features: opts.features || [],
|
features: opts.features || [],
|
||||||
quotas: opts.quotas || quotas(),
|
quotas: opts.quotas || quotas(),
|
||||||
|
@ -149,23 +147,21 @@ export const license = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function offlineLicense (
|
export function offlineLicense(opts: GenerateLicenseOpts = {}): OfflineLicense {
|
||||||
opts: GenerateLicenseOpts = {}
|
|
||||||
): OfflineLicense {
|
|
||||||
const base = license(opts)
|
const base = license(opts)
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
expireAt: new Date().toISOString(),
|
expireAt: new Date().toISOString(),
|
||||||
identifier: offlineIdentifier()
|
identifier: offlineIdentifier(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function offlineIdentifier(
|
export function offlineIdentifier(
|
||||||
installId: string = generator.guid(),
|
installId: string = generator.guid(),
|
||||||
tenantId: string = generator.guid(),
|
tenantId: string = generator.guid()
|
||||||
): OfflineIdentifier {
|
): OfflineIdentifier {
|
||||||
return {
|
return {
|
||||||
installId,
|
installId,
|
||||||
tenantId
|
tenantId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
notifications,
|
notifications,
|
||||||
CopyInput,
|
CopyInput,
|
||||||
File
|
File,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { auth, admin } from "stores/portal"
|
import { auth, admin } from "stores/portal"
|
||||||
import { redirect } from "@roxi/routify"
|
import { redirect } from "@roxi/routify"
|
||||||
|
@ -35,9 +35,7 @@
|
||||||
|
|
||||||
let offlineLicenseIdentifier = ""
|
let offlineLicenseIdentifier = ""
|
||||||
let offlineLicense = undefined
|
let offlineLicense = undefined
|
||||||
const offlineLicenseExtensions = [
|
const offlineLicenseExtensions = [".txt"]
|
||||||
".txt",
|
|
||||||
]
|
|
||||||
|
|
||||||
// Make sure page can't be visited directly in cloud
|
// Make sure page can't be visited directly in cloud
|
||||||
$: {
|
$: {
|
||||||
|
@ -97,7 +95,7 @@
|
||||||
const license = await API.getOfflineLicense()
|
const license = await API.getOfflineLicense()
|
||||||
if (license) {
|
if (license) {
|
||||||
offlineLicense = {
|
offlineLicense = {
|
||||||
name: "license"
|
name: "license",
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offlineLicense = undefined
|
offlineLicense = undefined
|
||||||
|
@ -147,7 +145,7 @@
|
||||||
// prevent file preview jitter by assigning constant
|
// prevent file preview jitter by assigning constant
|
||||||
// as soon as possible
|
// as soon as possible
|
||||||
offlineLicense = {
|
offlineLicense = {
|
||||||
name: "license"
|
name: "license",
|
||||||
}
|
}
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.readAsText(event.detail)
|
reader.readAsText(event.detail)
|
||||||
|
@ -202,7 +200,9 @@
|
||||||
{#if $admin.offlineMode}
|
{#if $admin.offlineMode}
|
||||||
<Layout gap="XS" noPadding>
|
<Layout gap="XS" noPadding>
|
||||||
<Heading size="XS">Installation identifier</Heading>
|
<Heading size="XS">Installation identifier</Heading>
|
||||||
<Body size="S">Share this with support@budibase.com to obtain your offline license</Body>
|
<Body size="S"
|
||||||
|
>Share this with support@budibase.com to obtain your offline license</Body
|
||||||
|
>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
|
@ -263,8 +263,12 @@
|
||||||
<Layout noPadding gap="S">
|
<Layout noPadding gap="S">
|
||||||
<Body size="S">You are currently on the {license.plan.type} plan</Body>
|
<Body size="S">You are currently on the {license.plan.type} plan</Body>
|
||||||
<div>
|
<div>
|
||||||
<Body size="S">If you purchase or update your plan on the account</Body>
|
<Body size="S"
|
||||||
<Body size="S">portal, click the refresh button to sync those changes</Body>
|
>If you purchase or update your plan on the account</Body
|
||||||
|
>
|
||||||
|
<Body size="S"
|
||||||
|
>portal, click the refresh button to sync those changes</Body
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<Body size="XS">
|
<Body size="XS">
|
||||||
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
|
{processStringSync("Updated {{ duration time 'millisecond' }} ago", {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export const DEFAULT_CONFIG = {
|
||||||
adminUser: { checked: false },
|
adminUser: { checked: false },
|
||||||
sso: { checked: false },
|
sso: { checked: false },
|
||||||
},
|
},
|
||||||
offlineMode: false
|
offlineMode: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAdminStore() {
|
export function createAdminStore() {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
export const buildLicensingEndpoints = API => ({
|
export const buildLicensingEndpoints = API => ({
|
||||||
|
|
||||||
// LICENSE KEY
|
// LICENSE KEY
|
||||||
|
|
||||||
activateLicenseKey: async data => {
|
activateLicenseKey: async data => {
|
||||||
|
@ -31,7 +30,7 @@ export const buildLicensingEndpoints = API => ({
|
||||||
return API.post({
|
return API.post({
|
||||||
url: "/api/global/license/offline",
|
url: "/api/global/license/offline",
|
||||||
body: {
|
body: {
|
||||||
offlineLicenseToken
|
offlineLicenseToken,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1a5207d91fb9e0835562c708dd9c421973026543
|
Subproject commit b5124e76b9fa8020641e8d019ac1713c6245d6e6
|
|
@ -36,4 +36,4 @@ export interface CreateOfflineLicenseRequest {
|
||||||
export interface GetOfflineLicenseResponse {
|
export interface GetOfflineLicenseResponse {
|
||||||
offlineLicenseToken: string
|
offlineLicenseToken: string
|
||||||
license: OfflineLicense
|
license: OfflineLicense
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ export interface ActivateLicenseKeyRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetLicenseKeyResponse {
|
export interface GetLicenseKeyResponse {
|
||||||
licenseKey: string,
|
licenseKey: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFLINE LICENSE
|
// OFFLINE LICENSE
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { PurchasedPlan, Quotas, Feature, Billing } from "."
|
||||||
import { ISO8601 } from "../../shared"
|
import { ISO8601 } from "../../shared"
|
||||||
|
|
||||||
export interface OfflineIdentifier {
|
export interface OfflineIdentifier {
|
||||||
installId: string,
|
installId: string
|
||||||
tenantId: string
|
tenantId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,4 @@ export type DeepPartial<T> = {
|
||||||
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]
|
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ISO8601 = string
|
export type ISO8601 = string
|
||||||
|
|
|
@ -11,16 +11,16 @@ const pro = {
|
||||||
activateOfflineLicense: jest.fn(),
|
activateOfflineLicense: jest.fn(),
|
||||||
getOfflineLicenseToken: jest.fn(),
|
getOfflineLicenseToken: jest.fn(),
|
||||||
deleteOfflineLicenseToken: jest.fn(),
|
deleteOfflineLicenseToken: jest.fn(),
|
||||||
getIdentifierBase64: jest.fn()
|
getIdentifierBase64: jest.fn(),
|
||||||
},
|
},
|
||||||
cache: {
|
cache: {
|
||||||
...actual.licensing.cache,
|
...actual.licensing.cache,
|
||||||
refresh: jest.fn(),
|
refresh: jest.fn(),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
quotas: {
|
quotas: {
|
||||||
...actual.quotas,
|
...actual.quotas,
|
||||||
getQuotaUsage: jest.fn()
|
getQuotaUsage: jest.fn(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,9 @@ import {
|
||||||
|
|
||||||
// LICENSE KEY
|
// LICENSE KEY
|
||||||
|
|
||||||
export async function activateLicenseKey(ctx: UserCtx<ActivateLicenseKeyRequest>) {
|
export async function activateLicenseKey(
|
||||||
|
ctx: UserCtx<ActivateLicenseKeyRequest>
|
||||||
|
) {
|
||||||
const { licenseKey } = ctx.request.body
|
const { licenseKey } = ctx.request.body
|
||||||
await licensing.keys.activateLicenseKey(licenseKey)
|
await licensing.keys.activateLicenseKey(licenseKey)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
|
@ -33,13 +35,17 @@ export async function deleteLicenseKey(ctx: UserCtx<void, void>) {
|
||||||
|
|
||||||
// OFFLINE LICENSE
|
// OFFLINE LICENSE
|
||||||
|
|
||||||
export async function activateOfflineLicenseToken(ctx: UserCtx<ActivateOfflineLicenseTokenRequest>) {
|
export async function activateOfflineLicenseToken(
|
||||||
|
ctx: UserCtx<ActivateOfflineLicenseTokenRequest>
|
||||||
|
) {
|
||||||
const { offlineLicenseToken } = ctx.request.body
|
const { offlineLicenseToken } = ctx.request.body
|
||||||
await licensing.offline.activateOfflineLicenseToken(offlineLicenseToken)
|
await licensing.offline.activateOfflineLicenseToken(offlineLicenseToken)
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getOfflineLicenseToken(ctx: UserCtx<void, GetOfflineLicenseTokenResponse>) {
|
export async function getOfflineLicenseToken(
|
||||||
|
ctx: UserCtx<void, GetOfflineLicenseTokenResponse>
|
||||||
|
) {
|
||||||
const offlineLicenseToken = await licensing.offline.getOfflineLicenseToken()
|
const offlineLicenseToken = await licensing.offline.getOfflineLicenseToken()
|
||||||
if (offlineLicenseToken) {
|
if (offlineLicenseToken) {
|
||||||
ctx.body = { offlineLicenseToken: "*" }
|
ctx.body = { offlineLicenseToken: "*" }
|
||||||
|
@ -54,7 +60,9 @@ export async function deleteOfflineLicenseToken(ctx: UserCtx<void, void>) {
|
||||||
ctx.status = 204
|
ctx.status = 204
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getOfflineLicenseIdentifier(ctx: UserCtx<void, GetOfflineIdentifierResponse>) {
|
export async function getOfflineLicenseIdentifier(
|
||||||
|
ctx: UserCtx<void, GetOfflineIdentifierResponse>
|
||||||
|
) {
|
||||||
const identifierBase64 = await licensing.offline.getIdentifierBase64()
|
const identifierBase64 = await licensing.offline.getIdentifierBase64()
|
||||||
ctx.body = { identifierBase64 }
|
ctx.body = { identifierBase64 }
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
|
|
|
@ -3,13 +3,17 @@ import * as controller from "../../controllers/global/license"
|
||||||
import { middleware } from "@budibase/backend-core"
|
import { middleware } from "@budibase/backend-core"
|
||||||
import Joi from "joi"
|
import Joi from "joi"
|
||||||
|
|
||||||
const activateLicenseKeyValidator = middleware.joiValidator.body(Joi.object({
|
const activateLicenseKeyValidator = middleware.joiValidator.body(
|
||||||
|
Joi.object({
|
||||||
licenseKey: Joi.string().required(),
|
licenseKey: Joi.string().required(),
|
||||||
}).required())
|
}).required()
|
||||||
|
)
|
||||||
|
|
||||||
const activateOfflineLicenseValidator = middleware.joiValidator.body(Joi.object({
|
const activateOfflineLicenseValidator = middleware.joiValidator.body(
|
||||||
|
Joi.object({
|
||||||
offlineLicenseToken: Joi.string().required(),
|
offlineLicenseToken: Joi.string().required(),
|
||||||
}).required())
|
}).required()
|
||||||
|
)
|
||||||
|
|
||||||
const router: Router = new Router()
|
const router: Router = new Router()
|
||||||
|
|
||||||
|
@ -17,13 +21,24 @@ router
|
||||||
.post("/api/global/license/refresh", controller.refresh)
|
.post("/api/global/license/refresh", controller.refresh)
|
||||||
.get("/api/global/license/usage", controller.getQuotaUsage)
|
.get("/api/global/license/usage", controller.getQuotaUsage)
|
||||||
// LICENSE KEY
|
// LICENSE KEY
|
||||||
.post("/api/global/license/key", activateLicenseKeyValidator, controller.activateLicenseKey)
|
.post(
|
||||||
|
"/api/global/license/key",
|
||||||
|
activateLicenseKeyValidator,
|
||||||
|
controller.activateLicenseKey
|
||||||
|
)
|
||||||
.get("/api/global/license/key", controller.getLicenseKey)
|
.get("/api/global/license/key", controller.getLicenseKey)
|
||||||
.delete("/api/global/license/key", controller.deleteLicenseKey)
|
.delete("/api/global/license/key", controller.deleteLicenseKey)
|
||||||
// OFFLINE LICENSE
|
// OFFLINE LICENSE
|
||||||
.post("/api/global/license/offline", activateOfflineLicenseValidator, controller.activateOfflineLicenseToken)
|
.post(
|
||||||
|
"/api/global/license/offline",
|
||||||
|
activateOfflineLicenseValidator,
|
||||||
|
controller.activateOfflineLicenseToken
|
||||||
|
)
|
||||||
.get("/api/global/license/offline", controller.getOfflineLicenseToken)
|
.get("/api/global/license/offline", controller.getOfflineLicenseToken)
|
||||||
.delete("/api/global/license/offline", controller.deleteOfflineLicenseToken)
|
.delete("/api/global/license/offline", controller.deleteOfflineLicenseToken)
|
||||||
.get("/api/global/license/offline/identifier", controller.getOfflineLicenseIdentifier)
|
.get(
|
||||||
|
"/api/global/license/offline/identifier",
|
||||||
|
controller.getOfflineLicenseIdentifier
|
||||||
|
)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
|
@ -37,7 +37,9 @@ describe("/api/global/license", () => {
|
||||||
|
|
||||||
describe("POST /api/global/license/key", () => {
|
describe("POST /api/global/license/key", () => {
|
||||||
it("returns 200", async () => {
|
it("returns 200", async () => {
|
||||||
const res = await config.api.license.activateLicenseKey({ licenseKey: "licenseKey" })
|
const res = await config.api.license.activateLicenseKey({
|
||||||
|
licenseKey: "licenseKey",
|
||||||
|
})
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
expect(licensing.keys.activateLicenseKey).toBeCalledWith("licenseKey")
|
expect(licensing.keys.activateLicenseKey).toBeCalledWith("licenseKey")
|
||||||
})
|
})
|
||||||
|
@ -53,7 +55,7 @@ describe("/api/global/license", () => {
|
||||||
const res = await config.api.license.getLicenseKey()
|
const res = await config.api.license.getLicenseKey()
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
expect(res.body).toEqual({
|
expect(res.body).toEqual({
|
||||||
licenseKey: "*"
|
licenseKey: "*",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -68,8 +70,12 @@ describe("/api/global/license", () => {
|
||||||
|
|
||||||
describe("POST /api/global/license/offline", () => {
|
describe("POST /api/global/license/offline", () => {
|
||||||
it("activates offline license", async () => {
|
it("activates offline license", async () => {
|
||||||
const res = await config.api.license.activateOfflineLicense({ offlineLicenseToken: "offlineLicenseToken"})
|
const res = await config.api.license.activateOfflineLicense({
|
||||||
expect(licensing.offline.activateOfflineLicense).toBeCalledWith("offlineLicenseToken")
|
offlineLicenseToken: "offlineLicenseToken",
|
||||||
|
})
|
||||||
|
expect(licensing.offline.activateOfflineLicenseToken).toBeCalledWith(
|
||||||
|
"offlineLicenseToken"
|
||||||
|
)
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -80,11 +86,13 @@ describe("/api/global/license", () => {
|
||||||
expect(res.status).toBe(404)
|
expect(res.status).toBe(404)
|
||||||
})
|
})
|
||||||
it("returns 200 + offline license token", async () => {
|
it("returns 200 + offline license token", async () => {
|
||||||
licensing.offline.getOfflineLicenseToken.mockResolvedValue("offlineLicenseToken")
|
licensing.offline.getOfflineLicenseToken.mockResolvedValue(
|
||||||
|
"offlineLicenseToken"
|
||||||
|
)
|
||||||
const res = await config.api.license.getOfflineLicense()
|
const res = await config.api.license.getOfflineLicense()
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
expect(res.body).toEqual({
|
expect(res.body).toEqual({
|
||||||
offlineLicenseToken: "*"
|
offlineLicenseToken: "*",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -103,7 +111,7 @@ describe("/api/global/license", () => {
|
||||||
const res = await config.api.license.getOfflineLicenseIdentifier()
|
const res = await config.api.license.getOfflineLicenseIdentifier()
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
expect(res.body).toEqual({
|
expect(res.body).toEqual({
|
||||||
identifierBase64: "base64"
|
identifierBase64: "base64",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import TestConfiguration from "../TestConfiguration"
|
import TestConfiguration from "../TestConfiguration"
|
||||||
import { TestAPI } from "./base"
|
import { TestAPI } from "./base"
|
||||||
import { ActivateLicenseKeyRequest, ActivateOfflineLicenseRequest } from "@budibase/types"
|
import {
|
||||||
|
ActivateLicenseKeyRequest,
|
||||||
|
ActivateOfflineLicenseTokenRequest,
|
||||||
|
} from "@budibase/types"
|
||||||
|
|
||||||
export class LicenseAPI extends TestAPI {
|
export class LicenseAPI extends TestAPI {
|
||||||
constructor(config: TestConfiguration) {
|
constructor(config: TestConfiguration) {
|
||||||
|
@ -35,7 +38,7 @@ export class LicenseAPI extends TestAPI {
|
||||||
.delete("/api/global/license/key")
|
.delete("/api/global/license/key")
|
||||||
.set(this.config.defaultHeaders())
|
.set(this.config.defaultHeaders())
|
||||||
}
|
}
|
||||||
activateOfflineLicense = async (body: ActivateOfflineLicenseRequest) => {
|
activateOfflineLicense = async (body: ActivateOfflineLicenseTokenRequest) => {
|
||||||
return this.request
|
return this.request
|
||||||
.post("/api/global/license/offline")
|
.post("/api/global/license/offline")
|
||||||
.send(body)
|
.send(body)
|
||||||
|
|
Loading…
Reference in New Issue