@nymphjs/tilmeld 1.0.0-alpha.1 → 1.0.0-alpha.5
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/CHANGELOG.md +26 -0
- package/README.md +15 -10
- package/dist/Group.d.ts +2 -0
- package/dist/Group.js +68 -59
- package/dist/Group.js.map +1 -1
- package/dist/Group.test.js +12 -7
- package/dist/Group.test.js.map +1 -1
- package/dist/Tilmeld.d.ts +26 -22
- package/dist/Tilmeld.js +172 -92
- package/dist/Tilmeld.js.map +1 -1
- package/dist/User.d.ts +2 -0
- package/dist/User.js +134 -122
- package/dist/User.js.map +1 -1
- package/dist/User.test.js +12 -7
- package/dist/User.test.js.map +1 -1
- package/dist/conf/d.d.ts +7 -3
- package/dist/conf/defaults.js +41 -109
- package/dist/conf/defaults.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/tilmeldJoiProps.d.ts +12 -0
- package/dist/tilmeldJoiProps.js +20 -0
- package/dist/tilmeldJoiProps.js.map +1 -0
- package/package.json +6 -6
- package/src/Group.test.ts +18 -7
- package/src/Group.ts +88 -64
- package/src/Tilmeld.ts +284 -116
- package/src/User.test.ts +18 -7
- package/src/User.ts +164 -125
- package/src/conf/d.ts +38 -2
- package/src/conf/defaults.ts +29 -68
- package/src/index.ts +3 -1
- package/src/tilmeldJoiProps.ts +46 -0
package/src/conf/d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { EmailOptions } from 'email-templates';
|
|
2
|
+
|
|
3
|
+
import type Tilmeld from '../Tilmeld';
|
|
2
4
|
import Group, { GroupData } from '../Group';
|
|
3
5
|
import User, { UserData } from '../User';
|
|
4
6
|
|
|
@@ -63,6 +65,35 @@ export interface Config {
|
|
|
63
65
|
* a concern. Same risks as user search if generatePrimary is true.)
|
|
64
66
|
*/
|
|
65
67
|
enableGroupSearch: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* A list of UIDs that can be read from the client by anyone. (getUID)
|
|
70
|
+
*
|
|
71
|
+
* Note: If you'd like to limit the access to logged in users, give them an
|
|
72
|
+
* ability like "uid/get/nameofuid".
|
|
73
|
+
*/
|
|
74
|
+
clientReadableUIDs: string[];
|
|
75
|
+
/**
|
|
76
|
+
* A list of UIDs that can be created from the client by anyone. (newUID)
|
|
77
|
+
*
|
|
78
|
+
* Inclusion in this list implies inclusion in clientReadableUIDs.
|
|
79
|
+
*
|
|
80
|
+
* Note: If you'd like to limit the access to logged in users, give them an
|
|
81
|
+
* ability like "uid/new/nameofuid".
|
|
82
|
+
*/
|
|
83
|
+
clientEnabledUIDs: string[];
|
|
84
|
+
/**
|
|
85
|
+
* A list of UIDs that can be set from the client by anyone. (setUID,
|
|
86
|
+
* renameUID)
|
|
87
|
+
*
|
|
88
|
+
* Inclusion in this list implies inclusion in clientReadableUIDs and
|
|
89
|
+
* clientEnabledUIDs.
|
|
90
|
+
*
|
|
91
|
+
* Note: There is no way to run renameUID from the client.
|
|
92
|
+
*
|
|
93
|
+
* Note: If you'd like to limit the access to logged in users, give them an
|
|
94
|
+
* ability like "uid/set/nameofuid".
|
|
95
|
+
*/
|
|
96
|
+
clientSetabledUIDs: string[];
|
|
66
97
|
/**
|
|
67
98
|
* These will be the available fields for users. (Some fields, like username,
|
|
68
99
|
* can't be excluded.)
|
|
@@ -194,7 +225,7 @@ export interface Config {
|
|
|
194
225
|
/**
|
|
195
226
|
* Function to build the JWT for user sessions.
|
|
196
227
|
*/
|
|
197
|
-
jwtBuilder: (user: User) => string;
|
|
228
|
+
jwtBuilder: (config: Config, user: User) => string;
|
|
198
229
|
/**
|
|
199
230
|
* Function to verify that a JWT was signed with the secret key, vaildate its
|
|
200
231
|
* data, validate the XSRF token, and extract the GUID.
|
|
@@ -205,6 +236,7 @@ export interface Config {
|
|
|
205
236
|
* timestamp otherwise.
|
|
206
237
|
*/
|
|
207
238
|
jwtExtract: (
|
|
239
|
+
config: Config,
|
|
208
240
|
token: string,
|
|
209
241
|
xsrfToken?: string
|
|
210
242
|
) => { guid: string; expire: Date } | null;
|
|
@@ -238,7 +270,11 @@ export interface Config {
|
|
|
238
270
|
* - lastName
|
|
239
271
|
* - email
|
|
240
272
|
*/
|
|
241
|
-
sendEmail: (
|
|
273
|
+
sendEmail: (
|
|
274
|
+
tilmeld: Tilmeld,
|
|
275
|
+
options: EmailOptions,
|
|
276
|
+
user: User & UserData
|
|
277
|
+
) => Promise<boolean>;
|
|
242
278
|
/**
|
|
243
279
|
* The address you'd like to receive a notification of registered users, if
|
|
244
280
|
* any.
|
package/src/conf/defaults.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { nymphJoiProps } from '@nymphjs/nymph';
|
|
1
2
|
import path from 'path';
|
|
2
3
|
import jwt from 'jsonwebtoken';
|
|
3
4
|
import { nanoid } from 'nanoid';
|
|
4
|
-
import Email
|
|
5
|
+
import Email from 'email-templates';
|
|
5
6
|
import Joi from 'joi';
|
|
6
7
|
|
|
7
|
-
import Tilmeld from '../Tilmeld';
|
|
8
8
|
import { Config } from './d';
|
|
9
|
-
import User
|
|
9
|
+
import User from '../User';
|
|
10
10
|
import Group from '../Group';
|
|
11
11
|
|
|
12
12
|
export default {
|
|
@@ -21,6 +21,9 @@ export default {
|
|
|
21
21
|
allowUsernameChange: true,
|
|
22
22
|
enableUserSearch: false,
|
|
23
23
|
enableGroupSearch: false,
|
|
24
|
+
clientReadableUIDs: [],
|
|
25
|
+
clientEnabledUIDs: [],
|
|
26
|
+
clientSetabledUIDs: [],
|
|
24
27
|
userFields: ['name', 'email', 'phone'],
|
|
25
28
|
regFields: ['name', 'email'],
|
|
26
29
|
verifyEmail: true,
|
|
@@ -49,32 +52,32 @@ export default {
|
|
|
49
52
|
jwtSecret: '',
|
|
50
53
|
jwtExpire: 60 * 60 * 24 * 7 * 8, // 8 weeks(ish)
|
|
51
54
|
jwtRenew: 60 * 60 * 24 * 7 * 2, // 2 weeks(ish)
|
|
52
|
-
jwtBuilder: (user) => {
|
|
53
|
-
const secret =
|
|
55
|
+
jwtBuilder: (config, user) => {
|
|
56
|
+
const secret = config.jwtSecret;
|
|
54
57
|
if (secret === '') {
|
|
55
58
|
throw new Error('JWT secret is not configured.');
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
return jwt.sign(
|
|
59
62
|
{
|
|
60
|
-
iss:
|
|
63
|
+
iss: config.appUrl,
|
|
61
64
|
nbf: Date.now() / 1000,
|
|
62
65
|
guid: user.guid,
|
|
63
66
|
xsrfToken: 'TILMELDXSRF-' + nanoid(),
|
|
64
67
|
},
|
|
65
68
|
secret,
|
|
66
|
-
{ expiresIn:
|
|
69
|
+
{ expiresIn: config.jwtExpire }
|
|
67
70
|
);
|
|
68
71
|
},
|
|
69
|
-
jwtExtract: (token, xsrfToken?) => {
|
|
70
|
-
const secret =
|
|
72
|
+
jwtExtract: (config, token, xsrfToken?) => {
|
|
73
|
+
const secret = config.jwtSecret;
|
|
71
74
|
if (secret === '') {
|
|
72
75
|
throw new Error('JWT secret is not configured.');
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
try {
|
|
76
79
|
const payload = jwt.verify(token, secret, {
|
|
77
|
-
issuer:
|
|
80
|
+
issuer: config.appUrl,
|
|
78
81
|
clockTolerance: 10,
|
|
79
82
|
});
|
|
80
83
|
|
|
@@ -104,12 +107,12 @@ export default {
|
|
|
104
107
|
}
|
|
105
108
|
},
|
|
106
109
|
emailTemplateDir: path.join(__dirname, '..', '..', 'emails'),
|
|
107
|
-
sendEmail: async (options
|
|
108
|
-
const appUrl = new URL(
|
|
110
|
+
sendEmail: async (tilmeld, options, user) => {
|
|
111
|
+
const appUrl = new URL(tilmeld.config.appUrl);
|
|
109
112
|
const email = new Email({
|
|
110
113
|
message: {
|
|
111
114
|
from: {
|
|
112
|
-
name:
|
|
115
|
+
name: tilmeld.config.appName,
|
|
113
116
|
address: `noreply@${appUrl.hostname}`,
|
|
114
117
|
},
|
|
115
118
|
},
|
|
@@ -118,13 +121,13 @@ export default {
|
|
|
118
121
|
const result = await email.send({
|
|
119
122
|
...options,
|
|
120
123
|
template: path.join(
|
|
121
|
-
|
|
124
|
+
tilmeld.config.emailTemplateDir,
|
|
122
125
|
options.template ?? '.'
|
|
123
126
|
),
|
|
124
127
|
locals: {
|
|
125
128
|
// System
|
|
126
|
-
siteName:
|
|
127
|
-
siteLink:
|
|
129
|
+
siteName: tilmeld.config.appName,
|
|
130
|
+
siteLink: tilmeld.config.appUrl,
|
|
128
131
|
// Recipient
|
|
129
132
|
toUsername: user.username ?? '',
|
|
130
133
|
toName: user.name ?? '',
|
|
@@ -133,13 +136,13 @@ export default {
|
|
|
133
136
|
toEmail: user.email ?? '',
|
|
134
137
|
toPhone: user.phone ?? '',
|
|
135
138
|
// Current User with Tilmeld.
|
|
136
|
-
...(User.current()
|
|
139
|
+
...(tilmeld.User.current()
|
|
137
140
|
? {
|
|
138
|
-
username: User.current(true).username,
|
|
139
|
-
name: User.current(true).name,
|
|
140
|
-
firstName: User.current(true).nameFirst,
|
|
141
|
-
lastName: User.current(true).nameLast,
|
|
142
|
-
email: User.current(true).email,
|
|
141
|
+
username: tilmeld.User.current(true).username,
|
|
142
|
+
name: tilmeld.User.current(true).name,
|
|
143
|
+
firstName: tilmeld.User.current(true).nameFirst,
|
|
144
|
+
lastName: tilmeld.User.current(true).nameLast,
|
|
145
|
+
email: tilmeld.User.current(true).email,
|
|
143
146
|
}
|
|
144
147
|
: {}),
|
|
145
148
|
...options.locals,
|
|
@@ -151,32 +154,11 @@ export default {
|
|
|
151
154
|
}
|
|
152
155
|
},
|
|
153
156
|
userRegisteredRecipient: null,
|
|
154
|
-
validatorGroup: (group
|
|
157
|
+
validatorGroup: (group) => {
|
|
155
158
|
Joi.attempt(
|
|
156
159
|
group.$getValidatable(),
|
|
157
160
|
Joi.object().keys({
|
|
158
|
-
|
|
159
|
-
.try(
|
|
160
|
-
Joi.any().only().allow(null),
|
|
161
|
-
Joi.string().trim(false).length(24).hex()
|
|
162
|
-
)
|
|
163
|
-
.required(),
|
|
164
|
-
cdate: Joi.alternatives()
|
|
165
|
-
.try(Joi.any().only().allow(null), Joi.number())
|
|
166
|
-
.required(),
|
|
167
|
-
mdate: Joi.alternatives()
|
|
168
|
-
.try(Joi.any().only().allow(null), Joi.number())
|
|
169
|
-
.required(),
|
|
170
|
-
tags: Joi.array()
|
|
171
|
-
.items(
|
|
172
|
-
Joi.string()
|
|
173
|
-
.pattern(/[\x01-\x1F\x7F]/, {
|
|
174
|
-
name: 'control characters',
|
|
175
|
-
invert: true,
|
|
176
|
-
})
|
|
177
|
-
.min(1)
|
|
178
|
-
)
|
|
179
|
-
.required(),
|
|
161
|
+
...nymphJoiProps,
|
|
180
162
|
groupname: Joi.string().trim(false).min(1).required(),
|
|
181
163
|
enabled: Joi.boolean().required(),
|
|
182
164
|
email: Joi.string()
|
|
@@ -222,32 +204,11 @@ export default {
|
|
|
222
204
|
'Invalid Group: '
|
|
223
205
|
);
|
|
224
206
|
},
|
|
225
|
-
validatorUser: (user
|
|
207
|
+
validatorUser: (user) => {
|
|
226
208
|
Joi.attempt(
|
|
227
209
|
user.$getValidatable(),
|
|
228
210
|
Joi.object().keys({
|
|
229
|
-
|
|
230
|
-
.try(
|
|
231
|
-
Joi.any().only().allow(null),
|
|
232
|
-
Joi.string().trim(false).length(24).hex()
|
|
233
|
-
)
|
|
234
|
-
.required(),
|
|
235
|
-
cdate: Joi.alternatives()
|
|
236
|
-
.try(Joi.any().only().allow(null), Joi.number())
|
|
237
|
-
.required(),
|
|
238
|
-
mdate: Joi.alternatives()
|
|
239
|
-
.try(Joi.any().only().allow(null), Joi.number())
|
|
240
|
-
.required(),
|
|
241
|
-
tags: Joi.array()
|
|
242
|
-
.items(
|
|
243
|
-
Joi.string()
|
|
244
|
-
.pattern(/[\x01-\x1F\x7F]/, {
|
|
245
|
-
name: 'control characters',
|
|
246
|
-
invert: true,
|
|
247
|
-
})
|
|
248
|
-
.min(1)
|
|
249
|
-
)
|
|
250
|
-
.required(),
|
|
211
|
+
...nymphJoiProps,
|
|
251
212
|
username: Joi.string().trim(false).min(1).required(),
|
|
252
213
|
enabled: Joi.boolean().required(),
|
|
253
214
|
email: Joi.string()
|
package/src/index.ts
CHANGED
|
@@ -11,10 +11,12 @@ export { Group };
|
|
|
11
11
|
|
|
12
12
|
import Tilmeld from './Tilmeld';
|
|
13
13
|
export { Tilmeld };
|
|
14
|
-
export default Tilmeld;
|
|
15
14
|
|
|
16
15
|
export * from './Tilmeld.types';
|
|
17
16
|
|
|
17
|
+
import tilmeldJoiProps from './tilmeldJoiProps';
|
|
18
|
+
export { tilmeldJoiProps };
|
|
19
|
+
|
|
18
20
|
export * from './User';
|
|
19
21
|
import User from './User';
|
|
20
22
|
export { User };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { TilmeldAccessLevels } from '@nymphjs/nymph';
|
|
2
|
+
import Joi from 'joi';
|
|
3
|
+
|
|
4
|
+
import User from './User';
|
|
5
|
+
import Group from './Group';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
user: Joi.object().instance(User),
|
|
9
|
+
group: Joi.object().instance(Group),
|
|
10
|
+
acUser: Joi.number().valid(
|
|
11
|
+
TilmeldAccessLevels.NO_ACCESS,
|
|
12
|
+
TilmeldAccessLevels.READ_ACCESS,
|
|
13
|
+
TilmeldAccessLevels.WRITE_ACCESS,
|
|
14
|
+
TilmeldAccessLevels.FULL_ACCESS
|
|
15
|
+
),
|
|
16
|
+
acGroup: Joi.number().valid(
|
|
17
|
+
TilmeldAccessLevels.NO_ACCESS,
|
|
18
|
+
TilmeldAccessLevels.READ_ACCESS,
|
|
19
|
+
TilmeldAccessLevels.WRITE_ACCESS,
|
|
20
|
+
TilmeldAccessLevels.FULL_ACCESS
|
|
21
|
+
),
|
|
22
|
+
acOther: Joi.number().valid(
|
|
23
|
+
TilmeldAccessLevels.NO_ACCESS,
|
|
24
|
+
TilmeldAccessLevels.READ_ACCESS,
|
|
25
|
+
TilmeldAccessLevels.WRITE_ACCESS,
|
|
26
|
+
TilmeldAccessLevels.FULL_ACCESS
|
|
27
|
+
),
|
|
28
|
+
acRead: Joi.array().items(
|
|
29
|
+
Joi.alternatives().try(
|
|
30
|
+
Joi.object().instance(User),
|
|
31
|
+
Joi.object().instance(Group)
|
|
32
|
+
)
|
|
33
|
+
),
|
|
34
|
+
acWrite: Joi.array().items(
|
|
35
|
+
Joi.alternatives().try(
|
|
36
|
+
Joi.object().instance(User),
|
|
37
|
+
Joi.object().instance(Group)
|
|
38
|
+
)
|
|
39
|
+
),
|
|
40
|
+
acFull: Joi.array().items(
|
|
41
|
+
Joi.alternatives().try(
|
|
42
|
+
Joi.object().instance(User),
|
|
43
|
+
Joi.object().instance(Group)
|
|
44
|
+
)
|
|
45
|
+
),
|
|
46
|
+
};
|