Skip to content

Commit

Permalink
fix: correct env variables replacement in the building process
Browse files Browse the repository at this point in the history
  • Loading branch information
lbwa committed Sep 26, 2019
1 parent a77b38b commit 79ca0ba
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 25 deletions.
64 changes: 62 additions & 2 deletions README.CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,31 @@
npm i v-access --save
```

## 数据结构
## 先决条件

`v-access` 所有认证功能都是基于从服务端提供的一个当前用户的 **权限列表** 来实现的(受启发于 [GCP Cloud IAM](https://cloud.google.com/storage/docs/access-control/iam))。该权限列表中的每一项元素都表明了一个服务端的权限。并且一个或多个权限可组成为一个用户角色。

存在一个最佳实践,使用形如 `[scope].[module].[ability]` 的单个权限格式来表示一个功能的访问权限,并且 `[scope]` 在没有其他外部系统(作用域)的情况下是可选的。

例如,任意包含 `account.read` 的用户权限列表,都表明当前用户可访问服务端的 `account` 服务。当存在一个由 `order.read``product.read` 组成的名为 `seller` 的用户角色时,任意包含该 `seller` 用户角色的用户都可以访问 `order` 服务和 `product` 服务。此处的用户角色本质上就是用户的能力集合。系统管理员可分配指定的用户角色给任意低级别用户。任意单个 `access` 都不应直接分配给低级别用户。

```ascii
+--> access 1
+-----> user role 1 |
| +--> access 2
|
| +--> access 3
user -+-----> user role 2 |
| +--> access 4
|
| +--> access 5
+-----> user role 3 |
+--> access 6
```

`v-access` 所有认证功能都是基于从服务端提供的一个当前用户的 **权限列表** 来实现的。该权限列表中的每一项元素都表明了一个服务端的权限,如任意包含 `account.read` 的用户权限列表,都表明当前用户可访问服务端的 `account` 服务。值得注意的是,任意的权限名称取决于你自己,`v-access` 并不限制单个权限名称的格式。无论你如何命名服务端的各项服务名称,你都应该首先在获取到当前用于的权限列表后,立即调用 [init](#initialization) 函数,并传入当前权限列表来完成 `v-access` 的认证模块的初始化。
值得注意的是,任意的权限名称取决于你自己,`v-access` 并不限制单个权限名称的格式。无论你如何命名服务端的各项服务名称,你都应该首先在获取到当前用于的权限列表后,立即调用 [init](#initialization) 函数,并传入当前权限列表来完成 `v-access` 的认证模块的初始化。

## 数据结构

- **任意一个** 权限列表中的单个服务权限都应遵顼以下结构:

Expand Down Expand Up @@ -309,6 +331,44 @@ Vue.use(VAccess, { router, routes })

如 [权限重置](#权限重置) 一样,当开发者在 `Vue.use(VAccess, options)` 模式下调用 `this.$$auth.reset()` 时,不仅可以重置当前权限容器,而且可在 **不发生页面重载** 的情况下实现将之前添加的私有动态路由删除。

## 与其他全局导航守卫

[关注点分离](https://en.wikipedia.org/wiki/Separation_of_concerns) 是一个用于分离差异化的系统组成部分,并在各个独立的模块之间形成 “高内聚,低耦合”。[router.beforeEach] 导航守卫接受 **多个** 钩子函数来实现一个 `导航管道`。这正是 `v-access` 的理论基础。`v-access` 提供了一个分离 `授权者` 的解决方案。开发者可不再过多关心 `authorizer` 是如何生效的了。

至此,结合 [router.beforeEach] 的文档描述,当你需要额外的钩子函数时:

```js
/* src/router/index.js */
const router = new VueRouter({
// Omit options
})
/**
* 该部分是开发者传入的额外的导航 hooks 函数
* v-access 并不关心开发者是否传入了导航 hooks 函数,它仅关心自身的 “授权者” 工作
*/
router.beforeEach((to, from, next) => {
/* Anything you want to do */
})
export default router
```

```js
/* src/plugins/v-access.js */
import Vue from 'vue'
import VAccess from 'v-access'
import router from '../router'
const routes = [/* Omit routes */]
Vue.use(VAccess, { router, routes }))
```

如果你还不清楚多个全局前置导航守卫是如何工作的,那么我推荐你首先仔细阅读 [router.beforeEach] 的官方文档。

[router.beforeeach]: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

## Changelog

此项目所有显著的修改都会记录于 [CHANGELOG](./CHANGELOG.md) 文件内.
Expand Down
107 changes: 84 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

- **Portable**: You only need to provide a current user access list without any complex initialization process, then `v-access` will provide all fully **element** and (or) **routes** access authorization functionalities.

- **Flexible**: Support any access data type with `id` fleid.
- **Flexible**: Support any access data type with `id` field.

- **Dynamic**: Support any private routes dynamic addition.

Expand All @@ -47,9 +47,31 @@
npm i v-access --save
```

