npm package: @mocobaas/server-sdk
Description: Moco Backend-as-a-Service
Author: Hash Rekayasa Teknologi
Latest version: 2.23.2

# MocoBaaS - Server-SDK

[Important Updates](#important-updates)

[Environment Variables](#environment-variables)

## Important Updates

### 2.23.0

- Integration with Kastela

### 2.22.0

- Migration process for database migration from sqlite to text file is removed

### 2.21.20

- Fix: `utils.resolveAssetPath`.
- Fix: unwanted config mutation during redis cache initialization.
- Fix: database transaction on destroy record

### 2.21.12

- The timeout (in seconds) on Mutex locking attempt can be adjusted via `MUTEX_ATTEMPT_TIMEOUT`

### 2.21.10

- RPC across node process is available via `ctx.moco.rpc`. This would be helpful for communicating with any service that only available on master process only.
- All database migrations are tracked on `migrations/data.txt`. Please run the project once on your laptop to ensure data migration from old `db.sqlite`. The migration between sqlite to plain will be removed on 2.22.0.
- Distributed mutex (based on redlock) is currently available via `let myMutex = await ctx.moco.mutex(key,ttl)`. It is also possible to extend ttl via `myMutex = myMutex.extend(newTtl)`. Releasing mutex can be done via `await myMutex.unlock()`.
- Typescript user is now able to add type on custom script context via Generic.

```ts
import SDK from "@mocobaas/server-sdk";
import moment from "moment";

interface IData {
  id: string;
  challenge: string;
  expire: number;
  digest: string;
}

async function handler(ctx: SDK.EventContext<IData>) {
  const mutex = await ctx.moco.mutex(id, 3000);
  const { id, expire, ...others } = ctx.data; // data shall follow IData interface
  await ctx.moco.cache.set(id, { id, ...others }, expire);
  await mutex.unlock();
}

module.exports = handler;
```

### 2.20.12

- Auth: `DENY_CONCURRENT_LOGINS` also accepts a list of user roles, e.g. `DENY_CONCURRENT_LOGINS="Content Creator,Publisher,Reader"`. If user has any of those roles, they won't be able to do concurrent logins.

### 2.20.8

- Auth: Use `DENY_CONCURRENT_LOGINS=1` to deny concurrent logins of a user (like on multiple devices).
- `ctx.moco.utils.revokeAllAccess()`

### 2.20.5

- Google Sign-in: Auto-link existing account on Register.

### 2.20.1

- ⚠️ **Breaking Change:** When anti-tamper is enabled (`NODE_ENV = production` or `FORCE_INTEGRITY_CHECK = 1`), deploy your project with mbaas-signer-cli 1.7.0.

```sh
wget --header="DEPLOY-TOKEN: your-deploy-token" https://gitlab.com/api/v4/projects/24382748/packages/generic/mbaas-signer-cli/1.7.0/mbaas-signer_1.7.0_linux_amd64.tar.gz -O - | tar -xzvf -
```

### 2.19.0

- You may run custom codes during boot process via `boot.js` file. Use `masterEntry` function to execute code once in the master process, and use `workerEntry` function to execute code once in each worker.

### 2.18.0

- Automatic restart MBaaS after disconnected from database. You need to change in main code (server.js) from `require("@mocobaas/server-sdk")();` to `require("@mocobaas/server-sdk/src/eternal")();`

### 2.17.5

- Change default timeout for inter-service communication to 1 minute (60s). You can still customize it by setting `SERVICERPC_TIMEOUT` or `PUBSUBRPC_TIMEOUT` variable.
- Better timeout error message, e.g. "[rpc - fwdcall] Connection timed out @ 1m0s while awaiting reply".

### 2.17.3

- Redis: Support using TLS (e.g. `config.cache.tls = true`).

### 2.17.2

- Fix: Database SSL configuration.

### 2.17.0

⚠️ **Security Fixes:**

- GraphQL Introspection: (1) On `NODE_ENV = production`, it is denied by default. Use `ALLOW_GRAPHQL_INTROSPECTION=1` to allow it. (2) On any other NODE_ENV, it is allowed by default. Use `ALLOW_GRAPHQL_INTROSPECTION=0` to deny it.
- Rate Limit Logger: Logs every time the limit is reached, prefixed with "[TMREQ]". Please set `logging.level` to `info` or above to enable this feature.
- Encryption Failure Logger: Logs every 5 failure attempts within 10 seconds, prefixed with "[E2EEFAIL]". Please set `logging.level` to `info` or above to enable this feature.

🚀 **New Features:**

- Auto Scaling based on Backpressure Metering.

### 2.16.1

- Configurable Check Email API rate limiter (`production` only): (1) You can set `ALLOW_CHECK_EMAIL=true` to enable API with the default limiter, 1 req/min. (2) Or you can use any integer values to enable API with custom limiter, e.g. `ALLOW_CHECK_EMAIL=5000` means 5000 req/min.

### 2.16.0

- ⚠️ **Breaking Change:** On Linux, glibc >= 2.27 is needed (`ldd --version` to check version). We recommend to use this docker image:
  1. `node:12-bullseye`
  2. `node:12-bullseye-slim`
  3. `node:14-bullseye`
  4. `node:14-bullseye-slim`
- Use `PWDCHANGE_AUTO_LOGOUT=1` to logout user on password change.
- If you want to run additional tasks when user change his/her password, use this event trigger: `{ "entity": "auth", "queue": "passwordChanged" }`.
- Fix: `ctx.moco.mqtt` typings.
- Fix: Some `ctx.moco` methods were unavailable on non-HTTP custom scripts.

### 2.15.13

- Fix: Payload character encoding.

### 2.15.0

⚠️ **Security Fixes:**

- These APIs will not inform whether the specified email is valid or not: Login (local), Resend Verification, Forgot Password.
- Check Email API is now unavailable by default. Use `ALLOW_CHECK_EMAIL=true` to allow accessing it.
- On `NODE_ENV = production`, Check Email API is guarded by a special rate limiter: 1 request per minute for each IP address.

🚀 **New Features:**

- OpenTelemetry is available for tracing custom scripts via `require("@mocobaas/server-sdk").tracing`.
- Use `initChildSpan` to generate `span` object and `nestedSpanClosure` wrapper.

```js
const { initChildSpan, otel } = require("@mocobaas/server-sdk").tracing;
//
const { span, nestedSpanClosure } = initChildSpan(`[func] function name`, {
  attributes: {
    attr1: "demo",
    // attributes
  },
});
await nestedSpanClosure(async () => {
  try {
    await doSomething();
    span.setStatus({ code: otel.SpanStatusCode.OK });
  } catch (error) {
    span.setStatus({
      code: otel.SpanStatusCode.ERROR,
      message: error.message,
    });
  } finally {
    span.end();
  }
});
```

### 2.14.1

- Redis: Support using custom dbid (`config.cache.db`).

### 2.14.0

- ⚠️ **Breaking Change:** When anti-tamper is enabled (`NODE_ENV = production` or `FORCE_INTEGRITY_CHECK = 1`), deploy your project with mbaas-signer-cli 1.4.0.

```sh
wget --header="DEPLOY-TOKEN: your-deploy-token" https://gitlab.com/api/v4/projects/24382748/packages/generic/mbaas-signer-cli/1.4.0/mbaas-signer_1.4.0_linux_amd64.tar.gz -O - | tar -xzvf -
```

### 2.13.6

- Fix: custom script RPC formatting.

### 2.13.5

- Fix: Swagger UI document URL.
- Fix: GraphiQL server URL.
- Fix: Swagger UI & GraphiQL payload encryption server-public-key refetcher.

### 2.13.2

- Fix: `ctx.moco.tables.knex` typings.

### 2.13.0

- OpenTelemetry support for tracing custom scripts execution and database calls.
- Use `OTEL_EXPORTER=console` to export OpenTelemetry via console. Replace `console` with `jaeger:::<jaeger_url>` for Jaeger exporter and `zipkin:::<zipkin_url>` for Zipkin exporter.
- Remove ExpressJS and related codes.
- Memoized function on table & schema metadata check.

### 2.12.3

- Fix: Password verification on invalid stored passwords.

### 2.12.1

- Fix: Database connection error on certain configuration.

### 2.12.0

- Add payload encryption support to Swagger UI.
- Replace GraphQL Playground with GraphiQL, still using the same endpoint: /graphql/playground.
- Add payload encryption support to GraphiQL.

### 2.11.2

- Fix: Do not send verification email on `REGISTRATION_AUTO_VERIVIED = 1`.

### 2.11.0

- Replace Redis Pub/Sub with Redis Stream for better deliverability between services.

### 2.10.14

- Auth: Use `REGISTRATION_AUTO_VERIVIED=1` to set user's verified to `true` on local registration.

### 2.10.12

- Fix: custom script responses.
- Log Viewer: (1) On `NODE_ENV = production`, it is disabled by default. Use `ENABLE_LOG_VIEWER=1` to enable it. (2) On any other NODE_ENV, it is enabled by default. Use `ENABLE_LOG_VIEWER=0` to disable it.

### 2.10.7

- Fix: Set custom script response status based on `returnCtx.status`.
- `ctx.moco.utils.addAccess()`

### 2.10.4

- Fix: Missing storage remove file endpoint.

### 2.10.1

- Fix: Integrity check for anti-tamper not working.
- More on anti-tamper: Use `FORCE_INTEGRITY_CHECK=1` to perform integrity check on any NODE_ENV.

### 2.10.0

- Binary: Use tar.xz compression for smaller download size.

### 2.9.0

- Materialized View Index Management
- Resource Availablity API
- One to One Relationship
- Payload Encryption `["COMMON", "TABLE", "GRAPHQL", "CUSTOM"]`

### 2.8.3

- "GET /api/isready" checks if the customscript module is ready to use. It is used internally by Moco BaaS Test Suite.

### 2.8.0

- Worker management & auto scaling

### 2.7.2

- Redis Pub/Sub "RPC_ERROR" message is now replaced with a detailed message. It uses a prefix: "[redisrpc - fwdrequest]".
- Some examples of Redis Pub/Sub errors: "SERVICE NOT FOUND: customscript", "CONNECTION TIMED OUT", "CONNECTION DROPPED".
- "GET /version" shows project version, server-sdk version and NODE_ENV.
- Fix: `env.vars` for setting environment variables, sourcing from single-file config (exported) or multi-file config (infrastructure).

### 2.6.41

- Custom Script Testing: `require("@mocobaas/server-sdk").testing` includes some testing tools, such as [chai](https://www.npmjs.com/package/chai) and [pactum](https://www.npmjs.com/package/pactum).

### 2.6.0

- Set the timeout for Redis Pub/Sub communication (as mentioned in v2.0.0) by setting `PUBSUBRPC_TIMEOUT` variable (in seconds). Defaults to 10 seconds.

### 2.5.0

- Execute graphql via custom script

### 2.3.0

- Load exported JSON configuration
- Move migrations to SQLite

### 2.2.0

- LogDNA support
- GraphQL api order by relation table

### 2.1.0

- MQTT support
- Sentry support
- Custom Script Caching

### 2.0.0

- Binary: As a part of transitioning into the compiled MBaaS codes, it downloads and runs some executable binaries for your current platform/operating system alongside with the Node.js process. And they all communicate each other via Redis Pub/Sub during Server operation.
- Anti-tamper: On `NODE_ENV = production`, MBaaS will perform an integrity check on custom scripts at boot time. The server will run normally only if the check passed.
- Auth: Uses Argon2 key derivation function when inserting/updating user's password, while still maintaining backward compatibility when verifying existing passwords.
- Auth: When Server starts, you will see a short Argon2 benchmark in your console. For the best balance between security and performance, it is recommended to have between 0.05 and 0.5 seconds hash timing (elapsed). Please set `authResources.argon2MemoryCost` to a certain number until you get a good timing. The result depends on your hardware resources.
- Auth: Implements refresh token protection, similar to that in IDFS (see [v1.41.0](#1410)).
- Auth: To better assist Client on the exact/unambiguous timing for refresh access and relogin user, Server provides these responses: (1) Invalid Access Token = HTTP Status 401 and error code `IVACC` = it is time to refresh access. (2) Invalid Refresh Token = HTTP Status 401 and error code `IVREF` = it is time to relogin user.
- Auth Events: User registration and email verification now trigger auth events, which can be handled by your custom scripts.
- Sign-in with Apple ID (see MocoBaaS Manual for the detailed explanation).
- Keycloak support: Replaces IDFS as the identity provider.
- HTTP Logger: A new module for logging HTTP requests and responses. Please set `logging.level` to `http` or above to enable this module.
- Custom Script: All methods in `ctx.moco.utils` now return Promise.

### 1.51.0

- Materialized View

### 1.50.0

- Auto Increment option for integer and bigInteger column

### 1.49.0

- Use trigger for table event

### 1.48.0

- Typing support on custom scripts for both table and queue operation. This should improves developer productivity.
- Typing for table operations can be activated / updated via console menu.
- Developer will see typing for table name, select, include, data (insert & update), and operation result.
- Typing is only applicable on method with 2 arguments, which first one is the target table name.

### 1.47.0

- Writing Typescript (TS) code is now supported.
- Please follow the [migration guide](https://moco-baas-manual.netlify.app/docs/typescript) for more details on how to work with TS.
- Console will automaticaly generate new TS file if your project folder contains `tsconfig.json`

### 1.43.3

- IDFS: bilingual support: "en" & "id".

### 1.41.6

- Another case-insensitive on checking email. Affected endpoints: "POST /services/auth/account".

### 1.41.0

- IDFS: It is possible that refresh tokens being stolen by malicious actors. To stop any misuse of access, when a refresh token is reused, it will revoke the whole token chain (grant). Meaning that the active refresh token will be invalid and the active access token(s) will also be invalid. The user will have to reauthorize.

### 1.40.0

- Case-insensitive on checking email. Affected endpoints: "POST /services/auth", "DELETE /services/auth", "GET /services/auth/account", "POST /services/emailverification".

### 1.35.0

- Support RS256 JWT algorithm, fallback to HS256 if not configured.
- JWT tokens are only valid to a single environment, i.e. development for development, production for production, etc.

### 1.32.7

- In case of randomly disconnected redis, please apply `REDIS_HEARTBEAT = true` in environment variable

### 1.32.21

- Moco context is available from anywhere via `getContext` method in `require("@mocobaas/server-sdk").utils`
- All methods in `getContext` are valid in exception for `user`

```js
const utils = require("@mocobaas/server-sdk").utils;
const mocoCtx = utils.getContext(); // return null if not configured yet
```

### 1.22.0 - Table

- add GraphQL endpoint for table, endpoint is "/graphql"
- add "GraphQL Playground" for GraphQL IDE, endpoint is "/graphql/playground"

## Environment Variables

| Variable                    | Values                        | Default     | Purpose                                                                          |
| --------------------------- | ----------------------------- | ----------- | -------------------------------------------------------------------------------- |
| NODE_ENV                    | development, production, etc. | development | Application environment, differentiating some configurations.                    |
| REDIS_HEARTBEAT             | true, 1                       |             | Enable Redis heartbeat.                                                          |
| DISABLE_STORAGE_PREFIX      | true, 1                       |             | Use unprefixed storage bucket name.                                              |
| OVERRIDE_STORAGE_PREFIX     | (any string values)           |             | Define custom prefix for storage bucket name.                                    |
| SERVICERPC_TIMEOUT          | 20, 7.5, etc.                 | 60          | Set timeout (in seconds) for Redis inter-service communication.                  |
| PUBSUBRPC_TIMEOUT           | "                             | "           | "                                                                                |
| FORCE_INTEGRITY_CHECK       | true, 1                       |             | Perform integrity check on any NODE_ENV.                                         |
| ENABLE_LOG_VIEWER           | true, false, 1, 0             |             | Enable/Disable Log Viewer (see [v2.10.12](#21012)).                              |
| REGISTRATION_AUTO_VERIVIED  | true, 1                       |             | Set user's verified to `true` on local registration.                             |
| ALLOW_CHECK_EMAIL           | true, (any integer values)    |             | Allow accessing Check Email API (see [v2.16.1](#2161)).                          |
| DENY_CONCURRENT_LOGINS      | true, 1, (list of user roles) |             | Deny concurrent logins of a user.                                                |
| PWDCHANGE_AUTO_LOGOUT       | true, 1                       |             | Logout user on password change.                                                  |
| ALLOW_GRAPHQL_INTROSPECTION | true, false, 1, 0             |             | Allow/Deny GraphQL Introspection (see [v2.17.0](#2170)).                         |
| MUTEX_ATTEMPT_TIMEOUT       | number                        | 10          | Define the timeout (seconds) of mutex locking attempt (available from v2.21.12). |