@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/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: (config: EmailOptions, user: User & UserData) => Promise<boolean>;
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.
@@ -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, { EmailOptions } from 'email-templates';
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, { UserData } from '../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 = Tilmeld.config.jwtSecret;
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: Tilmeld.config.appUrl,
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: Tilmeld.config.jwtExpire }
69
+ { expiresIn: config.jwtExpire }
67
70
  );
68
71
  },
69
- jwtExtract: (token, xsrfToken?) => {
70
- const secret = Tilmeld.config.jwtSecret;
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: Tilmeld.config.appUrl,
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: EmailOptions, user: User & UserData) => {
108
- const appUrl = new URL(Tilmeld.config.appUrl);
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: Tilmeld.config.appName,
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
- Tilmeld.config.emailTemplateDir,
124
+ tilmeld.config.emailTemplateDir,
122
125
  options.template ?? '.'
123
126
  ),
124
127
  locals: {
125
128
  // System
126
- siteName: Tilmeld.config.appName,
127
- siteLink: Tilmeld.config.appUrl,
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: Group) => {
157
+ validatorGroup: (group) => {
155
158
  Joi.attempt(
156
159
  group.$getValidatable(),
157
160
  Joi.object().keys({
158
- guid: Joi.alternatives()
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: User) => {
207
+ validatorUser: (user) => {
226
208
  Joi.attempt(
227
209
  user.$getValidatable(),
228
210
  Joi.object().keys({
229
- guid: Joi.alternatives()
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
+ };