@wbce-d9/api 10.4.0 → 10.6.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.
@@ -13,11 +13,15 @@ import asyncHandler from '../utils/async-handler.js';
13
13
  import { generateHash } from '../utils/generate-hash.js';
14
14
  import { sanitizeQuery } from '../utils/sanitize-query.js';
15
15
  const router = Router();
16
+ const randomStringSchemaDesc = Joi.object({
17
+ length: Joi.number().integer().min(1).max(500).default(32),
18
+ });
16
19
  router.get('/random/string', asyncHandler(async (req, res) => {
17
20
  const { nanoid } = await import('nanoid');
18
- if (req.query && req.query['length'] && Number(req.query['length']) > 500)
19
- throw new InvalidQueryException(`"length" can't be more than 500 characters`);
20
- const string = nanoid(req.query?.['length'] ? Number(req.query['length']) : 32);
21
+ const { error, value } = randomStringSchemaDesc.validate(req.query, { allowUnknown: true });
22
+ if (error)
23
+ throw new InvalidQueryException(error.message);
24
+ const string = nanoid(value.length);
21
25
  return res.json({ data: string });
22
26
  }));
23
27
  router.post('/hash/generate', asyncHandler(async (req, res) => {
@@ -41,6 +41,9 @@
41
41
  permissions:
42
42
  user:
43
43
  _eq: $CURRENT_USER
44
+ validation:
45
+ user:
46
+ _eq: $CURRENT_USER
44
47
 
45
48
  - collection: directus_presets
46
49
  action: delete
package/dist/mailer.js CHANGED
@@ -55,10 +55,18 @@ export default function getMailer() {
55
55
  }));
56
56
  }
57
57
  else if (transportName === 'sendgrid') {
58
- const sg = require('nodemailer-sendgrid');
59
- transporter = nodemailer.createTransport(sg({
60
- apiKey: env['EMAIL_SENDGRID_API_KEY'],
61
- }));
58
+ let auth = false;
59
+ if (env['EMAIL_SENDGRID_API_KEY'] || env['EMAIL_SMTP_PASSWORD']) {
60
+ auth = {
61
+ user: 'apikey',
62
+ pass: env['EMAIL_SENDGRID_API_KEY'],
63
+ };
64
+ }
65
+ transporter = nodemailer.createTransport({
66
+ host: 'smtp.sendgrid.net',
67
+ port: 587,
68
+ auth,
69
+ });
62
70
  }
