Skip to content

Commit

Permalink
Added docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
shrihari-prakash committed Sep 10, 2024
1 parent 11936b4 commit d8ca411
Show file tree
Hide file tree
Showing 27 changed files with 19,394 additions and 0 deletions.
20 changes: 20 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Dependencies
/node_modules

# Production
/build

# Generated files
.docusaurus
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
41 changes: 41 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Website

This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.

### Installation

```
$ yarn
```

### Local Development

```
$ yarn start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ yarn build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

Using SSH:

```
$ USE_SSH=true yarn deploy
```

Not using SSH:

```
$ GIT_USER=<Your GitHub username> yarn deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
3 changes: 3 additions & 0 deletions docs/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
20 changes: 20 additions & 0 deletions docs/docs/Debugging-Common-Errors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Debugging Common Errors
---

This page will be updated with most common errors people encounter while setting up Liquid.

### `Server error: handle() did not return a user object` error when redirecting back to your application:

![Screenshot 2024-08-27 at 14 43 46](img/server-handle-did-not-return-a-user-object.png)

This most commonly indicates a cookie problem. The login is typically successful in these cases, but the cookie that came with the login API response was either not transmitted to or were not set by the browser.

When this happens, the following configuration might be wrong:
1. You set `cookie.secure=false` on a https server.
2. You set `cookie.secure=true` on an insecure server.
3. Your reverse proxy (like nginx in front of Liquid) is not forwarding the cookie headers set by Liquid. Read [this section](/Making-Liquid-Production-Ready#special-configurations-for-nginx-reverse-proxy) to know how to setup reverse proxies.
4. `cookie.domain` was setup for the wrong domain / sub domain.

### `Invalid client: redirect_uri does not match client value` error when redirecting back to your application:
Redirect URI does not exactly match the URI setup in the `redirect_uri` field in the clients collection. You can also setup this field on Nitrogen.
237 changes: 237 additions & 0 deletions docs/docs/Intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
---
title: Intro
---

# Liquid
## Seamless and highly customizable authentication and user management server for any project. ✨

Liquid is a Docker-based open-source authentication server that supercharges your product development by offering out of the box APIs for features like follow-unfollow, blocking, and banning so that you can focus on just your application logic. 🚀

![](https://github.com/shrihari-prakash/liquid/raw/main/images/liquid-banner.png)

Think of Liquid like integrating a readymade authentication and user management server with your own codebase. You just boot up Liquid in a docker container with a few configuration files and it is all good to go.

# Quick Start

:::danger

**You should NEVER use the Quickstart for production deployments. For production usage, please read this page further and after the first time setup, and then refer to the [Production Guide](/Making-Liquid-Production-Ready) to make your instance production ready.**

:::

If you're looking for the quickest and most convenient way to run Liquid without installing manually the dependencies for database and cache by yourself, do the following:

1. Run
```shell
curl -sSL --insecure https://raw.githubusercontent.com/shrihari-prakash/liquid/main/quickstart/docker-compose.yaml > docker-compose.yaml
curl -sSL --insecure https://raw.githubusercontent.com/shrihari-prakash/liquid/main/quickstart/app-config.service.json > app-config.service.json
curl -sSL --insecure https://raw.githubusercontent.com/shrihari-prakash/liquid/main/quickstart/app-config.static.json > app-config.static.json
```
2. In the `app-config.service.json` file, add your frontend origin in `cors.allowed-origins` array.
3. Run `docker-compose up -d`.

This is useful if you want to try and evaluate Liquid to see if it fits your needs or to locally develop your apps with Liquid.

## Connecting Your Frontend Application to Liquid Quickstart Instance
For Liquid to securely allow your frontend to authenticate, you will need to update your frontend domain in a few places:

### Nitrogen Configuration
1. Login to the [Nitrogen admin panel](http://localhost:2001).
2. Navigate to the `Applications` tab.
3. Click the Edit button.
4. In the redirect URIs section, add your frontend origin.
5. Press Enter.
6. Click Save.

### Test connectivity
1. Navigate to http://localhost:2000?redirect_uri=https://your-frontend.origin
2. Enter the login details and click on Login.
3. You are now navigated back to your application with the state and code parameters in the URL.
4. Refer to [this section](/api-documentation/API-Documentation-OAuth-2.0#access-token-from-authorization-code) to see how to get an access token from the code in URL to call Liquid APIs.

The Quickstart script by default runs in "Demo Mode", which means, an application and a user is already created for you so that you can jump straight into evaluating Liquid with zero configuration. The script also comes with the [Nitrogen admin panel](https://github.com/shrihari-prakash/nitrogen) preconfigured. You can manage users and permissions by navigating to http://localhost:2001.

## Demo user
**Username:** liquid_demo

**Password:** liquid_demo

## Connecting Your Backend Service to Liquid Quickstart Instance
Refer to [this section](/Understanding-Access-Control-and-Integrating-with-Other-Microservices) to find out how to authenticate users connecting to your service using Liquid.

# Production Setup
## Before you start

There are a few dependencies for Liquid to run as intented.

First of all, you need **MongoDB** and **Redis** instances running. Redis is not absolutely required, but it is highly recommended that you have it. You can disable Redis by disabling the option `privilege.can-use-cache`, but again, it is not recommended.

Secondly, you need a **SendGrid** account, because this is how Liquid sends emails to verify user accounts and reset account passwords. If you do not have a SendGrid account right away, you can disable SendGrid usage by disabling the following options: `user.account-creation.require-email-verification` (backend & frontend), `privilege.can-reset-password` (frontend). As you might have noticed, this will bypass email verifications when users are signing up and will also disable the forgot password button. Disabling these can be useful for development purposes.

## Full list of dependencies

Almost everything is **optional** except MongoDB.

| Dependency | Optional | Used by Default | Related Options | Disable Recommended? |
| --------------------------- | -------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| MongoDB | No | Yes | mongo-db.connection-string | No |
| Redis | Yes | Yes | privilege.can-use-cache, redis.\* | No |
| SendGrid | Yes | Yes | user.account-creation.require-email-verification (backend & frontend), privilege.can-reset-password (frontend), sendgrid.\* | No |
| AWS S3 (or) S3 like storage | Yes | No | privilege.can-use-profile-picture-apis, s3.\* | Yes |
| RabbitMQ | Yes | No | privilege.can-use-push-events, privilege.can-use-rabbitmq, rabbitmq.\* | Yes |

## The basics

There are a few configuration files required for liquid to function:

1. **app-config.json**: The frontend configuration file. This controls everything that the user sees in pages like login, signup, etc. Heavily used for cosmetic changes, but also controls enabling and disabling certain features shown in forms.
2. **.env**: The backend configuration file. This is the file where all your important liquid configurations and secrets are stored. Like MongoDB URL, Redis credentials, what features to enable in the system, etc.
3. **scope-extensions.json**: The scopes file (Optional). OAuth systems usually determine if a user is allowed to access an API by checking if they have access to the scope associated with the API. More about this later.

:::note

Changing Backend options (`app-config.service.json` / `.env` file passed to Liquid) requires a restart of the service. Changing Frontend options instantly reflect when you refresh static pages.

:::

## Editing Liquid configurations

### Backend

All the available backend options are listed in [this file](https://github.com/shrihari-prakash/liquid/blob/main/src/service/configuration/options.json).

To configure options, create a file named `app-config.service.json`. Now copy the `name` field of the option you want to configure to the JSON file and set the intended value.

Here's a sample `app-config.service.json` file for a very minimal Liquid setup:

```json
{
"environment": "development",
"cookie.secure": true,
"cors.allowed-origins": ["http://localhost:2001", "https://your.frontend.origin"],
"mongo-db.connection-string": "mongodb://localhost:27017/liquid",
"redis.port": 6379,
"redis.host": "127.0.0.1",
"redis.db": 0,
"system.app-name": "Liquid",
"system.static.app-config-file-path": "/environment/app-config.static.json",
"privilege.can-reset-password": false,
"user.account-creation.require-email-verification": false,
"system.email-adapter": "print",
"system.rate-limit.light-api-max-limit": 100000000,
"system.rate-limit.medium-api-max-limit": 100000000,
"system.rate-limit.heavy-api-max-limit": 100000000,
"system.rate-limit.extreme-api-max-limit": 100000000,
"system.demo-mode": true
}

```

### Frontend

All the available options are listed in [this file](https://github.com/shrihari-prakash/liquid/blob/main/src/public/configuration/options.json).

When you want to configure an option, you would copy the `name` field of the option and set it in app-config.static.json.

Here's a sample `app-config.static.json` file:

```json
{
"oauth.client-id": "application_client",
"oauth.redirect-uri": "{{your-default-oauth-redirect-uri}}",
"content.app-name": "My App",
"content.app-tagline": "My App Tagline."
}
```

## Installation

Now that we have our configuration files ready, let's boot up liquid with them.

1. Pull the docker image by using command `docker pull shrihariprakash/liquid`.
2. Create a collection in your database named `clients` and insert the following document into the collection (Make sure you edit the frontend URIs and secret in the document below):

```json
{
"id": "application_client",
"grants": ["client_credentials", "authorization_code", "refresh_token"],
"redirectUris": [
"{{frontend-redirect-uri-1}}",
"{{frontend-redirect-uri-2}}"
],
"secret": "super-secure-client-secret",
"role": "internal_client",
"scope": ["*"],
"displayName": "Application Client"
}
```

3. Update properties `oauth.client-id` and `oauth.redirect-uri` in your `app-config.json` to values from the document you just inserted into `clients` collection. Feel free to explore other options related to UI customizations.
4. Have your backend configurations ready in the file **`.env`** (preferably put it on the same folder as your app-config.json).
5. Now open terminal in the folder that contains your `app-config.json` and `.env`.
6. If you are on Windows, run:

```bash
docker run -p 2000:2000 -v "%cd%":/environment --env "SYSTEM_SERVICE_APP_CONFIG_FILE_PATH=/environment/app-config.service.json" --name liquid -itd shrihariprakash/liquid:latest
```

7. If you are on Linux, run

```bash
docker run -p 2000:2000 -v "$(pwd)":/environment --env "SYSTEM_SERVICE_APP_CONFIG_FILE_PATH=/environment/app-config.service.json" --name liquid -itd shrihariprakash/liquid:latest
```

8. Alternatively, you can use docker compose for easy restarts:

```yaml
version: "3"
services:
liquid:
image: shrihariprakash/liquid:latest
container_name: liquid
ports:
- "2000:2000"
volumes:
- .:/environment # Replace . with the folder that contains app-config.json and .env
env_file:
- .env
```
9. All done ✨, navigating to `host-machine:2000` should render login page. All the APIs are ready to be called from your other services. If the rest of your project is running on Node, you can use the [Liquid Node Connector](https://www.npmjs.com/package/liquid-node-connector) to authenticate users connecting to your service and also to get client tokens to interact with Liquid client APIs. [Click here for Swagger](https://shrihari-prakash.github.io/liquid-docs). Also see Sign Up and Login section in the bottom of this document to find how to handle redirects from your app for authentication.
10. As a general best practice, whenever you launch Liquid, always look for any warnings in the logs. This can help you catch misconfigurations very early before your users notice them.

## First time setup

Now we have our liquid instance running. That's fantastic! There's just one more thing to do. Assign someone as the system administrator. Liquid needs a super admin for the system that can provide access to all other users in the system. To do this, create an account on Liquid by doing the following:

1. Visit `/signup` and fill the details.
2. Click on Create Account.
3. If you have email verifications enabled, a code is sent to your email. Enter this code on the verification page. If you have verifications disabled, you are redirected to the login page. **DO NOT LOGIN YET!**.

Once you sign up for an account, you would need to make yourself super admin by editing the database entry for your account. This is the last time you will touch the database manually. Run the following commands in your MongoDB instance:

```bash
use liquid
db.users.updateOne( { username: "your_username" },
{
$set: {
role: "super_admin",
scope: ["*"]
}
})
```

This would give you full access to the system.

### Login

1. To authenticate with liquid, redirect to `/login?redirect={{your_target_uri}}&theme={{light | dark}}` from your app (or you could just visit the login URL) and enter your credentials. Note that the value of redirect parameter must be one of the values configured in `redirectUris` of Setup(2).
2. If the credentials are correct, the application redirects the control to the url specified in `redirect` parameter with the state and authorization code.
3. In your application logic, you can use this code in exchange for an access and refresh token using the `authorization_code` grant.

## To make Liquid production ready, continue to the [Production Guide](/Making-Liquid-Production-Ready)

## API Documentation

Get started with the APIs [here](/api-documentation/API-Documentation-OAuth-2.0)
67 changes: 67 additions & 0 deletions docs/docs/Making-Liquid-Production-Ready.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Making Liquid Production Ready
---

## Important backend configurations to update

To make Liquid production ready, there are a few recommended configurations to be done on the backend side:

### Cookie Configurations:
* Set ***cookie-session-secret*** to a secure random string. You can use [this tool](https://www.uuidgenerator.net/guid) to generate one.
* Set ***cookie.secure*** to true.

### Core Environmental Configurations:
* Set ***system.reverse-proxy-mode*** to true if you intend to use a reverse proxy like Nginx.
* Set ***environment*** to production.

### Account Creation and Email Adapter Configurations:

* Set ***email.outbound-address*** to the email address that you intend to send emails to users from. It is important that this address matches the email address configured in your mail adapter.
* Set ***user.account-creation.require-email-verification*** to true.
* Set ***privilege.can-reset-password*** to true.

To send outbound emails from Liquid, say, for account verification and password reset, you can either use a Sendgrid account or your own SMTP server by configuring Nodemailer.

#### Using Sendgrid:
* Set ***system.email-adapter*** to ***sendgrid***.
* Set ***sendgrid.api-key*** to your SendGrid API key.

#### Using Nodemailer:
* Set ***system.email-adapter*** to `nodemailer`.
* Set ***nodemailer.service-name*** to `gmail` or `outlook` if you use those services. Do not set if you are using a custom SMTP server.
* Set ***nodemailer.host*** to your SMTP server host.
* Set ***nodemailer.port*** to your SMTP server port.
* Set ***nodemailer.secure*** to true if your SMTP server uses a secure connection.
* Set ***nodemailer.username*** to the username of your SMTP account.
* Set ***nodemailer.password*** to the password of your SMTP account.

### Caching:
* Set ***privilege.can-use-cache*** to true.
* Set ***redis.port***, ***redis.host***, ***redis.username***, ***redis.password***, and ***redis.db***.

### Database:
* Set ***mongo-db.connection-string*** to your MongoDB URL.

## Recommended configurations for MongoDB

In a production setup, we recommend turning on transactions by setting the option `mongo-db.use-transactions` to true. This makes sure API calls with multiple write operations don't result in inconsistent database states if some of them fail and some of them succeed.

## Recommended configurations for account creation

To reduce the amount of spam accounts, Liquid has an IP based user account creation throttling mechanism.

Use the following options to adjust this throttling:
* Set ***user.account-creation.enable-ip-based-throttle*** to `true`.
* The window size for the throttle can be controlled by setting the option ***user.account-creation.ip-based-throttle.window-size*** to the desired number of seconds. For example, if you set ***user.account-creation.ip-based-throttle.window-size*** to 3600, Liquid will allow only one account per hour to be created from the same IP.

## Special Configurations for Nginx Reverse Proxy

It is important that you configure the `headers X-Forwarded-Proto` and `X-Forwarded-For` as follows to ensure that the security features work properly:

```nginx
location / {
# other reverse proxy configurations...
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
}
```
Loading

0 comments on commit d8ca411

Please sign in to comment.