Skip to content

Releases: labring/laf

v1.0.0-beta.14

19 Dec 07:20
Compare
Choose a tag to compare

Security Upgrades

CVE Fixed: https://nvd.nist.gov/vuln/detail/CVE-2023-48225

@see GHSA-hv2g-gxx4-fwxp

⚠️ All private deployments should update to the latest version of laf to fix this CVE.

Updates

Simple cloud storage API

import cloud from '@lafjs/cloud'

export default async function (ctx: FunctionContext) {

  // get bucket
  const bucket = cloud.storage.bucket('cloud-bin')

  // create file
  await bucket.writeFile('test.html', 'hello, laf', { ContentType: 'text/html' })

  // read file
  const res = await bucket.readFile('test.html')
  console.log(await res.Body.transformToString())

  // list files
  const result = await bucket.listFiles()
  console.log(result.Contents)

  // delete file
  await bucket.deleteFile('test.html')

  return { data: 'hi, laf' }
}

Support npm packages caching

The newly added support for node modules caching includes:

  • The npm dependencies added by the application are automatically packaged and cached in the cloud-bin bucket. (node_modules.tar)
  • This effectively improves the speed of application startup.
  • A cloud-bin bucket is automatically created when the application starts.

Support offline dependencies installation mode (runtime)

To support offline dependencies installation mode:

  • Add LF_NODE_MODULES_CACHE=always environment variable to your application
  • Upload your node_modules.tar to {appid}-cloud-bin bucket manually

Then the runtime would skip npm install command, and use node_modules.tar instead.

Seperate the custom npm packages from built-in's

You can add npm packages which has different version with built-in packages in runtime.

Logging & monitor optimization and some bug fixes

  • Upgrade node 18 to node 20 of runtime
  • Fix ObjectId problem in laf web database management

check the change logs.

What's Changed

  • fix(web): fix app monitor longest array by @newfish-cmyk in #1682
  • chore(server): update default resource request of runtime pod by @maslow in #1686
  • fix(runtime): upgrade node to v20 to fix importModuleDynamic bug by @maslow in #1687
  • fix(runtime): object check by @bestlyg in #1684
  • fix(server): add field whitelist for validation by @0fatal in #1692
  • chore: harmonise lint configuration by @0fatal in #1688
  • chore: lint the remaining codes by @0fatal in #1693
  • chore: update readme wechat link by @newfish-cmyk in #1700
  • feat(server): Add a consolidated multi-pod, multi-container log query by @HUAHUAI23 in #1689
  • feat(web): support consolidated multi-pod, multi-container log query by @newfish-cmyk in #1691
  • feat(server): support request-limit ratio conf of runtime resource in region by @maslow in #1702
  • chore(build): update github workflows to build images for pr events by @maslow in #1705
  • chore: fix workflow pr check error by @maslow in #1706
  • fix(runtime): fix module.exports error; fix logs error while response.chunkedEncoding is true by @maslow in #1707
  • fix(runtime): fix process.env hot reload by @maslow in #1709
  • feat(runtime): detach custom dependency, support node_module caching by @skyoct in #1658
  • fix(runtime): fix cloud sdk cannot initialize in custom deps module by @maslow in #1711
  • feat(runtime): support relative path import of fn by @maslow in #1712
  • fix(web): function return shows when not undefined & update current function after edit name by @newfish-cmyk in #1713
  • doc: sync features with beta 13 updates by @nightwhite in #1678
  • doc: delete expired content by @nightwhite in #1716
  • fix(server): fix get_client_ip method, use x-forwarded-fro first by @maslow in #1717
  • doc: deprecated the interceptor fn without next method by @maslow in #1720
  • chore(runtime): update cloud sdk version in runtime by @maslow in #1721
  • fix(web): cannot update database record with ObjectId #1524 by @maslow in #1723
  • fix(server): fix runtime logging interface not authenticated by @HUAHUAI23 in #1725
  • feat(cli): cli support env by @skyoct in #1718
  • fix(server): Fix logging interface error return by @HUAHUAI23 in #1727
  • feat(runtime): add cloud.storage api in cloud sdk by @maslow in #1729
  • feat(cloud-sdk): add url api to cloud sdk by @maslow in #1732
  • fix(web): jsonviewer support to render large data by @newfish-cmyk in #1731
  • doc: opt db-ql documents by @yenche123 in #1726
  • fix(services): Changing exporter penalty rules by @HUAHUAI23 in #1733
  • refactor(cloud-sdk): refacct readFile returns in cloud-sdk by @maslow in #1734
  • refactor(cloud-sdk): refactor listFiles paramsof cloud sdk by @maslow in #1735
  • refactor(db-proxy): refactor accessor constructor in database-proxy, add objectid type as global in runtime; by @maslow in #1738
  • feat(runtime): support LF_NODE_MODULES_CACHE to control if offline deps installation by @maslow in #1743
  • fix(cli): fix cli env command description by @skyoct in #1742
  • chore(web): fix styles & optimize tips & add running cancel by @newfish-cmyk in #1740
  • chore(ci): add digest for images of the pr by @0fatal in #1736

