webledger-auth-plugin 1.0.10 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,3 +12,8 @@ node ace configure webledger-auth-plugin
12
12
  ```
13
13
 
14
14
  [**Instructions**](./instructions.md)
15
+
16
+
17
+ ## Develop locally
18
+ 1. `npm run link` this will build and link locally, somewhere in your `~/node_modules/<package_name>` or `~/.nvm/versions/node/v18.20.3/lib/node_modules`
19
+ 2. at the project folder where you want to install locally try `npm link webledger-auth-plugin` (package.json -> name)
@@ -1,24 +1,30 @@
1
1
  declare module '@ioc:AuthService' {
2
2
  export interface AuthServiceI {
3
- login(email: string, password: string): any;
4
- signup(params: any): any;
5
- getUser(uuid: string): any;
6
- updateUser(uuid: string, params: any): any;
7
- forgotPassword(email: string): any;
8
- resendEmailVerification(email: string): any;
9
- verifyPin(uuid: string, user_pin: string): any;
10
- forgotPin(uuid: string, password: string, user_pin: string): any;
11
- createToken(sub: string): any;
12
- verifyToken(token: string, sub?: string): any;
3
+ isEnable: boolean;
4
+ createToken(sub: string): string;
5
+ verifyToken(token: string, sub?: string): object | null;
6
+ getApps(): Promise<any>;
7
+ login(email: string, password: string): Promise<any>;
8
+ signup(params: any): Promise<any>;
9
+ getUser(uuid: string): Promise<any>;
10
+ updateUser(uuid: string, params: any): Promise<any>;
11
+ forgotPassword(email: string): Promise<any>;
12
+ resendEmailVerification(email: string): Promise<any>;
13
+ verifyPin(uuid: string, user_pin: string): Promise<any>;
14
+ forgotPin(uuid: string, password: string, user_pin: string): Promise<any>;
15
+ logoutURL(): string;
16
+ checkLoginURL(): string;
13
17
  }
14
18
  const authService: AuthServiceI;
15
19
  export default authService;
16
20
  export interface AuthServiceConfig {
21
+ enable: boolean;
17
22
  host: string;
18
- env: string;
19
- type: string;
20
23
  iss: string;
24
+ client: string;
21
25
  secret: string;
26
+ env?: string;
27
+ product?: string;
22
28
  expiry?: string;
23
29
  timeout?: number;
24
30
  paths?: {
@@ -1,8 +1,8 @@
1
1
  Congratulations! You have configured `AuthService` package successfully. Make sure to add the following values inside `env.ts` file:
2
2
 
3
3
  ```ts
4
+ AUTH_ENABLE: Env.schema.boolean,
4
5
  AUTH_HOST: Env.schema.string({ format: 'host' }),
