CAIN Stack template V2

Please read the following doc carefully to avoid any difficulties and misunderstandings.

About

This project is a template to build an offline first web application with authentication, that can be ported easily to other platforms (Android, iOS, Electron). It runs on the CAIN Stack which consists of following technologies:

C ouchDB as remote server database / PouchDB as local database

ouchDB as remote server database / PouchDB as local database A ngular as frontend framework

ngular as frontend framework I onic for cross platform components and capacitor as native api wrapper

onic for cross platform components and capacitor as native api wrapper NestJS as backend framework with Nano for business logic and superlogin for authentication

Features

Complete User authentication with confirm mail, password forget, user roles and more

Admin Panel for editing users

Private and shared database (admins can edit every document in every database)

Fully functional offline and syncing enabled by default

Native Apis like calling network state, camera and filesystem (more can be easily added with capacitor )

Cross Platform

Chat function (beta)

Changelog

New Interface + designated desktop ui

Private Chats, which can even be initiated offline

Img-Upload Component with native Filepicker / Gallery, Camera and Cropper

User profiles with images and bio

Enhanced Api Security

Search Function v0. 1

Skeleton preloading and refresher

Lazyloading Images

Decreased Client Bundle Size by 18%

Client

Frontend framework: Angular, PouchDB as local database, Ionic for cross platform components and capacitor as native api wrapper.

Client-Installation

Requirements: Installed Ionic Cli and NodeJS. Install the client dependencies by cd client and running npm i . Start the client framework by running ionic serve .

Client-Core

Located at client/src/app/core .

Data Service

The heart of the Cain Stack. The initDatabase function gets initiated when the user logs in. It filters the names and remote addresses of the databases the user has access to and builds an object of PouchDB instances. Afterwards it starts the initRemoteSync , which starts the synchronisation of the local with the remote databases. The data service includes many document, attachment and database functions, to be used in your own services (see client/src/app/services ). Visit [pouchdb. com](https://pouchdb.com/api. html) for the full api list.

Auth Service

Querys the superlogin apis and handles the destruction of local databses when logging out. It also checks the locally saved user token and therefore enables offline reauthentication.

User Service

Handles all User Doc related functions, like saving the user data locally, editing profile details and getting profile images.

Chat Service

Handles all chat related functions. Mainly the creation of private Chats, the querying of all user chats and the chat messages of one particular conversation. To avoid any conflicts when creating a new private chat database, the createPrivateChatId function builds a unique conversation Id based on the usernames of the participants. Therefore it is possible to create a chat even when the user is offline.

Client-Shared

Located at client/src/app/shared . Consists of components, helpers, modals and services. These can be used in your own pages. A quick overview of what is included:

Components

Doc-List (Has an input doc object array and is used by the pages Feed, User-Profile, Me and Notes)

and is used by the pages Feed, User-Profile, Me and Notes) Error-Messages (used in the auth gateway client/src/app/auth-gateway )

) Image-Upload (+cropper; can be used in any form and automatically chooses the correct filepicker and camera)

Info-Slider (displays information about the application; used in the page info )

) Skeleton-Card (preloading screen to decrease perceived loading time and is used by the pages Feed, User-Profile, Me and Notes)

Helpers

Email-Validator (checks if the email is already registered)

Search-Filter (querys the supplied doc for a keyword, used by the doc-list component)

Username-Validator (checks if the username is already registered)

Modals

Edit-Doc (used by the doc-list component)

Edit-Profile (used in the settings page to edit the user profile)

Edit-User (admin settings to modify a user; used in the settings page)

Services

Image Service (used by the image-upload component)

Pages

Auth-Gateway

Includes all pages regarding user authentication, registration and password resets.

Home

Handles routing for the tab bar. Namingly the pages Feed, Me and Conversation List. Depending on the client device, it shows the tabbar on the bottom (mobile) or on the top (desktop).

Feed