New Contributors

Full Changelog: v1.0.0-beta.13...v1.0.0-beta.14

Migration Guides

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.14

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.14

Update sys_db.Runtime to upgrade runtime images in MongoDb

use sys_db
// runtime version
const version = "1.0.0-beta.14"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()

v1.0.0-beta.13

10 Nov 12:15
Compare
Choose a tag to compare

Intro

Performance Enhanced

In this version, we have restructured the cloud function runtime, enhancing the execution performance of cloud functions by over 400%, HTTP request QPS by more than 300% (with CPU usage savings of over 200% under the same concurrency), and Websocket long connection performance by over 500%.

New logger implementent of runtime

Additionally, we have restructured the function log implementation, now directly using Runtime Pod log streams, which supports real-time log viewing and beautification of log formats.

New billing & monitoring implement of application

We have also rewritten application resource monitoring and metered billing, enabling laf in the sealos user namespace to support resource monitoring and metered billing functions.

What's Changed

Full Changelog: v1.0.0-beta.12...v1.0.0-beta.13

Migration Guides

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.13

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.13

Update sys_db.Runtime to upgrade runtime images in MongoDb

use sys_db
// runtime version
const version = "1.0.0-beta.13"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()

Restart all Running applications by update sys_db.Application in MongoDb

use sys_db
db.Application.updateMany({ state: 'Running' }, {
    $set: {
        state: 'Restarting'
    }
})

Enabling Resource Monitoring

This version of Laf uses a specialized runtime exporter for runtime resource metrics collection, so you will need to install the runtime exporter into the cluster to enable resource monitoring

kubectl apply  --namespace=laf-system  -f  - <<EOF
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
  name: runtime-exporter
spec:
  ports:
    - name: http
      port: 2342
      protocol: TCP
      targetPort: http
  selector:
    app.kubernetes.io/name: runtime-exporter
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
  name: runtime-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: runtime-exporter
  template:
    metadata:
      labels:
        app.kubernetes.io/name: runtime-exporter
    spec:
      automountServiceAccountToken: true
      serviceAccountName: laf-server # It's the same as the laf server's sa.
      securityContext: {}
      containers:
        - image: docker.io/lafyun/runtime-exporter:latest
          imagePullPolicy: Always
          name: runtime-exporter
          ports:
            - name: http
              containerPort: 2342
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /healthz
              port: http
          readinessProbe:
            httpGet:
              path: /healthz
              port: http
          env:
            - name: API_SECRET
              value: "fafafafa"
            - name: NAMESPACE
              value: "laf-system" # Depends on the namespace of the runtime.
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
    release: prometheus
  name: runtime-exporter