## Schema
## Prerequisites

All authorization functionalities are based on an access **list** which should be provided by your back-end services (inspired by [GCP Cloud IAM](https://cloud.google.com/storage/docs/access-control/iam)). Every element in the list represents a permission (ability) which is used to access a kind of back-end service functionalities. One or multiple permissions can be contained by one user role.

There is a best practice that uses syntax like `[scope].[module].[ability]` to represents the access of functionality, and `[scope]` is optional if you have no other external systems (scope).

For example, any user access list including `account.read` represents current user has capability to access `account` service. There is a user role named `seller` would be made of `order.read` and `product.read`, which means any user includes `seller` role can access `order` service and `product` service. A user role is similar to the abilities set. System administrators would use user roles to distribute access abilities to low-level user. Any single access shouldn't be distributed directly.

```ascii
+--> access 1
+-----> user role 1 |
| +--> access 2
|
| +--> access 3
user -+-----> user role 2 |
| +--> access 4
|
| +--> access 5
+-----> user role 3 |
+--> access 6
```

All authorization functionalities are based on a access **list** which should be provided by your any back-end services. Every element in the list represents an access to a kind of back-end service functionalities. For example, any user access list including `account.read` represents current user has access to `account` service. Your access name is up to you. Whatever you name your services, your should invoke [init](#initialization) function to pass access list for `v-access` initialization.
The access name is up to you. Whatever you name your access elements, you should invoke [init](#initialization) function to pass the access list for `v-access` initialization.

## Schema

- **One access** of user access list should has following structure:

Expand Down Expand Up @@ -89,7 +111,7 @@ You **MUST** invoke `init` function which is belong to `Vue` prototype property
Vue.use(VAccess, { router })
```

Following code describe that passing access list when you have fetched access list at anywhere.
The following code describes that passing access list when you have fetched access-list anywhere.

```ts
// In any vue instance
Expand All @@ -104,13 +126,13 @@ fetchUserAccessList().then(({ list: userAccessList }: { list: Access[] }) =>

1. `Vue` global component named `v-access`.

1. Verification functions which is belong to `Vue` prototype property named `$$auth`
1. Verification functions which belong to `Vue` prototype property named `$$auth`

**NOTICE:** Global component `<v-access>` supports **multiple** child components.

### Single verification

Whether current user has **ONE** access.
Whether the current user has **ONE** access.

- function

Expand All @@ -128,7 +150,7 @@ this.$$auth.has('accessNameA')

### Weak verification

Whether current user has **AT LEAST ONE** access.
Whether the current user has **AT LEAST ONE** access.

- function

Expand All @@ -148,7 +170,7 @@ this.$$auth.weakList(['accessNameA', 'accessNameB'])

### Strict verification

Whether current user has **ALL** access.
Whether the current user has **ALL** access.

- function

Expand All @@ -169,18 +191,18 @@ this.$$auth.strictList(['accessNameA', 'accessNameB'])

### Access reset

`v-access` has provided a reset function named `reset` which could be invoked to delete any access list when developer want to rest current access container.
`v-access` has provided a reset function named `reset` which could be invoked to delete any access-list when the developer wants to rest current access container.

## Routes access control

If you want to implement routes access control based on `vue-router`, your should provide a `vue-router` instance and a preset routes first. Other options is optional.
If you want to implement routes access control based on `vue-router`, you should provide a `vue-router` instance and a preset routes first. Other options are optional.

| Option | Required | Data type | Description |
| :------: | :---------------------------: | :--------------------: | :-------------------------------------------------------------------------------------------------------------------------: |
| router | ✔️ | `VueRouter` | A `vue-router` instance |
| routes | (default: `[]`) | `RouteWithAccess[]` | Preset routes list for access control |
| redirect | (default: `/@v-access-error`) | `string` | Occurred by unauthorized access |
| exclude | (default: `[]`) | `string[]` or `RegExp` | All of routes matched `exclude` will skip authorization, even if it doesn't satisfy `access` or `weakAccess` field of route |
| Option | Required | Data type | Description |
| :------: | :---------------------------: | :--------------------: | :-----------------------------------------------------------------------------------------------------------------------------: |
| router | ✔️ | `VueRouter` | A `vue-router` instance |
| routes | (default: `[]`) | `RouteWithAccess[]` | Preset routes list for access control |
| redirect | (default: `/@v-access-error`) | `string` | Occurred by unauthorized access |
| exclude | (default: `[]`) | `string[]` or `RegExp` | All of the routes matched `exclude` will skip authorization, even if it doesn't satisfy `access` or `weakAccess` field of route |

[route-config]: https://router.vuejs.org/api/#routes

Expand All @@ -193,11 +215,11 @@ Vue.use(VAccess, { router, routes })

### Public routes authorization

> Public static routes is passed by developer when `vue-router` initialization.
> Public static routes are passed by the developer when `vue-router` initialization.
You only need to set `access` or `weakAccess` field of any routes if you want to authorize any public static routes.

1. Any element of `access` field MUST be satisfied, otherwise url redirect will be occurred.
1. Any element of `access` field MUST be satisfied, otherwise URL redirect will occur.

> RouteConfig is a reference from official `vue-router` [documentation][route-config].
Expand All @@ -222,7 +244,7 @@ You only need to set `access` or `weakAccess` field of any routes if you want to
}
```

1. Current authorization will pass if at least one has be satisfied.
1. Current authorization will pass if at least one has to be satisfied.

```ts
interface PublicRouesWithWeakAuth extends RouteConfig {
Expand Down Expand Up @@ -252,9 +274,9 @@ You only need to set `access` or `weakAccess` field of any routes if you want to

> Private dynamic routes are come from `Vue.use(VAccess, { router, routes }`.
As mentioned above, The developer passes a preset private route list in `Vue.use`. The `v-access` will generate the final private routes based on the current user's **access list** and added to the current `vue-router` instance.
As mentioned above, The developer passes a preset private route list in `Vue.use`. The `v-access` will generate the final private routes based on the current user's **access-list** and added to the current `vue-router` instance.

The data type of private routes provided by developer also supports `access` and `weakAccess` fields, same as public routes.
The data type of private routes provided by developer also supports `access` and `weakAccess` fields, the same as public routes.

1. Strict authorization, same as public routes

Expand All @@ -271,7 +293,7 @@ The data type of private routes provided by developer also supports `access` and
path: '/private-routes',
component: () => import('@/views/Private'),
meta: {
// This routes will be added when all elements has been satisfied
// This routes will be added when all elements have been satisfied
access: [
'admin',
'mongo.read'
Expand All @@ -294,7 +316,7 @@ The data type of private routes provided by developer also supports `access` and
{
path: '/private-routes',
component: () => import('@/views/Private'),
// This routes will be added when at least one elements has been satisfied
// This routes will be added when at least one element has been satisfied
meta: {
weakAccess: [
'admin',
Expand All @@ -309,6 +331,45 @@ The data type of private routes provided by developer also supports `access` and

As with [access resets](#access-reset), the current access container will be reset without page reloading when developer calls `this.$$auth.reset()` with `Vue.use(VAccess, options)`.

## With other hooks

[Separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) is a design principle for separating distinct parts, and implement the high cohesion and low coupling between multiple independent parts. [router.beforeEach] navigation guard accepts **multiple** hooks to implement a navigation pipe. This is the theoretical basis for `v-access` implementation. `v-access` has provided a solution for separating `authorizer` part. Developers couldn't care about how `authorizer` works anymore.

According to the above description, you can just pass other hooks into [router.beforeEach] if you need to add extra logic for navigation control.

```js
/* src/router/index.js */
const router = new VueRouter({
// Omit options
})

/**
* This part is your other navigation hook.
* v-access doesn't care about whether extra hooks has been passed by the
* developer, and only care about its **authorizer** works.
*/
router.beforeEach((to, from, next) => {
/* Anything you want to do */
})

export default router
```

```js
/* src/plugins/v-access.js */
import Vue from 'vue'
import VAccess from 'v-access'
import router from '../router'

const routes = [/* Omit routes */]

Vue.use(VAccess, { router, routes }))
```

If you aren't familiar with how multiple global before hooks work, I strongly recommend you to read the documentation about [router.beforeEach].

[router.beforeeach]: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

## Changelog

All notable changes to this project will be documented in [CHANGELOG](./CHANGELOG.md) file.
Expand Down
4 changes: 4 additions & 0 deletions build/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import typescript from 'rollup-plugin-typescript2'
import { terser } from 'rollup-plugin-terser'
import replace from 'rollup-plugin-replace'
import path from 'path'
const version = require('../package.json').version

Expand Down Expand Up @@ -41,6 +42,9 @@ function createConfig(opts) {
typescript({
clean: true
}),
replace({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
}),
terser({
output: {
comments: function(node, comment) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"jest": "^24.8.0",
"prettier": "^1.18.2",
"rollup": "^1.19.4",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-terser": "^5.1.1",
"rollup-plugin-typescript2": "^0.22.1",
"ts-jest": "^24.0.2",
Expand Down
27 changes: 27 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2199,6 +2199,13 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"

magic-string@^0.25.2:
version "0.25.3"
resolved "https://registry.npm.taobao.org/magic-string/download/magic-string-0.25.3.tgz#34b8d2a2c7fec9d9bdf9929a3fd81d271ef35be9"
integrity sha1-NLjSosf+ydm9+ZKaP9gdJx7zW+k=
dependencies:
sourcemap-codec "^1.4.4"

make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.npm.taobao.org/make-dir/download/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
Expand Down Expand Up @@ -2971,6 +2978,14 @@ rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3:
dependencies:
glob "^7.1.3"

rollup-plugin-replace@^2.2.0:
version "2.2.0"
resolved "https://registry.npm.taobao.org/rollup-plugin-replace/download/rollup-plugin-replace-2.2.0.tgz#f41ae5372e11e7a217cde349c8b5d5fd115e70e3"
integrity sha1-9BrlNy4R56IXzeNJyLXV/RFecOM=
dependencies:
magic-string "^0.25.2"
rollup-pluginutils "^2.6.0"

rollup-plugin-terser@^5.1.1:
version "5.1.1"
resolved "https://registry.npm.taobao.org/rollup-plugin-terser/download/rollup-plugin-terser-5.1.1.tgz#e9d2545ec8d467f96ba99b9216d2285aad8d5b66"
Expand Down Expand Up @@ -2999,6 +3014,13 @@ rollup-pluginutils@2.8.1, rollup-pluginutils@^2.8.1:
dependencies:
estree-walker "^0.6.1"

rollup-pluginutils@^2.6.0:
version "2.8.2"
resolved "https://registry.npm.taobao.org/rollup-pluginutils/download/rollup-pluginutils-2.8.2.tgz?cache=0&sync_timestamp=1568405888956&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Frollup-pluginutils%2Fdownload%2Frollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
integrity sha1-cvKvB0i1kjZNvTOJ5gDlqURKNR4=
dependencies:
estree-walker "^0.6.1"

rollup@^1.19.4:
version "1.19.4"
resolved "https://registry.npm.taobao.org/rollup/download/rollup-1.19.4.tgz#0cb4e4d6fa127adab59b11d0be50e8dd1c78123a"
Expand Down Expand Up @@ -3194,6 +3216,11 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
resolved "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha1-dHIq8y6WFOnCh6jQu95IteLxomM=

sourcemap-codec@^1.4.4:
version "1.4.6"
resolved "https://registry.npm.taobao.org/sourcemap-codec/download/sourcemap-codec-1.4.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsourcemap-codec%2Fdownload%2Fsourcemap-codec-1.4.6.tgz#e30a74f0402bad09807640d39e971090a08ce1e9"
integrity sha1-4wp08EArrQmAdkDTnpcQkKCM4ek=

spdx-correct@^3.0.0:
version "3.1.0"
resolved "https://registry.npm.taobao.org/spdx-correct/download/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
Expand Down

0 comments on commit 79ca0ba

Please sign in to comment.