# ctpass - Tiwater Passport

Authentication and authorization services.

![Node.js CI](https://github.com/tiwater/passport/workflows/Node.js%20CI/badge.svg)

## 技术栈

* Nest.js + TypeScript
* Typegoose + Mongodb
* Passport
* [CASL](https://casl.js.org/v5/en/)
* JWT - [JSON Web Tokens](https://jwt.io/)
* Swagger - API 文档自动生成
* Appmetrics

## 环境准备

1. 安装最新版 node 和 npm；
2. 安装 yarn `npm install -g yarn`；
3. 安装 Mongodb 参考  https://blog.csdn.net/mirajay_yeah/article/details/109646189；
4. 全局安装 Nest CLI: `yarn global add @nestjs/cli`；
5. 在项目目录内运行 `yarn` 安装依赖包；
6. 运行 `yarn start:dev` (监听文件变化自动重启服务)，监听端口为 7777 ；
7. 在 Swagger UI 中发起 API 测试 http://localhost:7777/apidocs/ ；
8. 通过 Appmetrics-dash 查看服务访问情况 http://localhost:7777/appmetrics-dash/ ；

## Bearer 验证

1. 在 Swagger UI 中调用 API `/auth/login` ，可以输入 user/pwd 和 admin/admin 两组账号，具有不同的权限。vendorId 设为 1；
2. 查看返回值是否为 201，并拷贝 Response body 中的 access_token 值，类似于 `eyJhbGciOiJIUzI1Ni...OAJvsHzPI`，注意不要包含引号；
3. 点击右上角 Authorize 按钮，粘贴刚才拷贝的 access_key 内容，点击 Authorize 按钮成功后点 Close 关闭对话框；
4. 调用 API `/users/profile` 方法，即可基于 Bearer token 验证获取相应的用户信息；
5. 作为对比，可以再次点击右上角 Authorize 并在弹出的对话框里点 Logout，然后再次调用 `/users/profile`，此时应返回 401 错误；

## Folder structure

app - Application module
auth - Authentication and authorization module
db - The database connection provider
dbrepository - Provide the operations against the persistent entities
models - Definition of the PO (Persistent Object) and DTO (Data Transfer Object)
privilege - The previlege management related module
thirdparty - The module to support the third party platforms, e.g. communicate with Wechat, Alipay, etc.
user - User account related module
util - The generic class/function/definition, e.g. constant definitions, logger, etc.


## New API development

1. For the private APIs which need the user to login before access it,
add the annotation `@Permissions` to claim the permission the API requires, e.g. `@Permissions(PermissionDef.PrivateAccess)`. For new modules that need separtate permission, please add new permission definition in the `PermissionDef`, and also add the initialize code in the `PermissionRepository` 
2. If user pass the authorization and enter the API, the API can get a `JwtPayload` object from the `@Request() req.user` property, which includes the key information of the logged in user, such as userId, user permissions, etc.
3. Can take the `UserController.getProfile()` as an example.

## 其他

1. 建议在 Visual Studio Code 中安装 Markdown All in One 插件，即可比较方便编辑 README.md 等文档，点击右上角 Open Preview to the Side 图标，即可以左右分栏方式编辑 Markdown 文档。
2. This project is published to NPM and introduced into tisvc.

## TODO

1. Role & Permission based 访问控制机制，考虑基于 [CSAL](https://casl.js.org/v5/en/guide/intro
)。