5
- AUTH_ENV: Env.schema.string(),
6
- AUTH_PRODUCT_TYPE: Env.schema.string(),
7
- AUTH_JWT_TOKEN: Env.schema.string(),
6
+ AUTH_CLIENT: Env.schema.string(),
7
+ AUTH_SECRET: Env.schema.string(),
8
8
  ```
@@ -11,7 +11,8 @@ class AuthServiceProvider {
11
11
  register() {
12
12
  this.app.container.singleton('AuthService', () => {
13
13
  const config = this.app.container.use('Adonis/Core/Config');
14
- return new AuthService_1.default(config.get('authService'));
14
+ const service = new AuthService_1.default(config.get('authService'));
15
+ return service;
15
16
  });
16
17
  }
17
18
  }
@@ -7,6 +7,55 @@ export default class AuthService implements AuthServiceI {
7
7
  createToken(sub: string): any;
8
8
  verifyToken(token: string, sub?: string): any;
9
9
  private setAuthToken;
10
+ /**
11
+ * isEnable is useful if enable both local or server auth
12
+ * if true means you can use server auth else you can do something else
13
+ *
14
+ * Example code for login
15
+ *
16
+ * import User from 'App/Models/User'
17
+ * import AuthService from '@ioc:AuthService'
18
+ *
19
+ public async login(ctx: HttpContextContract) {
20
+ const { email, password } = ctx.request.only(['email', 'password'])
21
+
22
+ try {
23
+ let user: User | null,
24
+ token: any = null,
25
+ sso_url = null
26
+ if (AuthService.isEnable) {
27
+ const res = await AuthService.login(email, password)
28
+ const data = res.data.user
29
+ sso_url = res.data.sso_url
30
+ user = await User.findBy('uuid', data.uuid)
31
+ if (!user) user = await User.findBy('email', email)
32
+
33
+ if (user) {
34
+ data.isLocked = false
35
+ user.merge(data)
36
+ await user.save()
37
+ } else {
38
+ user = await User.create(data)
39
+ }
40
+ token = await ctx.auth.use('api').generate(user, { expiresIn: '12 hours' })
41
+ } else {
42
+ token = await ctx.auth.use('api').attempt(email, password)
43
+ user = ctx.auth.use('api').user!
44
+ if (!ctx.auth.use('api').user) {
45
+ return ctx.response.status(400).json({ message: 'Invalid credentials', token })
46
+ }
47
+ await ctx.auth.user?.merge({ isLocked: false }).save()
48
+ }
49
+
50
+ if (user) return ctx.response.json({ ...user.serialize(), token, sso_url })
51
+ } catch (e) {
52
+ this.logger.error(`Error login: ${e.message}`)
53
+ }
54
+ return ctx.response.status(400).json({ message: 'Invalid credentials' })
55
+ }
56
+ */
57
+ get isEnable(): boolean;
58
+ getApps(): Promise<import("axios").AxiosResponse<any, any>>;
10
59
  login(email: string, password: string): Promise<import("axios").AxiosResponse<any, any>>;
11
60
  signup(params: any): Promise<import("axios").AxiosResponse<any, any>>;
12
61
  getUser(uuid: string): Promise<import("axios").AxiosResponse<any, any>>;
@@ -15,4 +64,6 @@ export default class AuthService implements AuthServiceI {
15
64
  resendEmailVerification(email: string): Promise<import("axios").AxiosResponse<any, any>>;
16
65
  verifyPin(uuid: string, user_pin: string): Promise<import("axios").AxiosResponse<any, any>>;
17
66
  forgotPin(uuid: string, password: string, user_pin: string): Promise<import("axios").AxiosResponse<any, any>>;
67
+ logoutURL(): string;
68
+ checkLoginURL(): string;
18
69
  }
@@ -9,6 +9,7 @@ class AuthService {
9
9
  constructor(config) {
10
10
  this.config = config;
11
11
  this.paths = {
12
+ apps: '/api/apps',
12
13
  login: '/api/login',
13
14
  signup: '/api/signup',
14
15
  get_user: '/api/users',
@@ -22,34 +23,97 @@ class AuthService {
22
23
  this.client.defaults.timeout = config.timeout || 30000; // default is 30seconds
23
24
  const headers = {
24
25
  'Content-Type': 'application/json',
25
- 'x-auth-env': config.env,
26
- 'x-product-type': config.type,
26
+ 'x-auth-client': config.client,
27
27
  };
28
+ const [product, env] = config.client.split('_');
29
+ config.env = env;
30
+ config.product = product;
28
31
  for (const key in headers) {
29
32
  this.client.defaults.headers.common[key] = headers[key];
30
33
  }
31
34
  this.paths = { ...this.paths, ...config.paths };
32
35
  }
33
36
  createToken(sub) {
34
- const payload = { env: this.config.env, type: this.config.type, iss: this.config.iss, sub };
37
+ const payload = {
38
+ env: this.config.env,
39
+ product: this.config.product,
40
+ iss: this.config.iss,
41
+ sub,
42
+ };
35
43
  const jwtAuthToken = (0, jsonwebtoken_1.sign)(payload, this.config.secret, {
36
44
  expiresIn: this.config.expiry || '1m',
37
45
  });
38
46
  return jwtAuthToken;
39
47
  }
40
48
  verifyToken(token, sub) {
41
- const data = (0, jsonwebtoken_1.verify)(token, this.config.secret);
42
- if (sub) {
43
- if (sub === data.sub) {
49
+ try {
50
+ const data = (0, jsonwebtoken_1.verify)(token, this.config.secret);
51
+ if (!sub)
44
52
  return data;
45
- }
53
+ return sub === data.sub ? data : null;
54
+ }
55
+ catch (e) {
46
56
  return null;
47
57
  }
48
- return data;
49
58
  }
50
59
  setAuthToken(sub) {
51
60
  const jwtAuthToken = this.createToken(sub);
52
- this.client.defaults.headers.common['Authorization'] = `Bearer ${jwtAuthToken}`;
61
+ this.client.defaults.headers.common['Authorization'] = jwtAuthToken;
62
+ }
63
+ /**
64
+ * isEnable is useful if enable both local or server auth
65
+ * if true means you can use server auth else you can do something else
66
+ *
67
+ * Example code for login
68
+ *
69
+ * import User from 'App/Models/User'
70
+ * import AuthService from '@ioc:AuthService'
71
+ *
72
+ public async login(ctx: HttpContextContract) {
73
+ const { email, password } = ctx.request.only(['email', 'password'])
74
+
75
+ try {
76
+ let user: User | null,
77
+ token: any = null,
78
+ sso_url = null
79
+ if (AuthService.isEnable) {
80
+ const res = await AuthService.login(email, password)
81
+ const data = res.data.user
82
+ sso_url = res.data.sso_url
83
+ user = await User.findBy('uuid', data.uuid)
84
+ if (!user) user = await User.findBy('email', email)
85
+
86
+ if (user) {
87
+ data.isLocked = false
88
+ user.merge(data)
89
+ await user.save()
90
+ } else {
91
+ user = await User.create(data)
92
+ }
93
+ token = await ctx.auth.use('api').generate(user, { expiresIn: '12 hours' })
94
+ } else {
95
+ token = await ctx.auth.use('api').attempt(email, password)
96
+ user = ctx.auth.use('api').user!
97
+ if (!ctx.auth.use('api').user) {
98
+ return ctx.response.status(400).json({ message: 'Invalid credentials', token })
99
+ }
100
+ await ctx.auth.user?.merge({ isLocked: false }).save()
101
+ }
102
+
103
+ if (user) return ctx.response.json({ ...user.serialize(), token, sso_url })
104
+ } catch (e) {
105
+ this.logger.error(`Error login: ${e.message}`)
106
+ }
107
+ return ctx.response.status(400).json({ message: 'Invalid credentials' })
108
+ }
109
+ */
110
+ get isEnable() {
111
+ return this.config.enable;
112
+ }
113
+ getApps() {
114
+ const subject = 'apps';
115
+ this.setAuthToken(subject);
116
+ return this.client.get(this.paths[subject]);
53
117
  }
54
118
  login(email, password) {
55
119
  const subject = 'login';
@@ -91,5 +155,13 @@ class AuthService {
91
155
  this.setAuthToken(subject);
92
156
  return this.client.post(`${this.paths[subject]}/${uuid}/forgot_pin`, { password, user_pin });
93
157
  }
158
+ logoutURL() {
159
+ const url = `${this.config.host}/sso/${this.config.env}/logout?product=${this.config.product}`;
160
+ return url;
161
+ }
162
+ checkLoginURL() {
163
+ const url = `${this.config.host}/sso/${this.config.env}/jump/${this.config.product}`;
164
+ return url;
165
+ }
94
166
  }
95
167
  exports.default = AuthService;
@@ -2,11 +2,13 @@ import { AuthServiceConfig } from '@ioc:AuthService'
2
2
  import Env from '@ioc:Adonis/Core/Env'
3
3
 
4
4
  const authServiceConfig: AuthServiceConfig = {
5
+ enable: Env.get('AUTH_ENABLE', true),
5
6
  host: Env.get('AUTH_HOST'),
6
7
  env: Env.get('AUTH_ENV'),
7
8
  type: Env.get('AUTH_PRODUCT_TYPE'),
8
9
  iss: Env.get('BASE_URL'),
9
- secret: Env.get('AUTH_JWT_TOKEN'),
10
+ client: Env.get('AUTH_CLIENT'),
11
+ secret: Env.get('AUTH_SECRET'),
10
12
  }
11
13
 
12
14
  export default authServiceConfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webledger-auth-plugin",
3
- "version": "1.0.10",
3
+ "version": "2.0.0",
4
4
  "description": "webledger auth service AdonisJS 5 login plugin",
5
5
  "main": "build/providers/AuthServiceProvider.js",
6
6
  "scripts": {
@@ -12,6 +12,7 @@
12
12
  "build": "npm run compile",
13
13
  "prepublishOnly": "npm run build",
14
14
  "lint": "eslint . --ext=.ts",
15
+ "link": "npm run build && npm link",
15
16
  "format": "prettier --write .",
16
17
  "commit": "git-cz",
17
18
  "release": "np --message=\"chore(release): %s\"",