@unchainedshop/ticketing 4.0.0-rc.16 → 4.0.0-rc.18

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.
Files changed (50) hide show
  1. package/lib/fastify.js +2 -2
  2. package/lib/fastify.js.map +1 -1
  3. package/lib/magic-key.js +4 -4
  4. package/lib/magic-key.js.map +1 -1
  5. package/lib/mobile-tickets/apple-handler-express.d.ts.map +1 -1
  6. package/lib/mobile-tickets/apple-handler-express.js +48 -28
  7. package/lib/mobile-tickets/apple-handler-express.js.map +1 -1
  8. package/lib/mobile-tickets/apple-handler-fastify.d.ts.map +1 -1
  9. package/lib/mobile-tickets/apple-handler-fastify.js +55 -37
  10. package/lib/mobile-tickets/apple-handler-fastify.js.map +1 -1
  11. package/lib/mobile-tickets/apple-wallet.d.ts +1 -1
  12. package/lib/mobile-tickets/apple-wallet.d.ts.map +1 -1
  13. package/lib/mobile-tickets/apple-wallet.js +2 -2
  14. package/lib/mobile-tickets/apple-wallet.js.map +1 -1
  15. package/lib/mobile-tickets/apple-webservice.d.ts +7 -0
  16. package/lib/mobile-tickets/apple-webservice.d.ts.map +1 -0
  17. package/lib/mobile-tickets/apple-webservice.js +177 -0
  18. package/lib/mobile-tickets/apple-webservice.js.map +1 -0
  19. package/lib/mobile-tickets/google-handler-express.d.ts.map +1 -1
  20. package/lib/mobile-tickets/google-handler-express.js +4 -1
  21. package/lib/mobile-tickets/google-handler-express.js.map +1 -1
  22. package/lib/mobile-tickets/google-handler-fastify.d.ts.map +1 -1
  23. package/lib/mobile-tickets/google-handler-fastify.js +4 -1
  24. package/lib/mobile-tickets/google-handler-fastify.js.map +1 -1
  25. package/lib/mobile-tickets/google-webservice.d.ts +7 -0
  26. package/lib/mobile-tickets/google-webservice.d.ts.map +1 -0
  27. package/lib/mobile-tickets/google-webservice.js +52 -0
  28. package/lib/mobile-tickets/google-webservice.js.map +1 -0
  29. package/lib/module.d.ts +8 -8
  30. package/lib/module.d.ts.map +1 -1
  31. package/lib/module.js +2 -2
  32. package/lib/module.js.map +1 -1
  33. package/lib/pdf-tickets/print-webservice.d.ts +7 -0
  34. package/lib/pdf-tickets/print-webservice.d.ts.map +1 -0
  35. package/lib/pdf-tickets/print-webservice.js +31 -0
  36. package/lib/pdf-tickets/print-webservice.js.map +1 -0
  37. package/lib/template-registry.d.ts +2 -2
  38. package/lib/template-registry.d.ts.map +1 -1
  39. package/package.json +9 -9
  40. package/readme.md +1 -1
  41. package/src/fastify.ts +2 -2
  42. package/src/magic-key.ts +4 -4
  43. package/src/mobile-tickets/apple-handler-express.ts +56 -33
  44. package/src/mobile-tickets/apple-handler-fastify.ts +63 -42
  45. package/src/mobile-tickets/apple-wallet.ts +2 -2
  46. package/src/mobile-tickets/google-handler-express.ts +5 -1
  47. package/src/mobile-tickets/google-handler-fastify.ts +6 -1
  48. package/src/module.ts +3 -3
  49. package/src/template-registry.ts +2 -2
  50. package/tsconfig.json +2 -1