spec:
  endpoints:
    - interval: 60s
      path: "/runtime/metrics/fafafafa"    # fafafafa is consistent with the runtime exporter's environment variable API_SECRET
      scrapeTimeout: 10s
      honorLabels: true
  namespaceSelector:
    matchNames:
      - laf-system # Depends on the namespace of the runtime exporter.
  selector:
    matchLabels:
      app.kubernetes.io/name: runtime-exporter
---
# Application billing rules
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  labels:
    app.kubernetes.io/name: runtime-exporter
    release: prometheus
  name: prometheus-laf-billing.rules
spec:
  groups:
    - name: prometheus-laf-billing.rules
      interval: 60s
      rules:
        - record: laf:billing:cpu
          expr: max_over_time(sum by (appid) (laf_runtime_cpu_limit{container!=""})[1h:])
        - record: laf:billing:memory
          expr: max_over_time(sum by (appid) (laf_runtime_memory_limit{container!=""})[1h:])
EOF

v1.0.0-beta.12

31 Oct 07:07
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.0.0-beta.11...v1.0.0-beta.12

Migration Guides

Update laf-server & laf-web images:

# upgrade laf SERVER
kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.12

# upgrade laf WEB
kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.12

Update sys_db to upgrade runtime images

// runtime version
const version = "1.0.0-beta.12"
// const version = "1.0.0-beta.12"

const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
		version: version,
    image: {
      main: main_image,
      init: init_image
    }
	}
})

db.Runtime.find().pretty()

Update sys_db.Region if you still use apisix gateway:

Deprecated: apisix gateway is deprecated in laf, will not be supported in future.

use sys_db
db.Region.updateOne({}, {
    $set: {
        namespaceConf: {
            mode: 'appid',
            prefix: '',
            fixed: ''
        },
        'gatewayConf.tls.wildcardCertificateSecretName': null,
        'gatewayConf.driver': 'apisix'
    }
})

Migrate apisix gateway to nginx ingress gateway:

First stop all laf applications by update sys_db:

use sys_db;
db.Application.updateMany({ state: 'Running' }, {
    $set: {
        state: 'Stopped',
        _restart_flag: 'migration-gateway'
    }
})

Waiting for all application stopped.

# stop laf-server
kubectl scale deployment laf-server -n laf-system --replicas=0

# uninstall apisix
helm delete apisix --namespace laf-system

sealos run docker.io/labring/ingress-nginx:v1.8.1 \
      -e HELM_OPTS="-n ingress-nginx --set controller.hostNetwork=true --set controller.kind=DaemonSet --set controller.service.enabled=false"

kubectl create namespace laf-runtime
use sys_db
db.Region.updateOne({}, {
    $set: {
        namespaceConf: {
            mode: 'fixed',
            prefix: '',
            fixed: 'laf-runtime'
        },
        'gatewayConf.tls.wildcardCertificateSecretName': '',
        'gatewayConf.driver': 'nginx'
    }
})
# start laf-s...
Read more

v1.0.0-beta.11

12 Sep 11:04
Compare
Choose a tag to compare

What's Changed

Read more

v1.0.0-beta.10

12 Jul 08:44
Compare
Choose a tag to compare

What's Changed

Read more

v1.0.0-beta.9

07 Jun 09:51
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.0.0-beta.8...v1.0.0-beta.9

Key Points

  • laf has implemented a new measuring and billing mechanism. #1187
  • remove prisma in laf server
  • support history mode route in websitehosting
  • support multiple-level url for cloud function
  • add laf ai polit

Migration Guides

Upgrade the server and web image version:

run this in your master node to upgrade laf-server & laf-web

kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.9

kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.9

To support new billing mechanism, you should add a new field to Application collection in system database.

run this in your mongodb shell.

use sys_db;
db.Application.updateMany({}, {
    $set: { 
        billingLockedAt: new Date('1970-01-01T00:00:00.000Z')
    }
})

To support multi-level url path in cloud function:

run this in your mongodb shell to upgrade runtime version

 use sys_db;

