Merge pull request #7859 from Budibase/feature/enterprise
Enterprise / license override support
This commit is contained in:
commit
c3ee8b0e56
|
@ -23,9 +23,11 @@ export default class LoggingProcessor implements EventProcessor {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let timestampString = getTimestampString(timestamp)
|
let timestampString = getTimestampString(timestamp)
|
||||||
console.log(
|
let message = `[audit] [tenant=${identity.tenantId}] [identityType=${identity.type}] [identity=${identity.id}] ${timestampString} ${event} `
|
||||||
`[audit] [tenant=${identity.tenantId}] [identityType=${identity.type}] [identity=${identity.id}] ${timestampString} ${event} `
|
if (env.isDev()) {
|
||||||
)
|
message = message + `[debug: [properties=${JSON.stringify(properties)}] ]`
|
||||||
|
}
|
||||||
|
console.log(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
async identify(identity: Identity, timestamp?: string | number) {
|
async identify(identity: Identity, timestamp?: string | number) {
|
||||||
|
|
|
@ -1,27 +1,78 @@
|
||||||
import { publishEvent } from "../events"
|
import { publishEvent } from "../events"
|
||||||
import {
|
import {
|
||||||
Event,
|
Event,
|
||||||
License,
|
|
||||||
LicenseActivatedEvent,
|
LicenseActivatedEvent,
|
||||||
LicenseDowngradedEvent,
|
LicensePlanChangedEvent,
|
||||||
LicenseUpdatedEvent,
|
LicenseTierChangedEvent,
|
||||||
LicenseUpgradedEvent,
|
PlanType,
|
||||||
|
Account,
|
||||||
|
LicensePortalOpenedEvent,
|
||||||
|
LicenseCheckoutSuccessEvent,
|
||||||
|
LicenseCheckoutOpenedEvent,
|
||||||
|
LicensePaymentFailedEvent,
|
||||||
|
LicensePaymentRecoveredEvent,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
|
||||||
// TODO
|
export async function tierChanged(account: Account, from: number, to: number) {
|
||||||
export async function updgraded(license: License) {
|
const properties: LicenseTierChangedEvent = {
|
||||||
const properties: LicenseUpgradedEvent = {}
|
accountId: account.accountId,
|
||||||
await publishEvent(Event.LICENSE_UPGRADED, properties)
|
to,
|
||||||
|
from,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_TIER_CHANGED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
export async function planChanged(
|
||||||
export async function downgraded(license: License) {
|
account: Account,
|
||||||
const properties: LicenseDowngradedEvent = {}
|
from: PlanType,
|
||||||
await publishEvent(Event.LICENSE_DOWNGRADED, properties)
|
to: PlanType
|
||||||
|
) {
|
||||||
|
const properties: LicensePlanChangedEvent = {
|
||||||
|
accountId: account.accountId,
|
||||||
|
to,
|
||||||
|
from,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_PLAN_CHANGED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
export async function activated(account: Account) {
|
||||||
export async function activated(license: License) {
|
const properties: LicenseActivatedEvent = {
|
||||||
const properties: LicenseActivatedEvent = {}
|
accountId: account.accountId,
|
||||||
|
}
|
||||||
await publishEvent(Event.LICENSE_ACTIVATED, properties)
|
await publishEvent(Event.LICENSE_ACTIVATED, properties)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function checkoutOpened(account: Account) {
|
||||||
|
const properties: LicenseCheckoutOpenedEvent = {
|
||||||
|
accountId: account.accountId,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_CHECKOUT_OPENED, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkoutSuccess(account: Account) {
|
||||||
|
const properties: LicenseCheckoutSuccessEvent = {
|
||||||
|
accountId: account.accountId,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_CHECKOUT_SUCCESS, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function portalOpened(account: Account) {
|
||||||
|
const properties: LicensePortalOpenedEvent = {
|
||||||
|
accountId: account.accountId,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_PORTAL_OPENED, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function paymentFailed(account: Account) {
|
||||||
|
const properties: LicensePaymentFailedEvent = {
|
||||||
|
accountId: account.accountId,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_PAYMENT_FAILED, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function paymentRecovered(account: Account) {
|
||||||
|
const properties: LicensePaymentRecoveredEvent = {
|
||||||
|
accountId: account.accountId,
|
||||||
|
}
|
||||||
|
await publishEvent(Event.LICENSE_PAYMENT_RECOVERED, properties)
|
||||||
|
}
|
||||||
|
|
|
@ -5,10 +5,12 @@ const { doInAppContext } = require("@budibase/backend-core/context")
|
||||||
const { doInTenant } = require("@budibase/backend-core/tenancy")
|
const { doInTenant } = require("@budibase/backend-core/tenancy")
|
||||||
const {
|
const {
|
||||||
quotas,
|
quotas,
|
||||||
|
} = require("@budibase/pro")
|
||||||
|
const {
|
||||||
QuotaUsageType,
|
QuotaUsageType,
|
||||||
StaticQuotaName,
|
StaticQuotaName,
|
||||||
MonthlyQuotaName,
|
MonthlyQuotaName,
|
||||||
} = require("@budibase/pro")
|
} = require("@budibase/types")
|
||||||
|
|
||||||
describe("/rows", () => {
|
describe("/rows", () => {
|
||||||
let request = setup.getRequest()
|
let request = setup.getRequest()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { getTenantId } from "@budibase/backend-core/tenancy"
|
import { getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
|
import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
// get app count
|
// get app count
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { getTenantId } from "@budibase/backend-core/tenancy"
|
import { getTenantId } from "@budibase/backend-core/tenancy"
|
||||||
import { getAllApps } from "@budibase/backend-core/db"
|
import { getAllApps } from "@budibase/backend-core/db"
|
||||||
import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
import { getUniqueRows } from "../../../utilities/usageQuota/rows"
|
||||||
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
|
import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
|
||||||
|
|
||||||
export const run = async () => {
|
export const run = async () => {
|
||||||
// get all rows in all apps
|
// get all rows in all apps
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import TestConfig from "../../../../tests/utilities/TestConfiguration"
|
import TestConfig from "../../../../tests/utilities/TestConfiguration"
|
||||||
import * as syncApps from "../syncApps"
|
import * as syncApps from "../syncApps"
|
||||||
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
|
import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
|
||||||
|
|
||||||
describe("syncApps", () => {
|
describe("syncApps", () => {
|
||||||
let config = new TestConfig(false)
|
let config = new TestConfig(false)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import TestConfig from "../../../../tests/utilities/TestConfiguration"
|
import TestConfig from "../../../../tests/utilities/TestConfiguration"
|
||||||
import * as syncRows from "../syncRows"
|
import * as syncRows from "../syncRows"
|
||||||
import { quotas, QuotaUsageType, StaticQuotaName } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
|
import { QuotaUsageType, StaticQuotaName } from "@budibase/types"
|
||||||
|
|
||||||
describe("syncRows", () => {
|
describe("syncRows", () => {
|
||||||
let config = new TestConfig(false)
|
let config = new TestConfig(false)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Hosting } from "../../sdk"
|
import { Feature, Hosting, PlanType, Quotas } from "../../sdk"
|
||||||
|
|
||||||
export interface CreateAccount {
|
export interface CreateAccount {
|
||||||
email: string
|
email: string
|
||||||
|
@ -22,6 +22,11 @@ export const isCreatePasswordAccount = (
|
||||||
account: CreateAccount
|
account: CreateAccount
|
||||||
): account is CreatePassswordAccount => account.authType === AuthType.PASSWORD
|
): account is CreatePassswordAccount => account.authType === AuthType.PASSWORD
|
||||||
|
|
||||||
|
export interface LicenseOverrides {
|
||||||
|
features?: Feature[]
|
||||||
|
quotas?: Quotas
|
||||||
|
}
|
||||||
|
|
||||||
export interface Account extends CreateAccount {
|
export interface Account extends CreateAccount {
|
||||||
// generated
|
// generated
|
||||||
accountId: string
|
accountId: string
|
||||||
|
@ -31,9 +36,12 @@ export interface Account extends CreateAccount {
|
||||||
verificationSent: boolean
|
verificationSent: boolean
|
||||||
// licensing
|
// licensing
|
||||||
tier: string // deprecated
|
tier: string // deprecated
|
||||||
|
planType?: PlanType
|
||||||
|
planTier?: number
|
||||||
stripeCustomerId?: string
|
stripeCustomerId?: string
|
||||||
licenseKey?: string
|
licenseKey?: string
|
||||||
licenseKeyActivatedAt?: number
|
licenseKeyActivatedAt?: number
|
||||||
|
licenseOverrides?: LicenseOverrides
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PasswordAccount extends Account {
|
export interface PasswordAccount extends Account {
|
||||||
|
|
|
@ -2,3 +2,4 @@ export * from "./config"
|
||||||
export * from "./user"
|
export * from "./user"
|
||||||
export * from "./userGroup"
|
export * from "./userGroup"
|
||||||
export * from "./plugin"
|
export * from "./plugin"
|
||||||
|
export * from "./quotas"
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { MonthlyQuotaName, StaticQuotaName } from "../../sdk"
|
||||||
|
|
||||||
|
export interface QuotaUsage {
|
||||||
|
_id: string
|
||||||
|
_rev?: string
|
||||||
|
quotaReset: string
|
||||||
|
usageQuota: {
|
||||||
|
[key in StaticQuotaName]: number
|
||||||
|
}
|
||||||
|
monthly: {
|
||||||
|
[key: string]: {
|
||||||
|
[key in MonthlyQuotaName]: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -133,9 +133,14 @@ export enum Event {
|
||||||
AUTOMATION_TRIGGER_UPDATED = "automation:trigger:updated",
|
AUTOMATION_TRIGGER_UPDATED = "automation:trigger:updated",
|
||||||
|
|
||||||
// LICENSE
|
// LICENSE
|
||||||
LICENSE_UPGRADED = "license:upgraded",
|
LICENSE_PLAN_CHANGED = "license:plan:changed",
|
||||||
LICENSE_DOWNGRADED = "license:downgraded",
|
LICENSE_TIER_CHANGED = "license:tier:changed",
|
||||||
LICENSE_ACTIVATED = "license:activated",
|
LICENSE_ACTIVATED = "license:activated",
|
||||||
|
LICENSE_PAYMENT_FAILED = "license:payment:failed",
|
||||||
|
LICENSE_PAYMENT_RECOVERED = "license:payment:recovered",
|
||||||
|
LICENSE_CHECKOUT_OPENED = "license:checkout:opened",
|
||||||
|
LICENSE_CHECKOUT_SUCCESS = "license:checkout:success",
|
||||||
|
LICENSE_PORTAL_OPENED = "license:portal:opened",
|
||||||
|
|
||||||
// ACCOUNT
|
// ACCOUNT
|
||||||
ACCOUNT_CREATED = "account:created",
|
ACCOUNT_CREATED = "account:created",
|
||||||
|
|
|
@ -1,7 +1,37 @@
|
||||||
export interface LicenseUpgradedEvent {}
|
import { PlanType } from "../licensing"
|
||||||
|
|
||||||
export interface LicenseDowngradedEvent {}
|
export interface LicenseTierChangedEvent {
|
||||||
|
accountId: string
|
||||||
|
from: number
|
||||||
|
to: number
|
||||||
|
}
|
||||||
|
|
||||||
export interface LicenseUpdatedEvent {}
|
export interface LicensePlanChangedEvent {
|
||||||
|
accountId: string
|
||||||
|
from: PlanType
|
||||||
|
to: PlanType
|
||||||
|
}
|
||||||
|
|
||||||
export interface LicenseActivatedEvent {}
|
export interface LicenseActivatedEvent {
|
||||||
|
accountId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LicenseCheckoutOpenedEvent {
|
||||||
|
accountId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LicenseCheckoutSuccessEvent {
|
||||||
|
accountId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LicensePortalOpenedEvent {
|
||||||
|
accountId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LicensePaymentFailedEvent {
|
||||||
|
accountId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LicensePaymentRecoveredEvent {
|
||||||
|
accountId: string
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ export interface Subscription {
|
||||||
cancelAt: number | null | undefined
|
cancelAt: number | null | undefined
|
||||||
currentPeriodStart: number
|
currentPeriodStart: number
|
||||||
currentPeriodEnd: number
|
currentPeriodEnd: number
|
||||||
|
status: string
|
||||||
|
pastDueAt?: number | null
|
||||||
|
downgradeAt?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Billing {
|
export interface Billing {
|
||||||
|
|
|
@ -6,6 +6,7 @@ export interface AccountPlan {
|
||||||
export enum PlanType {
|
export enum PlanType {
|
||||||
FREE = "free",
|
FREE = "free",
|
||||||
PRO = "pro",
|
PRO = "pro",
|
||||||
|
TEAM = "team",
|
||||||
BUSINESS = "business",
|
BUSINESS = "business",
|
||||||
ENTERPRISE = "enterprise",
|
ENTERPRISE = "enterprise",
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ export enum QuotaType {
|
||||||
export enum StaticQuotaName {
|
export enum StaticQuotaName {
|
||||||
ROWS = "rows",
|
ROWS = "rows",
|
||||||
APPS = "apps",
|
APPS = "apps",
|
||||||
|
USER_GROUPS = "userGroups",
|
||||||
|
PLUGINS = "plugins",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MonthlyQuotaName {
|
export enum MonthlyQuotaName {
|
||||||
|
@ -22,7 +24,6 @@ export enum MonthlyQuotaName {
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ConstantQuotaName {
|
export enum ConstantQuotaName {
|
||||||
QUERY_TIMEOUT_SECONDS = "queryTimeoutSeconds",
|
|
||||||
AUTOMATION_LOG_RETENTION_DAYS = "automationLogRetentionDays",
|
AUTOMATION_LOG_RETENTION_DAYS = "automationLogRetentionDays",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ export const isConstantQuota = (
|
||||||
export type PlanQuotas = {
|
export type PlanQuotas = {
|
||||||
[PlanType.FREE]: Quotas
|
[PlanType.FREE]: Quotas
|
||||||
[PlanType.PRO]: Quotas
|
[PlanType.PRO]: Quotas
|
||||||
|
[PlanType.TEAM]: Quotas
|
||||||
[PlanType.BUSINESS]: Quotas
|
[PlanType.BUSINESS]: Quotas
|
||||||
[PlanType.ENTERPRISE]: Quotas
|
[PlanType.ENTERPRISE]: Quotas
|
||||||
}
|
}
|
||||||
|
@ -68,10 +70,11 @@ export type Quotas = {
|
||||||
[QuotaUsageType.STATIC]: {
|
[QuotaUsageType.STATIC]: {
|
||||||
[StaticQuotaName.ROWS]: Quota
|
[StaticQuotaName.ROWS]: Quota
|
||||||
[StaticQuotaName.APPS]: Quota
|
[StaticQuotaName.APPS]: Quota
|
||||||
|
[StaticQuotaName.USER_GROUPS]: Quota
|
||||||
|
[StaticQuotaName.PLUGINS]: Quota
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[QuotaType.CONSTANT]: {
|
[QuotaType.CONSTANT]: {
|
||||||
[ConstantQuotaName.QUERY_TIMEOUT_SECONDS]: Quota
|
|
||||||
[ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: Quota
|
[ConstantQuotaName.AUTOMATION_LOG_RETENTION_DAYS]: Quota
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue