@hapiboo/module-auth 1.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.
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.securityService = void 0;
4
+ const jsonwebtoken_1 = require("jsonwebtoken");
5
+ let _jwt_secret;
6
+ const _client_secrets = [];
7
+ var helpers;
8
+ (function (helpers) {
9
+ function __validateTokenAndGetPayload(token) {
10
+ let response = {};
11
+ (0, jsonwebtoken_1.verify)(token, _jwt_secret, (error, data) => {
12
+ if (error) {
13
+ if (error instanceof jsonwebtoken_1.TokenExpiredError) {
14
+ console.error('jwt expired');
15
+ }
16
+ throw error;
17
+ }
18
+ if (typeof data !== 'string') {
19
+ response = data ?? {};
20
+ }
21
+ });
22
+ return response;
23
+ }
24
+ helpers.__validateTokenAndGetPayload = __validateTokenAndGetPayload;
25
+ function __retractRequestToken(request) {
26
+ let token = '';
27
+ if (request.headers['authorization']) {
28
+ const auth = request.headers['authorization'];
29
+ const elements = auth.split(' ');
30
+ if (elements.length === 2 && elements[0].toLowerCase() === 'bearer') {
31
+ token = elements[1];
32
+ }
33
+ else {
34
+ throw Error('incorrect authentication type');
35
+ }
36
+ }
37
+ else {
38
+ throw Error('not authenticated');
39
+ }
40
+ return token;
41
+ }
42
+ helpers.__retractRequestToken = __retractRequestToken;
43
+ function __generateTokenString(payload, expirationInHours) {
44
+ return (0, jsonwebtoken_1.sign)(payload, _jwt_secret, { expiresIn: `${expirationInHours}h` });
45
+ }
46
+ helpers.__generateTokenString = __generateTokenString;
47
+ })(helpers || (helpers = {}));
48
+ var securityService;
49
+ (function (securityService) {
50
+ function initialize(jwt_secret) {
51
+ _jwt_secret = jwt_secret;
52
+ _client_secrets.length = 0;
53
+ }
54
+ securityService.initialize = initialize;
55
+ function registerClient(client_secret) {
56
+ _client_secrets.push(client_secret);
57
+ }
58
+ securityService.registerClient = registerClient;
59
+ let token;
60
+ (function (token) {
61
+ function refresh(user_id, refreshCode, expirationInHours) {
62
+ return helpers.__generateTokenString({ user_id: user_id, code: refreshCode }, expirationInHours);
63
+ }
64
+ token.refresh = refresh;
65
+ function data(user_id, account_id, admin, expirationInHours, data) {
66
+ return helpers.__generateTokenString({ user_id: user_id, account_id: account_id, admin: admin, data: data }, expirationInHours);
67
+ }
68
+ token.data = data;
69
+ function client(client) {
70
+ return helpers.__generateTokenString({ client: client }, 1);
71
+ }
72
+ token.client = client;
73
+ })(token = securityService.token || (securityService.token = {}));
74
+ let middleware;
75
+ (function (middleware) {
76
+ function client(request, response, next) {
77
+ try {
78
+ const payload = helpers.__validateTokenAndGetPayload(helpers.__retractRequestToken(request));
79
+ if (payload.client && payload.client != undefined && payload.client != '' && _client_secrets.find((secret) => { return secret == payload.client; }) != undefined) {
80
+ next();
81
+ }
82
+ else {
83
+ response.status(401);
84
+ response.json({ error: 'auth token validation error' });
85
+ return;
86
+ }
87
+ }
88
+ catch (error) {
89
+ if (error instanceof Error) {
90
+ response.status(401);
91
+ response.json({ error: error.message });
92
+ return;
93
+ }
94
+ else {
95
+ response.status(401);
96
+ response.json({ error: 'auth token validation error' });
97
+ return;
98
+ }
99
+ }
100
+ }
101
+ middleware.client = client;
102
+ function refresh(request, response, next) {
103
+ request.payload = undefined;
104
+ try {
105
+ const payload = helpers.__validateTokenAndGetPayload(helpers.__retractRequestToken(request));
106
+ request.payload = { user_id: payload.user_id, code: payload.code };
107
+ next();
108
+ }
109
+ catch (error) {
110
+ if (error instanceof Error) {
111
+ response.status(410);
112
+ response.json({ error: error.message });
113
+ return;
114
+ }
115
+ else {
116
+ response.status(410);
117
+ response.json({ error: 'refresh token validation error' });
118
+ return;
119
+ }
120
+ }
121
+ }
122
+ middleware.refresh = refresh;
123
+ function simple(request, response, next) {
124
+ request.payload = undefined;
125
+ try {
126
+ const payload = helpers.__validateTokenAndGetPayload(helpers.__retractRequestToken(request));
127
+ request.payload = { user_id: payload.user_id, account_id: undefined, admin: payload.admin };
128
+ next();
129
+ }
130
+ catch (error) {
131
+ if (error instanceof Error) {
132
+ response.status(401);
133
+ response.json({ error: error.message });
134
+ return;
135
+ }
136
+ else {
137
+ response.status(401);
138
+ response.json({ error: 'auth token validation error' });
139
+ return;
140
+ }
141
+ }
142
+ }
143
+ middleware.simple = simple;
144
+ function full(request, response, next) {
145
+ request.payload = undefined;
146
+ try {
147
+ const payload = helpers.__validateTokenAndGetPayload(helpers.__retractRequestToken(request));
148
+ request.payload = { user_id: payload.user_id, account_id: payload.account_id, admin: payload.admin, data: payload.data };
149
+ next();
150
+ }
151
+ catch (error) {
152
+ if (error instanceof Error) {
153
+ response.status(401);
154
+ response.json({ error: error.message });
155
+ return;
156
+ }
157
+ else {
158
+ response.status(401);
159
+ response.json({ error: 'auth token validation error' });
160
+ return;
161
+ }
162
+ }
163
+ }
164
+ middleware.full = full;
165
+ function admin(request, response, next) {
166
+ if (request.payload && request.payload.admin) {
167
+ next();
168
+ }
169
+ else {
170
+ response.status(403);
171
+ response.json({ error: 'insufficient priviledges' });
172
+ }
173
+ }
174
+ middleware.admin = admin;
175
+ function data(request, response, next) {
176
+ if (request.payload && request.payload.data && request.payload.data != undefined) {
177
+ next();
178
+ }
179
+ else {
180
+ response.status(400);
181
+ response.json({ error: 'malformed payload data' });
182
+ }
183
+ }
184
+ middleware.data = data;
185
+ function checkAdmin(request, response, next) {
186
+ simple(request, response, () => {
187
+ admin(request, response, next);
188
+ });
189
+ }
190
+ middleware.checkAdmin = checkAdmin;
191
+ function checkData(request, response, next) {
192
+ full(request, response, () => {
193
+ data(request, response, next);
194
+ });
195
+ }
196
+ middleware.checkData = checkData;
197
+ })(middleware = securityService.middleware || (securityService.middleware = {}));
198
+ })(securityService || (exports.securityService = securityService = {}));
@@ -0,0 +1,45 @@
1
+ import { IResponsePromise, IResponsePromiseVoid } from '@hapiboo/core';
2
+ import { User } from '../models';
3
+ export interface IAuthEmailLink {
4
+ url: string;
5
+ title: string;
6
+ }
7
+ export interface IAuthPerformers {
8
+ sendConfirmation(emailAddress: string, displayName: string, isInvited: boolean, confirmationLink: IAuthEmailLink): IResponsePromiseVoid;
9
+ sendRecover(emailAddress: string, recoverLink: IAuthEmailLink): IResponsePromiseVoid;
10
+ sendAfterPasswordChanged(emailAddress: string): IResponsePromiseVoid;
11
+ afterRegistration(account_id: string, user_id: string, account_name: string, account_email: string): IResponsePromise<{
12
+ id: string;
13
+ }>;
14
+ getTokenPayload<T>(user: User): IResponsePromise<T>;
15
+ }
16
+ export interface IAuthSettings {
17
+ allowSelfRegistration: boolean;
18
+ allowMultiLogin: boolean;
19
+ passwordHashLength: number;
20
+ passwordHashIterations: number;
21
+ firstAdmin: {
22
+ name: string;
23
+ email: string;
24
+ };
25
+ overrulingPermission: string | undefined;
26
+ }
27
+ export declare namespace authSettings {
28
+ function init(settings: IAuthSettings, performers: IAuthPerformers): void;
29
+ const allowSelfRegistration: boolean;
30
+ const allowMultiLogin: boolean;
31
+ const passwordHashLength: number;
32
+ const passwordHashIterations: number;
33
+ const firstAdmin: {
34
+ name: string;
35
+ email: string;
36
+ };
37
+ const overrulingPermission: string | undefined;
38
+ function sendConfirmation(emailAddress: string, displayName: string, isInvited: boolean, confirmationLink: IAuthEmailLink): IResponsePromiseVoid;
39
+ function sendRecover(emailAddress: string, confirmationLink: IAuthEmailLink): IResponsePromiseVoid;
40
+ function sendAfterPasswordChanged(emailAddress: string): IResponsePromiseVoid;
41
+ function afterRegistration(account_id: string, user_id: string, account_name: string, account_email: string): IResponsePromise<{
42
+ id: string;
43
+ }>;
44
+ function getTokenPayload<T>(user: User): IResponsePromise<T>;
45
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authSettings = void 0;
4
+ const core_1 = require("@hapiboo/core");
5
+ var authSettings;
6
+ (function (authSettings) {
7
+ let _settings = {
8
+ allowSelfRegistration: true,
9
+ allowMultiLogin: false,
10
+ passwordHashLength: 1024,
11
+ passwordHashIterations: 32,
12
+ firstAdmin: {
13
+ name: 'admin',
14
+ email: 'admin@mk13.studio'
15
+ },
16
+ overrulingPermission: undefined
17
+ };
18
+ let _performers = undefined;
19
+ function init(settings, performers) {
20
+ _settings = settings;
21
+ _performers = performers;
22
+ }
23
+ authSettings.init = init;
24
+ authSettings.allowSelfRegistration = (() => {
25
+ return _settings.allowSelfRegistration;
26
+ })();
27
+ authSettings.allowMultiLogin = (() => {
28
+ return _settings.allowMultiLogin;
29
+ })();
30
+ authSettings.passwordHashLength = (() => {
31
+ return _settings.passwordHashLength;
32
+ })();
33
+ authSettings.passwordHashIterations = (() => {
34
+ return _settings.passwordHashIterations;
35
+ })();
36
+ authSettings.firstAdmin = (() => {
37
+ return {
38
+ name: _settings.firstAdmin.name,
39
+ email: _settings.firstAdmin.email
40
+ };
41
+ })();
42
+ authSettings.overrulingPermission = (() => {
43
+ return _settings.overrulingPermission;
44
+ })();
45
+ function sendConfirmation(emailAddress, displayName, isInvited, confirmationLink) {
46
+ if (_performers) {
47
+ return _performers.sendConfirmation(emailAddress, displayName, isInvited, confirmationLink);
48
+ }
49
+ else {
50
+ return core_1.promise.createFailedVoidPromise(core_1.ResponseError.getMessageResponse(400, 'Email performers not set in authentication settings.'));
51
+ }
52
+ }
53
+ authSettings.sendConfirmation = sendConfirmation;
54
+ function sendRecover(emailAddress, confirmationLink) {
55
+ if (_performers) {
56
+ return _performers.sendRecover(emailAddress, confirmationLink);
57
+ }
58
+ else {
59
+ return core_1.promise.createFailedVoidPromise(core_1.ResponseError.getMessageResponse(400, 'Email performers not set in authentication settings.'));
60
+ }
61
+ }
62
+ authSettings.sendRecover = sendRecover;
63
+ function sendAfterPasswordChanged(emailAddress) {
64
+ if (_performers) {
65
+ return _performers.sendAfterPasswordChanged(emailAddress);
66
+ }
67
+ else {
68
+ return core_1.promise.createFailedVoidPromise(core_1.ResponseError.getMessageResponse(400, 'Email performers not set in authentication settings.'));
69
+ }
70
+ }
71
+ authSettings.sendAfterPasswordChanged = sendAfterPasswordChanged;
72
+ function afterRegistration(account_id, user_id, account_name, account_email) {
73
+ if (_performers) {
74
+ return _performers.afterRegistration(account_id, user_id, account_name, account_email);
75
+ }
76
+ else {
77
+ return core_1.promise.createFailedPromise(core_1.ResponseError.getMessageResponse(400, 'Email performers not set in authentication settings.'));
78
+ }
79
+ }
80
+ authSettings.afterRegistration = afterRegistration;
81
+ function getTokenPayload(user) {
82
+ if (_performers) {
83
+ return _performers.getTokenPayload(user);
84
+ }
85
+ else {
86
+ return core_1.promise.createFailedPromise(core_1.ResponseError.getMessageResponse(400, 'Email performers not set in authentication settings.'));
87
+ }
88
+ }
89
+ authSettings.getTokenPayload = getTokenPayload;
90
+ })(authSettings || (exports.authSettings = authSettings = {}));
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@hapiboo/module-auth",
3
+ "version": "1.0.0",
4
+ "description": "MK13 Studio Hapiboo - Auth Module",
5
+ "author": "MK13 Studio",
6
+ "license": "ISC",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "dependencies": {
16
+ "@hapiboo/core": "^3.0.1",
17
+ "@hapiboo/crypto": "^3.0.0",
18
+ "@hapiboo/date": "^3.0.1",
19
+ "@hapiboo/flux": "^1.1.1",
20
+ "@hapiboo/server": "^3.0.0",
21
+ "express": "^5.2.1",
22
+ "jsonwebtoken": "^9.0.2",
23
+ "uuid": "^13.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/express": "^5.0.6",
27
+ "@types/jsonwebtoken": "^9.0.10",
28
+ "@typescript-eslint/eslint-plugin": "^8.51.0",
29
+ "@typescript-eslint/parser": "^8.51.0",
30
+ "eslint": "^9.39.2",
31
+ "typescript": "^5.9.3",
32
+ "typescript-eslint": "^8.51.0"
33
+ },
34
+ "scripts": {
35
+ "version-to-publish": "pnpm exec tsx ../../scripts/version_update.ts packages/_auth --publish-version",
36
+ "publish-check": "bash ../../scripts/publish.sh ./",
37
+ "version-to-children": "pnpm exec tsx ../../scripts/version_update.ts packages/_auth --update-children",
38
+ "ci:publish-prepare": "rm -f pnpm-lock.yaml && rm -rf node_modules dist && pnpm install --ignore-workspace --no-frozen-lockfile && eslint 'src/*.ts' && echo \"Linter OK\" && tsc && echo \"Build OK\"",
39
+ "ci:publish": "pnpm ci:publish-prepare && pnpm version-to-publish && pnpm publish-check && pnpm version-to-children"
40
+ }
41
+ }