63
71
  else {
64
72
  logger.warn('Illegal transport given for email. Check the EMAIL_TRANSPORT env var.');
@@ -22,7 +22,8 @@ export const respond = asyncHandler(async (req, res) => {
22
22
  cache &&
23
23
  !req.sanitizedQuery.export &&
24
24
  res.locals['cache'] !== false &&
25
- exceedsMaxSize === false) {
25
+ exceedsMaxSize === false &&
26
+ req.originalUrl?.startsWith('/auth')) {
26
27
  const key = getCacheKey(req);
27
28
  try {
28
29
  await setCacheValue(cache, key, res.locals['payload'], getMilliseconds(env['CACHE_TTL']));
@@ -7,7 +7,7 @@ import { DEFAULT_AUTH_PROVIDER } from '../constants.js';
7
7
  import getDatabase from '../database/index.js';
8
8
  import emitter from '../emitter.js';
9
9
  import env from '../env.js';
10
- import { InvalidCredentialsException, InvalidOTPException, InvalidProviderException, UserSuspendedException, } from '../exceptions/index.js';
10
+ import { InvalidCredentialsException, InvalidOTPException, UserSuspendedException } from '../exceptions/index.js';
11
11
  import { createRateLimiter } from '../rate-limiter.js';
12
12
  import { getMilliseconds } from '../utils/get-milliseconds.js';
13
13
  import { stall } from '../utils/stall.js';
@@ -72,20 +72,10 @@ export class AuthenticationService {
72
72
  accountability: this.accountability,
73
73
  });
74
74
  };
75
- if (user?.status !== 'active') {
75
+ if (user?.status !== 'active' || user.provider.toLowerCase() !== providerName.toLowerCase()) {
76
76
  emitStatus('fail');
77
- if (user?.status === 'suspended') {
78
- await stall(STALL_TIME, timeStart);
79
- throw new UserSuspendedException();
80
- }
81
- else {
82
- await stall(STALL_TIME, timeStart);
83
- throw new InvalidCredentialsException();
84
- }
85
- }
86
- else if (user.provider.toLowerCase() !== providerName.toLowerCase()) {
87
77
  await stall(STALL_TIME, timeStart);
88
- throw new InvalidProviderException();
78
+ throw new InvalidCredentialsException();
89
79
  }
90
80
  const settingsService = new SettingsService({
91
81
  knex: this.knex,
@@ -1894,10 +1894,10 @@ export class GraphQLService {
1894
1894
  },
1895
1895
  resolve: async (_, args) => {
1896
1896
  const { nanoid } = await import('nanoid');
1897
- if (args['length'] && Number(args['length']) > 500) {
1898
- throw new InvalidPayloadException(`"length" can't be more than 500 characters`);
1897
+ if (args['length'] !== undefined && (args['length'] < 1 || args['length'] > 500)) {
1898
+ throw new InvalidPayloadException(`"length" must be between 1 and 500`);
1899
1899
  }
1900
- return nanoid(args['length'] ? Number(args['length']) : 32);
1900
+ return nanoid(args['length'] ? args['length'] : 32);
1901
1901
  },
1902
1902
  },
1903
1903
  utils_hash_generate: {
@@ -117,7 +117,7 @@ export class UsersService extends ItemsService {
117
117
  */
118
118
  async getUserByEmail(email) {
119
119
  return await this.knex
120
- .select('id', 'role', 'status', 'password')
120
+ .select('id', 'role', 'status', 'password', 'email')
121
121
  .from('directus_users')
122
122
  .whereRaw(`LOWER(??) = ?`, ['email', email.toLowerCase()])
123
123
  .first();
@@ -307,13 +307,13 @@ export class UsersService extends ItemsService {
307
307
  if (isEmpty(user) || user.status === 'invited') {
308
308
  const subjectLine = subject ?? "You've been invited";
309
309
  await mailService.send({
310
- to: email,
310
+ to: user.email,
311
311
  subject: subjectLine,
312
312
  template: {
313
313
  name: 'user-invitation',
314
314
  data: {
315
315
  url: this.inviteUrl(email, url),
316
- email,
316
+ email: user.email,
317
317
  },
318
318
  },
319
319
  });
@@ -351,20 +351,20 @@ export class UsersService extends ItemsService {
351
351
  knex: this.knex,
352
352
  accountability: this.accountability,
353
353
  });
354
- const payload = { email, scope: 'password-reset', hash: getSimpleHash('' + user.password) };
354
+ const payload = { email: user.email, scope: 'password-reset', hash: getSimpleHash('' + user.password) };
355
355
  const token = jwt.sign(payload, env['SECRET'], { expiresIn: '1d', issuer: 'directus' });
356
356
  const acceptURL = url
357
357
  ? new Url(url).setQuery('token', token).toString()
358
358
  : new Url(env['PUBLIC_URL']).addPath('admin', 'reset-password').setQuery('token', token).toString();
359
359
  const subjectLine = subject ? subject : 'Password Reset Request';
360
360
  await mailService.send({
361
- to: email,
361
+ to: user.email,
362
362
  subject: subjectLine,
363
363
  template: {
364
364
  name: 'password-reset',
365
365
  data: {
366
366
  url: acceptURL,
367
- email,
367
+ email: user.email,
368
368
  },
369
369
  },
370
370
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wbce-d9/api",
3
- "version": "10.4.0",
3
+ "version": "10.6.0",
4
4
  "description": "Directus is a real-time API and App dashboard for managing SQL database content",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -72,7 +72,7 @@
72
72
  "@wbce-d9/format-title": "10.0.0",
73
73
  "argon2": "0.30.3",
74
74
  "async": "3.2.4",
75
- "axios": "^1.7.2",
75
+ "axios": "^1.8.2",
76
76
  "busboy": "1.6.0",
77
77
  "bytes": "3.1.2",
78
78
  "camelcase": "7.0.1",
@@ -80,7 +80,7 @@
80
80
  "chokidar": "3.5.3",
81
81
  "commander": "10.0.1",
82
82
  "content-disposition": "0.5.4",
83
- "cookie-parser": "1.4.6",
83
+ "cookie-parser": "1.4.7",
84
84
  "cors": "2.8.5",
85
85
  "csv-parser": "3.0.0",
86
86
  "date-fns": "2.29.3",
@@ -91,11 +91,11 @@
91
91
  "eventemitter2": "6.4.9",
92
92
  "execa": "7.1.1",
93
93
  "exif-reader": "1.2.0",
94
- "express": "4.18.2",
94
+ "express": "^4.21.2",
95
95
  "fast-redact": "3.1.2",
96
96
  "flat": "5.0.2",
97
97
  "fs-extra": "11.1.1",
98
- "graphql": "16.6.0",
98
+ "graphql": "16.8.1",
99
99
  "graphql-compose": "9.0.10",
100
100
  "helmet": "6.1.5",
101
101
  "icc": "3.0.0",
@@ -107,7 +107,7 @@
107
107
  "json2csv": "5.0.7",
108
108
  "jsonwebtoken": "9.0.0",
109
109
  "keyv": "4.5.2",
110
- "knex": "2.4.2",
110
+ "knex": "3.1.0",
111
111
  "ldapjs": "2.3.3",
112
112
  "liquidjs": "10.7.0",
113
113
  "lodash-es": "4.17.21",
@@ -115,10 +115,10 @@
115
115
  "micromustache": "8.0.3",
116
116
  "mime-types": "2.1.35",
117
117
  "ms": "2.1.3",
118
- "nanoid": "4.0.2",
118
+ "nanoid": "5.0.9",
119
119
  "node-cron": "3.0.2",
120
120
  "node-machine-id": "1.1.12",
121
- "nodemailer": "6.9.1",
121
+ "nodemailer": "6.9.9",
122
122
  "object-hash": "3.0.0",
123
123
  "openapi3-ts": "3.2.0",
124
124
  "openid-client": "5.4.0",
@@ -130,10 +130,10 @@
130
130
  "pino-pretty": "10.0.0",
131
131
  "qs": "6.11.1",
132
132
  "rate-limiter-flexible": "2.4.1",
133
- "rollup": "3.20.7",
133
+ "rollup": "3.29.5",
134
134
  "samlify": "2.8.10",
135
- "sanitize-html": "2.10.0",
136
- "sharp": "0.32.0",
135
+ "sanitize-html": "2.12.1",
136
+ "sharp": "0.32.6",
137
137
  "snappy": "7.2.2",
138
138
  "stream-json": "1.7.5",
139
139
  "strip-bom-stream": "5.0.0",
@@ -143,20 +143,20 @@
143
143
  "uuid-validate": "0.0.3",
144
144
  "vm2": "^3.9.19",
145
145
  "wellknown": "0.5.0",
146
- "@wbce-d9/app": "9.30.0",
146
+ "@wbce-d9/app": "9.32.0",
147
+ "@wbce-d9/constants": "9.28.0",
148
+ "@wbce-d9/extensions-sdk": "9.27.1",
147
149
  "@wbce-d9/exceptions": "9.26.4",
148
- "@wbce-d9/constants": "9.27.0",
149
- "@wbce-d9/extensions-sdk": "9.26.7",
150
150
  "@wbce-d9/schema": "9.26.4",
151
- "@wbce-d9/storage": "9.26.4",
151
+ "@wbce-d9/storage-driver-azure": "9.26.8",
152
152
  "@wbce-d9/specs": "9.26.4",
153
- "@wbce-d9/storage-driver-azure": "9.26.7",
154
- "@wbce-d9/storage-driver-cloudinary": "9.26.7",
155
- "@wbce-d9/storage-driver-gcs": "9.26.7",
156
- "@wbce-d9/update-check": "9.26.4",
157
- "@wbce-d9/storage-driver-local": "9.26.7",
158
- "@wbce-d9/storage-driver-s3": "9.26.9",
159
- "@wbce-d9/utils": "9.29.0"
153
+ "@wbce-d9/storage": "9.26.4",
154
+ "@wbce-d9/storage-driver-cloudinary": "9.27.0",
155
+ "@wbce-d9/storage-driver-local": "9.26.8",
156
+ "@wbce-d9/storage-driver-s3": "9.26.10",
157
+ "@wbce-d9/storage-driver-gcs": "9.26.8",
158
+ "@wbce-d9/utils": "9.29.1",
159
+ "@wbce-d9/update-check": "9.28.0"
160
160
  },
161
161
  "devDependencies": {
162
162
  "@ngneat/falso": "6.4.0",
@@ -200,11 +200,11 @@
200
200
  "@wbce-d9/tsconfig": "0.0.7",
201
201
  "copyfiles": "2.4.1",
202
202
  "form-data": "4.0.0",
203
- "knex-mock-client": "2.0.0",
203
+ "knex-mock-client": "3.0.2",
204
204
  "supertest": "6.3.3",
205
205
  "typescript": "5.0.4",
206
206
  "vitest": "0.30.1",
207
- "@wbce-d9/types": "9.27.0"
207
+ "@wbce-d9/types": "9.28.0"
208
208
  },
209
209
  "optionalDependencies": {
210
210
  "@keyv/redis": "2.5.7",
@@ -212,10 +212,9 @@
212
212
  "memcached": "2.2.2",
213
213
  "mysql": "2.18.1",
214
214
  "nodemailer-mailgun-transport": "2.1.5",
215
- "nodemailer-sendgrid": "1.0.3",
216
215
  "pg": "8.10.0",
217
216
  "sqlite3": "5.1.6",
218
- "tedious": "16.0.0"
217
+ "tedious": "18.6.1"
219
218
  },
220
219
  "engines": {
221
220
  "node": ">=18.0.0"