Shows all documents of the shared database, by querying the shared-doc service ( client/src/app/services ).

Profile

Consists of two pages: Me and User-profile. Me shows the current user doc, User-Profile, the profile of any other user.

Chat

Consists of two pages: Chat and Conversations. Chat displays the messages of a single conversation, Conversations displays all chats the user is participating in.

Notes

Shows all documents of the private database, by querying the private-doc service ( client/src/app/services ).

User-Settings

Handles functions like *change profile, email, password, etc. *. For admin users shows an additional tab for managing users.

App-building

Android & iOS

Change your app name and id in the capacitor.config.json and ionic.config.json located in the root folder of client . For bulding please refer to the official capacitor documentation.

PWA

Use the pwa-asset-generator and the web-app-manifest-generator to theme your app, and change your app name in the index.html and manifest.webmanifest .

Client Misc

Image Lazyloading

Images are mostly lazyloaded with the help of ng-lazyload-image. If you create a new page, you have to import the LazyLoadImageModule in your page module. For a nice UI, images will fade in when they are lazyloaded. Have a look at the lazyload section in client/src/global.css . If you do not want to use lazyload for an <img> tag, you have to declare your own class and set opacity: 1 !important in your global. css.

Server

Server-Installation

Requirements: Installed NodeJS, NestJS and Docker / Docker-Compose locally. Run docker-compose up in the root folder. Open Fauxton, the couchdb gui and disable the cors policy in settings and after you edited the credentials in the docker-compose.yaml and .env file.

Important: When developing always open Fauxton in a private window, as its authentication document conflicts with the user document of the CAIN Stack application.

Environment

Put a .env file into the root of the server folder

BASEURL=http://localhost:8100 NESTURL=http://localhost:3000 COUCHDB_HOST=localhost COUCHDB_PORT=5984 COUCHDB_USR=admin COUCHDB_PW=couchdb MAILER_USR=gmailaccountname MAILER_PW=gmailaccountpassword

Server-Core

DB Setup & Design Docs

The setup function ( server/src/core/db-setup.ts )is triggerd on server startup and automatically creates all necessary databases and design documents (can be found in server/core/design-docs ). For developing it can be useful to purge all databases. Just uncomment the function at the beginning of the setup handler, save, comment again and save again.

superlogin-config server/src/core/superlogin-config.ts

Authentication heavily relies on superlogin. Press the link to read the full documentation. Almost all main apis are included in this template.

Mailer settings

A confirmation e-mail can be sent when a user signs up or forgot his password. You can use a standard gmail account to send out those mails. Just enter your credentials into the MAILER_USR and MAILER_PW sections of the .env file. You then have to enable access throught less secure apps. You can also use SendMail or any other custom Nodemailer transport. Have a look in the mailer section of the superlogin-config.ts . If you want to enable the confirmation mails you can change the mailer configuration in the superlogin config file server/src/core/superlogin-config.ts under the local section. Mailer Templates can be modified in server/src/assets/email-templates .

sendConfirmEmail: false, requireEmailConfirm: false,

User roles

User roles can be defined and will be automatically added to the user doc (see server/src/core/signup-handler.ts on line 30). By default users with the admin role will have access to all documents. Routes can be guarded by user role (see server/src/user/user.module.ts on line 23)

Server Core Services server/src/core/services

Auth service checks if the token of the bearer token corresponds with the token in the user document in couchdb. The stream service converts a buffer into an readable stream for optimized file responses.

Controllers

User-Api server/src/user

The user controller is responsible for getting and edditing profile details and additional settings for admin users. The apis are protected by the superlogin middleware, see user.module.ts .

Chat-Api server/src/chat

After starting the server, the chat controller starts listening to changes in the chat-index database and creates the corresponding chat databases and adds the participants to the security document of these databases.

Help & support

Visit heichling. xyz and send me a message if you have any questions. Also check out maxperience. blog for more information.