@aeriajs/builtins 0.0.277 → 0.0.278
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/dist/authentication.js +6 -11
- package/dist/collections/file/description.js +10 -14
- package/dist/collections/file/download.js +21 -25
- package/dist/collections/file/index.js +15 -18
- package/dist/collections/file/insert.js +8 -12
- package/dist/collections/file/remove.js +7 -11
- package/dist/collections/file/removeAll.js +5 -9
- package/dist/collections/index.js +4 -20
- package/dist/collections/log/index.js +5 -8
- package/dist/collections/resourceUsage/index.js +2 -5
- package/dist/collections/user/activate.js +31 -35
- package/dist/collections/user/authenticate.js +29 -33
- package/dist/collections/user/createAccount.js +25 -29
- package/dist/collections/user/description.js +5 -8
- package/dist/collections/user/editProfile.js +12 -16
- package/dist/collections/user/getActivationLink.js +21 -26
- package/dist/collections/user/getCurrentUser.js +12 -16
- package/dist/collections/user/getInfo.js +22 -26
- package/dist/collections/user/getRedefinePasswordLink.js +15 -19
- package/dist/collections/user/index.d.ts +10 -10
- package/dist/collections/user/index.js +39 -42
- package/dist/collections/user/insert.js +16 -20
- package/dist/collections/user/redefinePassword.js +31 -35
- package/dist/functions/describe.js +21 -25
- package/dist/functions/index.js +1 -17
- package/dist/index.d.ts +15 -15
- package/dist/index.js +11 -29
- package/package.json +11 -17
- package/dist/authentication.mjs +0 -58
- package/dist/collections/file/description.mjs +0 -75
- package/dist/collections/file/download.mjs +0 -115
- package/dist/collections/file/index.mjs +0 -59
- package/dist/collections/file/insert.mjs +0 -44
- package/dist/collections/file/remove.mjs +0 -21
- package/dist/collections/file/removeAll.mjs +0 -22
- package/dist/collections/index.mjs +0 -5
- package/dist/collections/log/index.mjs +0 -55
- package/dist/collections/resourceUsage/index.mjs +0 -39
- package/dist/collections/user/activate.mjs +0 -119
- package/dist/collections/user/authenticate.mjs +0 -165
- package/dist/collections/user/createAccount.mjs +0 -93
- package/dist/collections/user/description.mjs +0 -149
- package/dist/collections/user/editProfile.mjs +0 -52
- package/dist/collections/user/getActivationLink.mjs +0 -88
- package/dist/collections/user/getCurrentUser.mjs +0 -57
- package/dist/collections/user/getInfo.mjs +0 -85
- package/dist/collections/user/getRedefinePasswordLink.mjs +0 -63
- package/dist/collections/user/index.mjs +0 -71
- package/dist/collections/user/insert.mjs +0 -70
- package/dist/collections/user/redefinePassword.mjs +0 -110
- package/dist/functions/describe.mjs +0 -95
- package/dist/functions/index.mjs +0 -2
- package/dist/index.mjs +0 -21
package/dist/authentication.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.defaultSuccessfulAuthentication = exports.successfulAuthentication = exports.AuthenticationError = void 0;
|
|
4
|
-
const core_1 = require("@aeriajs/core");
|
|
5
|
-
exports.AuthenticationError = {
|
|
1
|
+
import { signToken } from '@aeriajs/core';
|
|
2
|
+
export const AuthenticationError = {
|
|
6
3
|
InvalidCredentials: 'INVALID_CREDENTIALS',
|
|
7
4
|
InactiveUser: 'INACTIVE_USER',
|
|
8
5
|
};
|
|
9
|
-
const successfulAuthentication = async (user, context) => {
|
|
6
|
+
export const successfulAuthentication = async (user, context) => {
|
|
10
7
|
const tokenContent = {
|
|
11
8
|
sub: user._id,
|
|
12
9
|
roles: user.roles,
|
|
@@ -30,7 +27,7 @@ const successfulAuthentication = async (user, context) => {
|
|
|
30
27
|
}
|
|
31
28
|
tokenContent.userinfo = userinfo;
|
|
32
29
|
}
|
|
33
|
-
const token = await
|
|
30
|
+
const token = await signToken(tokenContent);
|
|
34
31
|
return {
|
|
35
32
|
user,
|
|
36
33
|
token: {
|
|
@@ -39,9 +36,8 @@ const successfulAuthentication = async (user, context) => {
|
|
|
39
36
|
},
|
|
40
37
|
};
|
|
41
38
|
};
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
const token = await (0, core_1.signToken)({
|
|
39
|
+
export const defaultSuccessfulAuthentication = async () => {
|
|
40
|
+
const token = await signToken({
|
|
45
41
|
sub: null,
|
|
46
42
|
roles: ['root'],
|
|
47
43
|
userinfo: {},
|
|
@@ -60,4 +56,3 @@ const defaultSuccessfulAuthentication = async () => {
|
|
|
60
56
|
},
|
|
61
57
|
};
|
|
62
58
|
};
|
|
63
|
-
exports.defaultSuccessfulAuthentication = defaultSuccessfulAuthentication;
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const mongodb_1 = require("mongodb");
|
|
5
|
-
const core_1 = require("@aeriajs/core");
|
|
6
|
-
const entrypoint_1 = require("@aeriajs/entrypoint");
|
|
1
|
+
import { ObjectId } from 'mongodb';
|
|
2
|
+
import { defineDescription } from '@aeriajs/core';
|
|
3
|
+
import { getConfig } from '@aeriajs/entrypoint';
|
|
7
4
|
const timestamp = (lastModified) => lastModified instanceof Date
|
|
8
5
|
? new Date(lastModified).getTime()
|
|
9
6
|
: 'fresh';
|
|
10
|
-
const getFileLink = async (fileId) => {
|
|
11
|
-
const config = await
|
|
7
|
+
export const getFileLink = async (fileId) => {
|
|
8
|
+
const config = await getConfig();
|
|
12
9
|
return `${config.publicUrl || ''}/file/${fileId}`;
|
|
13
10
|
};
|
|
14
|
-
|
|
15
|
-
exports.description = (0, core_1.defineDescription)({
|
|
11
|
+
export const description = defineDescription({
|
|
16
12
|
$id: 'file',
|
|
17
13
|
icon: 'paperclip',
|
|
18
14
|
owned: 'always',
|
|
@@ -49,16 +45,16 @@ exports.description = (0, core_1.defineDescription)({
|
|
|
49
45
|
link: {
|
|
50
46
|
type: 'getter',
|
|
51
47
|
getter: async (doc) => {
|
|
52
|
-
if ('_id' in doc && 'last_modified' in doc && doc._id instanceof
|
|
53
|
-
return `${await
|
|
48
|
+
if ('_id' in doc && 'last_modified' in doc && doc._id instanceof ObjectId) {
|
|
49
|
+
return `${await getFileLink(doc._id)}/${timestamp(doc.last_modified)}`;
|
|
54
50
|
}
|
|
55
51
|
},
|
|
56
52
|
},
|
|
57
53
|
download_link: {
|
|
58
54
|
type: 'getter',
|
|
59
55
|
getter: async (doc) => {
|
|
60
|
-
if ('_id' in doc && 'last_modified' in doc && doc._id instanceof
|
|
61
|
-
return `${await
|
|
56
|
+
if ('_id' in doc && 'last_modified' in doc && doc._id instanceof ObjectId) {
|
|
57
|
+
return `${await getFileLink(doc._id)}/download/${timestamp(doc.last_modified)}`;
|
|
62
58
|
}
|
|
63
59
|
},
|
|
64
60
|
},
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const core_1 = require("@aeriajs/core");
|
|
6
|
-
const fs = require("node:fs");
|
|
7
|
-
exports.DownloadError = {
|
|
1
|
+
import { HTTPStatus, ACError, defineContract, endpointErrorSchema } from '@aeriajs/types';
|
|
2
|
+
import { ObjectId } from '@aeriajs/core';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
export const DownloadError = {
|
|
8
5
|
RangeNotSatisfiable: 'RANGE_NOT_SATISFIABLE',
|
|
9
6
|
};
|
|
10
|
-
|
|
7
|
+
export const downloadContract = defineContract({
|
|
11
8
|
payload: {
|
|
12
9
|
type: 'object',
|
|
13
10
|
required: ['fileId'],
|
|
@@ -30,14 +27,14 @@ exports.downloadContract = (0, types_1.defineContract)({
|
|
|
30
27
|
},
|
|
31
28
|
},
|
|
32
29
|
response: [
|
|
33
|
-
|
|
30
|
+
endpointErrorSchema({
|
|
34
31
|
httpStatus: [
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
HTTPStatus.NotFound,
|
|
33
|
+
HTTPStatus.RangeNotSatisfiable,
|
|
37
34
|
],
|
|
38
35
|
code: [
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
ACError.ResourceNotFound,
|
|
37
|
+
DownloadError.RangeNotSatisfiable,
|
|
41
38
|
],
|
|
42
39
|
}),
|
|
43
40
|
{
|
|
@@ -46,10 +43,10 @@ exports.downloadContract = (0, types_1.defineContract)({
|
|
|
46
43
|
},
|
|
47
44
|
],
|
|
48
45
|
});
|
|
49
|
-
const download = async (payload, context) => {
|
|
46
|
+
export const download = async (payload, context) => {
|
|
50
47
|
const { fileId, options = [] } = payload;
|
|
51
48
|
const file = await context.collection.model.findOne({
|
|
52
|
-
_id: new
|
|
49
|
+
_id: new ObjectId(fileId),
|
|
53
50
|
}, {
|
|
54
51
|
projection: {
|
|
55
52
|
absolute_path: 1,
|
|
@@ -59,12 +56,12 @@ const download = async (payload, context) => {
|
|
|
59
56
|
});
|
|
60
57
|
if (!file) {
|
|
61
58
|
if (!payload.noHeaders) {
|
|
62
|
-
context.response.writeHead(
|
|
59
|
+
context.response.writeHead(HTTPStatus.NotFound, {
|
|
63
60
|
'content-type': 'application/json',
|
|
64
61
|
});
|
|
65
62
|
}
|
|
66
|
-
return context.error(
|
|
67
|
-
code:
|
|
63
|
+
return context.error(HTTPStatus.NotFound, {
|
|
64
|
+
code: ACError.ResourceNotFound,
|
|
68
65
|
});
|
|
69
66
|
}
|
|
70
67
|
let stat;
|
|
@@ -75,8 +72,8 @@ const download = async (payload, context) => {
|
|
|
75
72
|
context.response.writeHead(404, {
|
|
76
73
|
'content-type': 'application/json',
|
|
77
74
|
});
|
|
78
|
-
return context.error(
|
|
79
|
-
code:
|
|
75
|
+
return context.error(HTTPStatus.NotFound, {
|
|
76
|
+
code: ACError.ResourceNotFound,
|
|
80
77
|
});
|
|
81
78
|
}
|
|
82
79
|
const range = context.request.headers.range;
|
|
@@ -87,12 +84,12 @@ const download = async (payload, context) => {
|
|
|
87
84
|
? parseInt(parts[1])
|
|
88
85
|
: stat.size - 1;
|
|
89
86
|
if (start >= stat.size || end >= stat.size) {
|
|
90
|
-
context.response.writeHead(
|
|
87
|
+
context.response.writeHead(HTTPStatus.RangeNotSatisfiable, {
|
|
91
88
|
'content-type': 'application/json',
|
|
92
89
|
'content-range': `bytes */${stat.size}`,
|
|
93
90
|
});
|
|
94
|
-
return context.error(
|
|
95
|
-
code:
|
|
91
|
+
return context.error(HTTPStatus.RangeNotSatisfiable, {
|
|
92
|
+
code: DownloadError.RangeNotSatisfiable,
|
|
96
93
|
});
|
|
97
94
|
}
|
|
98
95
|
const chunkSize = (end - start) + 1;
|
|
@@ -113,7 +110,7 @@ const download = async (payload, context) => {
|
|
|
113
110
|
});
|
|
114
111
|
}
|
|
115
112
|
if (!payload.noHeaders) {
|
|
116
|
-
context.response.writeHead(
|
|
113
|
+
context.response.writeHead(HTTPStatus.Ok, {
|
|
117
114
|
'content-type': file.type,
|
|
118
115
|
'content-disposition': `${options.includes('download')
|
|
119
116
|
? 'attachment; '
|
|
@@ -122,4 +119,3 @@ const download = async (payload, context) => {
|
|
|
122
119
|
}
|
|
123
120
|
return fs.createReadStream(file.absolute_path);
|
|
124
121
|
};
|
|
125
|
-
exports.download = download;
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const remove_js_1 = require("./remove.js");
|
|
9
|
-
const removeAll_js_1 = require("./removeAll.js");
|
|
10
|
-
exports.tempFile = (0, core_1.defineCollection)({
|
|
1
|
+
import { defineCollection, get } from '@aeriajs/core';
|
|
2
|
+
import { description } from './description.js';
|
|
3
|
+
import { insert } from './insert.js';
|
|
4
|
+
import { download, downloadContract } from './download.js';
|
|
5
|
+
import { remove } from './remove.js';
|
|
6
|
+
import { removeAll } from './removeAll.js';
|
|
7
|
+
export const tempFile = defineCollection({
|
|
11
8
|
description: {
|
|
12
9
|
$id: 'tempFile',
|
|
13
10
|
icon: 'file',
|
|
@@ -39,14 +36,14 @@ exports.tempFile = (0, core_1.defineCollection)({
|
|
|
39
36
|
},
|
|
40
37
|
},
|
|
41
38
|
});
|
|
42
|
-
|
|
43
|
-
description
|
|
39
|
+
export const file = defineCollection({
|
|
40
|
+
description,
|
|
44
41
|
functions: {
|
|
45
|
-
get
|
|
46
|
-
insert
|
|
47
|
-
download
|
|
48
|
-
remove
|
|
49
|
-
removeAll
|
|
42
|
+
get,
|
|
43
|
+
insert,
|
|
44
|
+
download,
|
|
45
|
+
remove,
|
|
46
|
+
removeAll,
|
|
50
47
|
},
|
|
51
48
|
exposedFunctions: {
|
|
52
49
|
get: 'unauthenticated',
|
|
@@ -56,6 +53,6 @@ exports.file = (0, core_1.defineCollection)({
|
|
|
56
53
|
removeAll: true,
|
|
57
54
|
},
|
|
58
55
|
contracts: {
|
|
59
|
-
download:
|
|
56
|
+
download: downloadContract,
|
|
60
57
|
},
|
|
61
58
|
});
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const promises_1 = require("node:fs/promises");
|
|
6
|
-
const core_1 = require("@aeriajs/core");
|
|
7
|
-
const insert = async (payload, context) => {
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { writeFile, unlink } from 'node:fs/promises';
|
|
3
|
+
import { insert as originalInsert } from '@aeriajs/core';
|
|
4
|
+
export const insert = async (payload, context) => {
|
|
8
5
|
if (!context.token.authenticated) {
|
|
9
6
|
throw new Error('');
|
|
10
7
|
}
|
|
@@ -31,16 +28,15 @@ const insert = async (payload, context) => {
|
|
|
31
28
|
},
|
|
32
29
|
});
|
|
33
30
|
if (oldFile && oldFile.absolute_path) {
|
|
34
|
-
await
|
|
31
|
+
await unlink(oldFile.absolute_path).catch(console.trace);
|
|
35
32
|
}
|
|
36
|
-
const filenameHash =
|
|
33
|
+
const filenameHash = createHash('sha1')
|
|
37
34
|
.update(what.name + Date.now())
|
|
38
35
|
.digest('hex');
|
|
39
36
|
what.absolute_path = `${tempPath}/${filenameHash}.${extension}`;
|
|
40
|
-
await
|
|
41
|
-
return (
|
|
37
|
+
await writeFile(what.absolute_path, Buffer.from(content.split(',').at(-1), 'base64'));
|
|
38
|
+
return originalInsert({
|
|
42
39
|
...payload,
|
|
43
40
|
what,
|
|
44
41
|
}, context);
|
|
45
42
|
};
|
|
46
|
-
exports.insert = insert;
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const fs = require("node:fs/promises");
|
|
7
|
-
const remove = async (payload, context) => {
|
|
8
|
-
const { error, result: file } = await (0, core_1.get)({
|
|
1
|
+
import { Result } from '@aeriajs/types';
|
|
2
|
+
import { remove as originalRemove, get } from '@aeriajs/core';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
export const remove = async (payload, context) => {
|
|
5
|
+
const { error, result: file } = await get({
|
|
9
6
|
filters: {
|
|
10
7
|
_id: payload.filters._id,
|
|
11
8
|
},
|
|
12
9
|
project: ['absolute_path'],
|
|
13
10
|
}, context);
|
|
14
11
|
if (error) {
|
|
15
|
-
return
|
|
12
|
+
return Result.error(error);
|
|
16
13
|
}
|
|
17
14
|
try {
|
|
18
15
|
await fs.unlink(file.absolute_path);
|
|
@@ -20,6 +17,5 @@ const remove = async (payload, context) => {
|
|
|
20
17
|
catch (err) {
|
|
21
18
|
console.trace(err);
|
|
22
19
|
}
|
|
23
|
-
return (
|
|
20
|
+
return originalRemove(payload, context);
|
|
24
21
|
};
|
|
25
|
-
exports.remove = remove;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const core_1 = require("@aeriajs/core");
|
|
5
|
-
const fs = require("node:fs/promises");
|
|
6
|
-
const removeAll = async (payload, context) => {
|
|
1
|
+
import { ObjectId, removeAll as originalRemoveAll } from '@aeriajs/core';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
export const removeAll = async (payload, context) => {
|
|
7
4
|
const files = context.collection.model.find({
|
|
8
5
|
_id: {
|
|
9
|
-
$in: payload.filters.map((oid) => new
|
|
6
|
+
$in: payload.filters.map((oid) => new ObjectId(oid)),
|
|
10
7
|
},
|
|
11
8
|
}, {
|
|
12
9
|
projection: {
|
|
@@ -21,6 +18,5 @@ const removeAll = async (payload, context) => {
|
|
|
21
18
|
console.trace(err);
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
|
-
return (
|
|
21
|
+
return originalRemoveAll(payload, context);
|
|
25
22
|
};
|
|
26
|
-
exports.removeAll = removeAll;
|
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./file/index.js"), exports);
|
|
18
|
-
__exportStar(require("./log/index.js"), exports);
|
|
19
|
-
__exportStar(require("./resourceUsage/index.js"), exports);
|
|
20
|
-
__exportStar(require("./user/index.js"), exports);
|
|
1
|
+
export * from './file/index.js';
|
|
2
|
+
export * from './log/index.js';
|
|
3
|
+
export * from './resourceUsage/index.js';
|
|
4
|
+
export * from './user/index.js';
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.log = void 0;
|
|
4
|
-
const core_1 = require("@aeriajs/core");
|
|
5
|
-
exports.log = (0, core_1.defineCollection)({
|
|
1
|
+
import { defineCollection, get, getAll, insert } from '@aeriajs/core';
|
|
2
|
+
export const log = defineCollection({
|
|
6
3
|
description: {
|
|
7
4
|
$id: 'log',
|
|
8
5
|
icon: 'magnifying-glass',
|
|
@@ -45,9 +42,9 @@ exports.log = (0, core_1.defineCollection)({
|
|
|
45
42
|
],
|
|
46
43
|
},
|
|
47
44
|
functions: {
|
|
48
|
-
get
|
|
49
|
-
getAll
|
|
50
|
-
insert
|
|
45
|
+
get,
|
|
46
|
+
getAll,
|
|
47
|
+
insert,
|
|
51
48
|
},
|
|
52
49
|
exposedFunctions: {
|
|
53
50
|
get: true,
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.resourceUsage = void 0;
|
|
4
|
-
const core_1 = require("@aeriajs/core");
|
|
5
|
-
exports.resourceUsage = (0, core_1.defineCollection)({
|
|
1
|
+
import { defineCollection } from '@aeriajs/core';
|
|
2
|
+
export const resourceUsage = defineCollection({
|
|
6
3
|
description: {
|
|
7
4
|
$id: 'resourceUsage',
|
|
8
5
|
icon: 'wrench',
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const types_1 = require("@aeriajs/types");
|
|
6
|
-
const bcrypt = require("bcryptjs");
|
|
7
|
-
exports.ActivationError = {
|
|
1
|
+
import { decodeToken, ObjectId } from '@aeriajs/core';
|
|
2
|
+
import { Result, ACError, HTTPStatus, defineContract, resultSchema, endpointErrorSchema } from '@aeriajs/types';
|
|
3
|
+
import * as bcrypt from 'bcryptjs';
|
|
4
|
+
export const ActivationError = {
|
|
8
5
|
UserNotFound: 'USER_NOT_FOUND',
|
|
9
6
|
AlreadyActiveUser: 'ALREADY_ACTIVE_USER',
|
|
10
7
|
InvalidLink: 'INVALID_LINK',
|
|
11
8
|
InvalidToken: 'INVALID_TOKEN',
|
|
12
9
|
};
|
|
13
|
-
|
|
10
|
+
export const activateContract = defineContract({
|
|
14
11
|
payload: {
|
|
15
12
|
type: 'object',
|
|
16
13
|
required: [],
|
|
@@ -27,23 +24,23 @@ exports.activateContract = (0, types_1.defineContract)({
|
|
|
27
24
|
},
|
|
28
25
|
},
|
|
29
26
|
response: [
|
|
30
|
-
|
|
27
|
+
endpointErrorSchema({
|
|
31
28
|
httpStatus: [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
HTTPStatus.NotFound,
|
|
30
|
+
HTTPStatus.Forbidden,
|
|
31
|
+
HTTPStatus.Unauthorized,
|
|
32
|
+
HTTPStatus.UnprocessableContent,
|
|
36
33
|
],
|
|
37
34
|
code: [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
ACError.ResourceNotFound,
|
|
36
|
+
ACError.MalformedInput,
|
|
37
|
+
ActivationError.AlreadyActiveUser,
|
|
38
|
+
ActivationError.InvalidLink,
|
|
39
|
+
ActivationError.InvalidToken,
|
|
40
|
+
ActivationError.UserNotFound,
|
|
44
41
|
],
|
|
45
42
|
}),
|
|
46
|
-
|
|
43
|
+
resultSchema({
|
|
47
44
|
type: 'object',
|
|
48
45
|
properties: {
|
|
49
46
|
userId: {
|
|
@@ -54,18 +51,18 @@ exports.activateContract = (0, types_1.defineContract)({
|
|
|
54
51
|
}),
|
|
55
52
|
],
|
|
56
53
|
});
|
|
57
|
-
const activate = async (payload, context) => {
|
|
54
|
+
export const activate = async (payload, context) => {
|
|
58
55
|
const { userId, token, password, } = payload;
|
|
59
56
|
if (!context.config.secret) {
|
|
60
57
|
throw new Error('config.secret is not set');
|
|
61
58
|
}
|
|
62
59
|
if (!userId || !token) {
|
|
63
|
-
return context.error(
|
|
64
|
-
code:
|
|
60
|
+
return context.error(HTTPStatus.NotFound, {
|
|
61
|
+
code: ActivationError.InvalidLink,
|
|
65
62
|
});
|
|
66
63
|
}
|
|
67
64
|
const user = await context.collection.model.findOne({
|
|
68
|
-
_id: new
|
|
65
|
+
_id: new ObjectId(userId),
|
|
69
66
|
}, {
|
|
70
67
|
projection: {
|
|
71
68
|
password: 1,
|
|
@@ -73,25 +70,25 @@ const activate = async (payload, context) => {
|
|
|
73
70
|
},
|
|
74
71
|
});
|
|
75
72
|
if (!user) {
|
|
76
|
-
return context.error(
|
|
77
|
-
code:
|
|
73
|
+
return context.error(HTTPStatus.NotFound, {
|
|
74
|
+
code: ActivationError.UserNotFound,
|
|
78
75
|
});
|
|
79
76
|
}
|
|
80
77
|
if (user.active) {
|
|
81
|
-
return context.error(
|
|
82
|
-
code:
|
|
78
|
+
return context.error(HTTPStatus.Forbidden, {
|
|
79
|
+
code: ActivationError.AlreadyActiveUser,
|
|
83
80
|
});
|
|
84
81
|
}
|
|
85
|
-
const decoded = await
|
|
82
|
+
const decoded = await decodeToken(token, context.config.secret);
|
|
86
83
|
if (!decoded) {
|
|
87
|
-
return context.error(
|
|
88
|
-
code:
|
|
84
|
+
return context.error(HTTPStatus.Unauthorized, {
|
|
85
|
+
code: ActivationError.InvalidToken,
|
|
89
86
|
});
|
|
90
87
|
}
|
|
91
88
|
if (!user.password) {
|
|
92
89
|
if (!password) {
|
|
93
|
-
return context.error(
|
|
94
|
-
code:
|
|
90
|
+
return context.error(HTTPStatus.UnprocessableContent, {
|
|
91
|
+
code: ACError.MalformedInput,
|
|
95
92
|
});
|
|
96
93
|
}
|
|
97
94
|
await context.collection.model.updateOne({
|
|
@@ -112,8 +109,7 @@ const activate = async (payload, context) => {
|
|
|
112
109
|
},
|
|
113
110
|
});
|
|
114
111
|
}
|
|
115
|
-
return
|
|
112
|
+
return Result.result({
|
|
116
113
|
userId: user._id,
|
|
117
114
|
});
|
|
118
115
|
};
|
|
119
|
-
exports.activate = activate;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const common_1 = require("@aeriajs/common");
|
|
8
|
-
const authentication_js_1 = require("../../authentication.js");
|
|
9
|
-
exports.authenticateContract = (0, types_1.defineContract)({
|
|
1
|
+
import { Result, HTTPStatus, ACError, defineContract, endpointErrorSchema, resultSchema } from '@aeriajs/types';
|
|
2
|
+
import { compare as bcryptCompare } from 'bcryptjs';
|
|
3
|
+
import { decodeToken, get } from '@aeriajs/core';
|
|
4
|
+
import { throwIfError } from '@aeriajs/common';
|
|
5
|
+
import { successfulAuthentication, defaultSuccessfulAuthentication, AuthenticationError } from '../../authentication.js';
|
|
6
|
+
export const authenticateContract = defineContract({
|
|
10
7
|
payload: {
|
|
11
8
|
type: 'object',
|
|
12
9
|
required: [],
|
|
@@ -34,15 +31,15 @@ exports.authenticateContract = (0, types_1.defineContract)({
|
|
|
34
31
|
},
|
|
35
32
|
},
|
|
36
33
|
response: [
|
|
37
|
-
|
|
38
|
-
httpStatus: [
|
|
34
|
+
endpointErrorSchema({
|
|
35
|
+
httpStatus: [HTTPStatus.Unauthorized],
|
|
39
36
|
code: [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
ACError.AuthorizationError,
|
|
38
|
+
AuthenticationError.InvalidCredentials,
|
|
39
|
+
AuthenticationError.InactiveUser,
|
|
43
40
|
],
|
|
44
41
|
}),
|
|
45
|
-
|
|
42
|
+
resultSchema({
|
|
46
43
|
type: 'object',
|
|
47
44
|
properties: {
|
|
48
45
|
user: {
|
|
@@ -61,7 +58,7 @@ exports.authenticateContract = (0, types_1.defineContract)({
|
|
|
61
58
|
},
|
|
62
59
|
},
|
|
63
60
|
}),
|
|
64
|
-
|
|
61
|
+
resultSchema({
|
|
65
62
|
type: 'object',
|
|
66
63
|
properties: {
|
|
67
64
|
user: {
|
|
@@ -102,19 +99,19 @@ exports.authenticateContract = (0, types_1.defineContract)({
|
|
|
102
99
|
}),
|
|
103
100
|
],
|
|
104
101
|
});
|
|
105
|
-
const authenticate = async (props, context) => {
|
|
102
|
+
export const authenticate = async (props, context) => {
|
|
106
103
|
if ('revalidate' in props) {
|
|
107
104
|
const { token } = props;
|
|
108
105
|
if (!token && !context.token.authenticated) {
|
|
109
|
-
return context.error(
|
|
110
|
-
code:
|
|
106
|
+
return context.error(HTTPStatus.Unauthorized, {
|
|
107
|
+
code: ACError.AuthorizationError,
|
|
111
108
|
});
|
|
112
109
|
}
|
|
113
110
|
const decodedToken = token
|
|
114
|
-
? await
|
|
111
|
+
? await decodeToken(token.content)
|
|
115
112
|
: context.token;
|
|
116
113
|
if (!decodedToken.sub) {
|
|
117
|
-
return
|
|
114
|
+
return Result.result(await defaultSuccessfulAuthentication());
|
|
118
115
|
}
|
|
119
116
|
const { error, result: user } = await context.collections.user.functions.get({
|
|
120
117
|
filters: {
|
|
@@ -126,16 +123,16 @@ const authenticate = async (props, context) => {
|
|
|
126
123
|
if (error) {
|
|
127
124
|
throw new Error();
|
|
128
125
|
}
|
|
129
|
-
return
|
|
126
|
+
return Result.result(await successfulAuthentication(user, context));
|
|
130
127
|
}
|
|
131
128
|
if (!props.email || !props.password) {
|
|
132
|
-
return context.error(
|
|
133
|
-
code:
|
|
129
|
+
return context.error(HTTPStatus.Unauthorized, {
|
|
130
|
+
code: AuthenticationError.InvalidCredentials,
|
|
134
131
|
});
|
|
135
132
|
}
|
|
136
133
|
if (context.config.defaultUser) {
|
|
137
134
|
if (props.email === context.config.defaultUser.username && props.password === context.config.defaultUser.password) {
|
|
138
|
-
return
|
|
135
|
+
return Result.result(await defaultSuccessfulAuthentication());
|
|
139
136
|
}
|
|
140
137
|
}
|
|
141
138
|
const user = await context.collection.model.findOne({
|
|
@@ -146,22 +143,21 @@ const authenticate = async (props, context) => {
|
|
|
146
143
|
active: 1,
|
|
147
144
|
},
|
|
148
145
|
});
|
|
149
|
-
if (!user || !user.password || !await (
|
|
150
|
-
return context.error(
|
|
151
|
-
code:
|
|
146
|
+
if (!user || !user.password || !await bcryptCompare(props.password, user.password)) {
|
|
147
|
+
return context.error(HTTPStatus.Unauthorized, {
|
|
148
|
+
code: AuthenticationError.InvalidCredentials,
|
|
152
149
|
});
|
|
153
150
|
}
|
|
154
151
|
if (!user.active) {
|
|
155
|
-
return context.error(
|
|
156
|
-
code:
|
|
152
|
+
return context.error(HTTPStatus.Unauthorized, {
|
|
153
|
+
code: AuthenticationError.InactiveUser,
|
|
157
154
|
});
|
|
158
155
|
}
|
|
159
|
-
const completeUser =
|
|
156
|
+
const completeUser = throwIfError(await get({
|
|
160
157
|
filters: {
|
|
161
158
|
_id: user._id,
|
|
162
159
|
},
|
|
163
160
|
populate: ['picture_file'],
|
|
164
161
|
}, context));
|
|
165
|
-
return
|
|
162
|
+
return Result.result(await successfulAuthentication(completeUser, context));
|
|
166
163
|
};
|
|
167
|
-
exports.authenticate = authenticate;
|