// runtime version
const version = "1.0.0-beta.9"
const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node-init:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()

Add new environment to laf-server deployments:

kubectl edit deployment/laf-server -n laf-system
env:
    - name: METERING_DATABASE_URL
     value: >-
         mongodb://your-root-user:your-password@mongo-cluster-rs0-0.mongo-cluster-rs0.default.svc.cluster.local:27017/sealos-resources?authSource=admin&replicaSet=rs0&w=majority

v1.0.0-beta.8

12 May 10:06
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.0.0-beta.7...v1.0.0-beta.8

v1.0.0-beta.7

25 Apr 10:05
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v1.0.0-beta.6...v1.0.0-beta.7

Upgrade Guide

run this in your master node to upgrade laf-server & laf-web

kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.7

kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.7

run this in your mongodb shell to upgrade runtime version

use sys_db;

// runtime version
const version = "1.0.0-beta.7"
const main_image = `docker.io/lafyun/runtime-node:${version}`
const init_image = `docker.io/lafyun/runtime-node-init:${version}`

db.Runtime.updateOne({ latest: true }, {
  $set: {
    version: version,
    image: {
      main: main_image,
      init: init_image
    }
  }
})

db.Runtime.find().pretty()
``

v1.0.0-beta.6

11 Apr 05:21
Compare
Choose a tag to compare