@@ -45,7 +45,7 @@ const appleWalletHandler: RouteHandlerMethod = async (
45
45
 
46
46
  const { hash } = req.query as Record<string, string>;
47
47
  const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
48
- if (hash !== correctHash) {
48
+ if (!hash || hash !== correctHash) {
49
49
  logger.error('Token hash invalid for current owner', { tokenId });
50
50
  reply.status(403);
51
51
  return reply.send({
@@ -61,6 +61,15 @@ const appleWalletHandler: RouteHandlerMethod = async (
61
61
  const signedUrl = await fileUploadAdapter.createDownloadURL(passFile);
62
62
  const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
63
63
 
64
+ if (!url) {
65
+ reply.status(500);
66
+ return reply.send({
67
+ success: false,
68
+ message: 'Could not create download URL',
69
+ name: 'URL_SIGNING_FAILED',
70
+ });
71
+ }
72
+
64
73
  const response = await fetch(url);
65
74
  const data = await response.arrayBuffer();
66
75
  const uint8View = new Uint8Array(data);
@@ -93,7 +102,7 @@ const appleWalletHandler: RouteHandlerMethod = async (
93
102
  if (
94
103
  !isAuthenticationTokenCorrect(
95
104
  req,
96
- (pass.meta.rawData as any)._id || (pass.meta.rawData as any).tokenId,
105
+ (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
97
106
  )
98
107
  ) {
99
108
  logger.error('Unauthorized', { passTypeIdentifier, serialNumber });
@@ -135,7 +144,7 @@ const appleWalletHandler: RouteHandlerMethod = async (
135
144
  deviceLibraryIdentifier,
136
145
  passesUpdatedSince,
137
146
  );
138
- const serialNumbers = passes.map((t) => t.meta.serialNumber);
147
+ const serialNumbers = passes.map((t) => t.meta?.serialNumber).filter(Boolean) as string[];
139
148
 
140
149
  if (serialNumbers?.length) {
141
150
  reply.status(200);
@@ -158,7 +167,7 @@ const appleWalletHandler: RouteHandlerMethod = async (
158
167
  if (
159
168
  !isAuthenticationTokenCorrect(
160
169
  req,
161
- (pass.meta.rawData as any)._id || (pass.meta.rawData as any).tokenId,
170
+ (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
162
171
  )
163
172
  ) {
164
173
  logger.error('Unauthorized', { passTypeIdentifier, serialNumber });
@@ -202,52 +211,64 @@ const appleWalletHandler: RouteHandlerMethod = async (
202
211
 
203
212
  const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
204
213
 
205
- if (pass) {
206
- if (
207
- !isAuthenticationTokenCorrect(
208
- req,
209
- (pass.meta.rawData as any)._id || (pass.meta.rawData as any).tokenId,
210
- )
211
- ) {
212
- logger.error('Unauthorized', { passTypeIdentifier, serialNumber });
213
- reply.status(401);
214
- return reply.send({
215
- success: false,
216
- message: 'Unauthorized',
217
- name: 'UNAUTHORIZED',
218
- });
219
- }
214
+ if (!pass) {
215
+ reply.status(404);
216
+ return reply.send();
217
+ }
220
218
 
221
- const { updated, created } = pass;
219
+ if (
220
+ !isAuthenticationTokenCorrect(
221
+ req,
222
+ (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
223
+ )
224
+ ) {
225
+ logger.error('Unauthorized', { passTypeIdentifier, serialNumber });
226
+ reply.status(401);
227
+ return reply.send({
228
+ success: false,
229
+ message: 'Unauthorized',
230
+ name: 'UNAUTHORIZED',
231
+ });
232
+ }
222
233
 
223
- const lastModifiedDate = new Date(updated || created);
224
- lastModifiedDate.setMilliseconds(0);
234
+ const { updated, created } = pass;
225
235
 
226
- const ifModifiedSinceDate = new Date(req.headers['if-modified-since']);
227
- ifModifiedSinceDate.setMilliseconds(0);
236
+ const lastModifiedDate = new Date(updated || created);
237
+ lastModifiedDate.setMilliseconds(0);
228
238
 
229
- if (ifModifiedSinceDate.getTime() >= lastModifiedDate.getTime()) {
230
- reply.status(304);
231
- return reply.send({
232
- success: true,
233
- message: 'Not modified',
234
- name: 'NOT_MODIFIED',
235
- });
236
- }
239
+ const ifModifiedSinceDate = new Date(req.headers['if-modified-since']!);
240
+ ifModifiedSinceDate.setMilliseconds(0);
237
241
 
238
- const fileUploadAdapter = getFileAdapter();
239
- const signedUrl = await fileUploadAdapter.createDownloadURL(pass);
240
- const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
242
+ if (ifModifiedSinceDate.getTime() >= lastModifiedDate.getTime()) {
243
+ reply.status(304);
244
+ return reply.send({
245
+ success: true,
246
+ message: 'Not modified',
247
+ name: 'NOT_MODIFIED',
248
+ });
249
+ }
241
250
 
242
- const result = await fetch(url);
243
- const data = await result.arrayBuffer();
244
- const uint8View = new Uint8Array(data);
251
+ const fileUploadAdapter = getFileAdapter();
252
+ const signedUrl = await fileUploadAdapter.createDownloadURL(pass);
253
+ const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
245
254
 
246
- reply.status(200);
247
- reply.header('content-type', 'application/vnd.apple.pkpass');
248
- reply.header('last-modified', lastModifiedDate.toUTCString());
249
- return reply.send(uint8View);
255
+ if (!url) {
256
+ reply.status(500);
257
+ return reply.send({
258
+ success: false,
259
+ message: 'Could not create download URL',
260
+ name: 'URL_SIGNING_FAILED',
261
+ });
250
262
  }
263
+
264
+ const result = await fetch(url);
265
+ const data = await result.arrayBuffer();
266
+ const uint8View = new Uint8Array(data);
267
+
268
+ reply.status(200);
269
+ reply.header('content-type', 'application/vnd.apple.pkpass');
270
+ reply.header('last-modified', lastModifiedDate.toUTCString());
271
+ return reply.send(uint8View);
251
272
  }
252
273
  }
253
274
 
@@ -14,7 +14,7 @@ export const pushToApplePushNotificationService = async (deviceTokens) => {
14
14
  };
15
15
 
16
16
  export const buildPassBinary = async (
17
- chainTokenId: string,
17
+ tokenSerialNumber: string,
18
18
  pass: {
19
19
  serialNumber: string;
20
20
  asBuffer: () => Promise<Buffer>;
@@ -23,7 +23,7 @@ export const buildPassBinary = async (
23
23
  const passBuffer = await pass.asBuffer();
24
24
  const rawFile = {
25
25
  _id: pass.serialNumber,
26
- filename: `${chainTokenId}-${new Date().getTime()}.pkpass`,
26
+ filename: `${tokenSerialNumber}-${new Date().getTime()}.pkpass`,
27
27
  createReadStream: () => Readable.from(passBuffer),
28
28
  mimetype: 'application/vnd.apple.pkpass',
29
29
  };
@@ -32,13 +32,17 @@ export const googleWalletHandler = async (
32
32
 
33
33
  const { hash } = req.query;
34
34
  const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
35
- if (hash !== correctHash) {
35
+ if (!hash || hash !== correctHash) {
36
36
  res.status(403).send('Token hash invalid for current owner');
37
37
  return;
38
38
  }
39
39
 
40
40
  const pass = await modules.passes.upsertGoogleWalletPass(token, resolvedContext);
41
41
 
42
+ if (!pass) {
43
+ throw new Error('Could not create Google Wallet pass');
44
+ }
45
+
42
46
  res.redirect(await pass.asURL());
43
47
  return;
44
48
  } catch (e) {
@@ -38,7 +38,7 @@ const googleWalletHandler: RouteHandlerMethod = async (
38
38
 
39
39
  const { hash } = req.query as Record<string, string>;
40
40
  const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
41
- if (hash !== correctHash) {
41
+ if (!hash || hash !== correctHash) {
42
42
  logger.error('Token hash invalid for current owner', { tokenId });
43
43
  reply.status(403);
44
44
  return reply.send({
@@ -49,6 +49,11 @@ const googleWalletHandler: RouteHandlerMethod = async (
49
49
  }
50
50
 
51
51
  const pass = await modules.passes.upsertGoogleWalletPass(token, resolvedContext);
52
+
53
+ if (!pass) {
54
+ throw new Error('Could not create Google Wallet pass');
55
+ }
56
+
52
57
  return reply.redirect(await pass.asURL());
53
58
  } catch (e) {
54
59
  logger.error(e);
package/src/module.ts CHANGED
@@ -37,7 +37,7 @@ const configurePasses = async ({ db }: ModuleInput<Record<string, never>>) => {
37
37
  const pass = await createAppleWalletPass(token, unchainedAPI);
38
38
  const rawFile = Promise.resolve(
39
39
  // wrap in promise to make stream upload work
40
- await buildPassBinary(token.chainTokenId, pass as any),
40
+ await buildPassBinary(token.tokenSerialNumber, pass as any),
41
41
  );
42
42
 
43
43
  const previousFile = await MediaObjects.findOne({
@@ -84,7 +84,7 @@ const configurePasses = async ({ db }: ModuleInput<Record<string, never>>) => {
84
84
  return pass;
85
85
  };
86
86
 
87
- const findAppleWalletPass = async (passTypeIdentifier, serialNumber): Promise<File> => {
87
+ const findAppleWalletPass = async (passTypeIdentifier, serialNumber) => {
88
88
  const mediaObject = await MediaObjects.findOne({
89
89
  path: APPLE_WALLET_PASSES_FILE_DIRECTORY,
90
90
  'meta.passTypeIdentifier': passTypeIdentifier,
@@ -172,7 +172,7 @@ const configurePasses = async ({ db }: ModuleInput<Record<string, never>>) => {
172
172
 
173
173
  for (const pass of allPasses) {
174
174
  // Check if binary is already invalidated, if so, skip
175
- const rawData = pass.meta.rawData as TokenSurrogate;
175
+ const rawData = pass.meta?.rawData as TokenSurrogate;
176
176
  if (rawData.invalidatedDate) continue;
177
177
 
178
178
  const redeemedToken = allTokens.find((t) => t._id === rawData._id && t.invalidatedDate);
@@ -16,8 +16,8 @@ export type PassRenderer = (
16
16
  token: TokenSurrogate,
17
17
  context: UnchainedCore,
18
18
  ) => Promise<{
19
- asURL?: () => Promise<string>;
20
- asBuffer?: () => Promise<Buffer>;
19
+ asURL: () => Promise<string>;
20
+ asBuffer: () => Promise<Buffer>;
21
21
  serialNumber?: string;
22
22
  passTypeIdentifier?: string;
23
23
  }>;
package/tsconfig.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "compilerOptions": {
4
4
  "declarationDir": "./lib",
5
5
  "rootDir": "./src",
6
- "outDir": "./lib"
6
+ "outDir": "./lib",
7
+
7
8
  },
8
9
  "exclude": ["**/*.test.ts", "**/*.test.js", "tests", "lib"]
9
10
  }