What's Changed

  • chore(deploy): remove casdoor charts by @maslow in #954
  • feat(server): support website custom domain ssl cert auto-gen by @maslow in #956
  • fix(server): fixed the error of repeatedly deleting website routes by @maslow in #957
  • feat(server): add check if password had binded by @sulnong in #951
  • refactor(web): optimize the tag selection by @LeezQ in #955
  • feat: fix login bg && add welcome text by @walle233 in #941
  • doc: add db query by @zuoFeng59556 in #958
  • fix(server): add website count limit, opt website task by @maslow in #959
  • fix(deploy): upgrade minio version to fix CVE-2023-28432 by @maslow in #960
  • fix(web): add types for ctx.request by @maslow in #963
  • fix(server): error on deleting cronjob; app stucked in starting by @maslow in #964
  • fix(server): fixed illegal removal of unowned trigger by @maslow in #965
  • feat(web): reset password by @walle233 in #974
  • doc: add website hosting and laf-cli by @zuoFeng59556 in #972
  • fix(server): rm minio alias init in boot, fix multi region limit; by @maslow in #976
  • feat(web): generate function code with AI prompt by @LeezQ in #978
  • fix(web): remove withCredentials by @LeezQ in #979
  • fix(server): cancel namespace removal while stopping app by @maslow in #980
  • fix(server): bucket deletion didn't remove related website by @maslow in #983
  • feat(server): add notes field to region,bundle,pay,auth by @maslow in #986
  • fix(server): fix tasks state handler logic by @maslow in #987
  • fix(server): fix instance task error by @maslow in #988
  • style(web): Responsive styles for home page by @yuedanlabs in #985
  • fix(server): add existing check in creating phase of tasks by @maslow in #990
  • refactor(web): sort tailwind css classname by @LeezQ in #989
  • doc: fix laf-cli and add websocket doc by @zuoFeng59556 in #991
  • feat(web): add bundle note messages by @LeezQ in #992
  • fix(server): return notes fields in region & bundles by @maslow in #993
  • fix: phone register(web) by @walle233 in #994
  • fix(web): fixed the path issue when clicking pathlink(#995) by @RicardoErii in #996
  • fix(server): check site deleting state in site creation by @maslow in #997
  • feat(web): add region info on logo by @LeezQ in #1001
  • feat(web): format code on save by @LeezQ in #1002
  • doc: update image and add cli-mind websocket laf client sdk by @zuoFeng59556 in #1004
  • fix: fix app url protocol error & update default url by @skyoct in #1006
  • feat: feat app list display by @skyoct in #1007
  • chore(deploy): optimize install-on-linux.sh by @bxy4543 in #1010
  • fix(web): appid confict if open 2 tabs by @LeezQ in #1011
  • feat(server): add account transaction by @maslow in #1014
  • chore: sealos does not support pulling multiple cluster images by @bxy4543 in #1016
  • feat(runtime): impl cloud function import and cache function by @skyoct in #1005
  • fix(server): check website hosting in bucket deletion, add error handle to tasks; by @maslow in #1017

New Contributors

Full Changelog: v1.0.0-beta.5...v1.0.0-beta.6

Upgrade Guide

kubectl set image deployments/laf-server -n laf-system \
	laf-server=docker.io/lafyun/laf-server:1.0.0-beta.6

kubectl set image deployments/laf-web -n laf-system \
	laf-web=docker.io/lafyun/laf-web:1.0.0-beta.6

! Urgent Security Upgrade

It is crucial to update your Minio version to RELEASE.2023-03-22T06-36-24Z in order to address the critical vulnerability CVE-2023-28432

New Configurations

To support auto-ssl-cert for website hosting, run this in your master node

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: laf-issuer
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your_email@yourmail.domain
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: apisix
EOF

v1.0.0-beta.5

22 Mar 18:05
Compare
Choose a tag to compare

What's Changed

  • fix(cli): fix axios config by @skyoct in #881
  • fix(web): fix MoreButton tooltip and npm package deletion confirm tip by @genie88 in #879
  • feat(cli): cli invoke function support parameters (#842) by @genie88 in #884
  • fix(cli): remove private npm mirror and replace AxiosRequestConfig to any by @skyoct in #886
  • feat(cli): init app support sync data by @skyoct in #895
  • feat(cli): rename name.meta.yaml to name.yaml by @skyoct in #893
  • fix(cli): fix publish package ignore file by @skyoct in #899
  • feat(web): add dark mode support (#891) by @genie88 in #900
  • fix(README): add chatGPT example by @zuoFeng59556 in #902
  • feat(subscription): impl subscription and account by @maslow in #894
  • feat(web): add subscription and wechat pay by @LeezQ in #904
  • feat(docs): add quick start todo by @zuoFeng59556 in #907
  • fix(server): add max renewal time in bundle; fix subscription price by @maslow in #908
  • doc: fix login example by @zuoFeng59556 in #911
  • chore(server): add sub field to find app api by @maslow in #913
  • refactor subscription dialog experience by @LeezQ in #914
  • fix(web): fix some dark mode ui bugs by @genie88 in #919
  • feat(cli): upgrade s3 sdk version by @skyoct in #922
  • refactor(web): upgrade icon by @LeezQ in #915
  • fix(server): fix bucket name regex by @maslow in #924
  • feat(server): add limit to update app state depends on subscription state by @maslow in #925
  • chore: remove contrib docs of laf web by @maslow in #927
  • feat(server): new authentication implements by @sulnong in #897
  • feat(web): impl new signup & signin method by @walle233 in #910
  • fix(server): change password signup phone filed to optional by @sulnong in #934
  • fix: web signup phone err by @walle233 in #935
  • fix: auth i18n english too long by @walle233 in #936
  • fix(server): fix init auth provider params by @maslow in #937
  • fix: sign up provider err by @walle233 in #938
  • doc: add cli README.md by @skyoct in #921
  • fix(server): deal with existed app without namespace by @maslow in #943
  • fix(web): update data use merge mode by @LeezQ in #940
  • fix(server): add regex for environment name by @maslow in #944
  • fix(server): stuck-starting instance blocked the task handler by @maslow in #945
  • doc: add function param and data query by @zuoFeng59556 in #948
  • refactor(web): updrage npm dependencies by @LeezQ in #950

New Contributors

Full Changelog: v1.0.0-beta.4...v1.0.0-beta.5

Migration points

Update Key Points

  • Add and adjust bundle fields
  • Subscription module
  • Account module
  • WeChat payment service
  • Improve multiple-region support

Breaks Changes

  1. Database: Bundle schema changes

    1. add limitCountPerUser field
    2. remove resource.limitCountPerUser field
    3. add subscriptionOptions field
    4. add resource.reservedTimeAfterExpired field
    5. add maxRenewalTime field
    6. remove specialPrice and price field
    • Operations

      db.Bundle.updateMany({}, {
      	$set: {
      		limitCountPerUser: 1,
      		maxRenewalTime: 3888000,
      		subscriptionOptions: [
      	    {
      	      "name": "monthly",
      	      "displayName": "1 Month",
      	      "duration": 2678400,
      	      "price": 0,
      	      "specialPrice": 0
      	    }
      		],
      		"resource.reservedTimeAfterExpired": 2678400
        }
      })
  2. Database: ApplicationBundle schema changes

    1. remove resource.limitCountPerUser field
    2. add resource.reservedTimeAfterExpired field
    3. add bundleId field
    • Operations

      db.ApplicationBundle.updateMany({}, {
      	$set: {
      		"resource.reservedTimeAfterExpired": 2678400,
          bundleId: new ObjectId("6405ffe6103ead6d468b1a17"),
      	}
      })
  3. Database: Region schema changes

    1. add storageConf.controlEndpoint field
    2. add databaseConf.controlConnectionUri field
  4. API: remove POST /v1/applications

    1. use POST /v1/subscriptions instead
  5. API: remove DELETE /v1/applications/:appid

    1. use DELETE v1/subscriptions instead
  6. Database: Add Subscriptions for existed applications

    1. expiredAt set to 1 month in future
    • Operations

      // write cloud function to insert subscriptions
      import cloud from '@lafjs/cloud'
      import { MongoClient, ObjectId, Db } from 'mongodb'
      
      const sys_db_uri = cloud.env.SYS_DB_URI
      // set your existed bundle id
      const bundleId = new ObjectId('6407200ca35fb4d684296d5c')
      
      export async function main(ctx: FunctionContext) {
        const client = new MongoClient(sys_db_uri)
        await client.connect()
      
        const db = client.db('sys_db')
      
        const apps = await db.collection('Application')
          .find()
          .toArray()
      
        for(let app of apps) {
          const res = await addSubscription(db, app, bundleId)
          console.log(app.appid, res)
        }
      
        return { data: 'hi, laf' }
      }
      
      async function addSubscription(db: Db, app: any, bundleId: ObjectId) {
        const sub = {
          "bundleId": bundleId,
          "appid": app.appid,
          "state": "Created",
          "phase": "Valid",
          "renewalPlan": "Manual",
          "expiredAt": new Date('2023-12-31T00:00:00.733Z'),
          "lockedAt": new Date('1970-01-01T00:00:00.000Z'),
          "createdAt": new Date(),
          "updatedAt": new Date(),
          "createdBy": app.createdBy,
          "input": {
            "name": app.name,
            "state": app.state,
            "regionId": app.regionId,
            "runtimeId": app.runtimeId
          }
        }
      
        return await db.collection('Subscription').insertOne(sub)
      }

New Configrations

Config phone auth provider

db.AuthProvider.updateOne({ name: "phone" }, {
	$set: {
           state: "Enabled",
          "config.alisms": {
	    "accessKeyId": "",
	    "accessKeySecret": "",
	    "api_entrypoint": "https://dysmsapi.aliyuncs.com",
	    "signName": "",
	    "templateCode": "SMS_000004"
	  }
      }
})

Add Wechat payment channel

// db.PaymentChannel.find().pretty()

db.PaymentChannel.insertOne({
  type: "WeChat",
  name: "WeChat Pay",
  spec: {
	  mchid: "",
           appid: "",
           apiV3Key: "",
           certificateSerialNumber: "",
          privateKey: "-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----",
          publicKey: "----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----"
  },
  state: "Active",
  createdAt: new Date(),
  updatedAt: new Date()
})