@unchainedshop/ticketing 4.3.4 → 4.4.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.
Files changed (79) hide show
  1. package/README.md +168 -0
  2. package/lib/express.d.ts +0 -1
  3. package/lib/express.js +3 -4
  4. package/lib/fastify.d.ts +0 -1
  5. package/lib/fastify.js +3 -4
  6. package/lib/index.d.ts +6 -7
  7. package/lib/index.js +4 -5
  8. package/lib/magic-key.d.ts +0 -1
  9. package/lib/magic-key.js +0 -4
  10. package/lib/mobile-tickets/apple-handler-express.d.ts +1 -2
  11. package/lib/mobile-tickets/apple-handler-express.js +1 -8
  12. package/lib/mobile-tickets/apple-handler-fastify.d.ts +0 -1
  13. package/lib/mobile-tickets/apple-handler-fastify.js +1 -8
  14. package/lib/mobile-tickets/apple-wallet.d.ts +0 -1
  15. package/lib/mobile-tickets/apple-wallet.js +0 -1
  16. package/lib/mobile-tickets/google-handler-express.d.ts +1 -2
  17. package/lib/mobile-tickets/google-handler-express.js +0 -1
  18. package/lib/mobile-tickets/google-handler-fastify.d.ts +0 -1
  19. package/lib/mobile-tickets/google-handler-fastify.js +0 -1
  20. package/lib/module.d.ts +4 -5
  21. package/lib/module.js +3 -10
  22. package/lib/pdf-tickets/print-handler-express.d.ts +1 -2
  23. package/lib/pdf-tickets/print-handler-express.js +1 -2
  24. package/lib/pdf-tickets/print-handler-fastify.d.ts +0 -1
  25. package/lib/pdf-tickets/print-handler-fastify.js +1 -2
  26. package/lib/services.d.ts +2 -3
  27. package/lib/services.js +0 -1
  28. package/lib/template-registry.d.ts +10 -10
  29. package/lib/template-registry.js +5 -7
  30. package/lib/types.d.ts +3 -4
  31. package/lib/types.js +0 -1
  32. package/package.json +17 -15
  33. package/lib/express.d.ts.map +0 -1
  34. package/lib/express.js.map +0 -1
  35. package/lib/fastify.d.ts.map +0 -1
  36. package/lib/fastify.js.map +0 -1
  37. package/lib/index.d.ts.map +0 -1
  38. package/lib/index.js.map +0 -1
  39. package/lib/magic-key.d.ts.map +0 -1
  40. package/lib/magic-key.js.map +0 -1
  41. package/lib/mobile-tickets/apple-handler-express.d.ts.map +0 -1
  42. package/lib/mobile-tickets/apple-handler-express.js.map +0 -1
  43. package/lib/mobile-tickets/apple-handler-fastify.d.ts.map +0 -1
  44. package/lib/mobile-tickets/apple-handler-fastify.js.map +0 -1
  45. package/lib/mobile-tickets/apple-wallet.d.ts.map +0 -1
  46. package/lib/mobile-tickets/apple-wallet.js.map +0 -1
  47. package/lib/mobile-tickets/google-handler-express.d.ts.map +0 -1
  48. package/lib/mobile-tickets/google-handler-express.js.map +0 -1
  49. package/lib/mobile-tickets/google-handler-fastify.d.ts.map +0 -1
  50. package/lib/mobile-tickets/google-handler-fastify.js.map +0 -1
  51. package/lib/module.d.ts.map +0 -1
  52. package/lib/module.js.map +0 -1
  53. package/lib/pdf-tickets/print-handler-express.d.ts.map +0 -1
  54. package/lib/pdf-tickets/print-handler-express.js.map +0 -1
  55. package/lib/pdf-tickets/print-handler-fastify.d.ts.map +0 -1
  56. package/lib/pdf-tickets/print-handler-fastify.js.map +0 -1
  57. package/lib/services.d.ts.map +0 -1
  58. package/lib/services.js.map +0 -1
  59. package/lib/template-registry.d.ts.map +0 -1
  60. package/lib/template-registry.js.map +0 -1
  61. package/lib/types.d.ts.map +0 -1
  62. package/lib/types.js.map +0 -1
  63. package/readme.md +0 -118
  64. package/src/express.ts +0 -35
  65. package/src/fastify.ts +0 -30
  66. package/src/index.ts +0 -66
  67. package/src/magic-key.ts +0 -43
  68. package/src/mobile-tickets/apple-handler-express.ts +0 -237
  69. package/src/mobile-tickets/apple-handler-fastify.ts +0 -279
  70. package/src/mobile-tickets/apple-wallet.ts +0 -31
  71. package/src/mobile-tickets/google-handler-express.ts +0 -57
  72. package/src/mobile-tickets/google-handler-fastify.ts +0 -69
  73. package/src/module.ts +0 -251
  74. package/src/pdf-tickets/print-handler-express.ts +0 -34
  75. package/src/pdf-tickets/print-handler-fastify.ts +0 -43
  76. package/src/services.ts +0 -35
  77. package/src/template-registry.ts +0 -48
  78. package/src/types.ts +0 -8
  79. package/tsconfig.json +0 -10
@@ -1,237 +0,0 @@
1
- import { createLogger } from '@unchainedshop/logger';
2
- import type { Request, Response } from 'express';
3
- import { TicketingAPI } from '../types.js';
4
- import { getFileAdapter } from '@unchainedshop/core-files';
5
-
6
- const logger = createLogger('unchained:apple-wallet-webservice');
7
-
8
- const isAuthenticationTokenCorrect = (req, authenticationToken) => {
9
- const expectedAuthorizationValue = `ApplePass ${authenticationToken}`;
10
- return req.headers.authorization === expectedAuthorizationValue;
11
- };
12
-
13
- const appleWalletHandler = async (req: Request & { unchainedContext: TicketingAPI }, res: Response) => {
14
- const resolvedContext = req.unchainedContext;
15
- const { modules } = resolvedContext;
16
- logger.info(`${req.path} (${JSON.stringify(req.query)})`);
17
-
18
- if (req.path.startsWith('/download/')) {
19
- try {
20
- const [, , passFileName] = req.path.split('/');
21
- const [tokenId] = passFileName.split('.pkpass');
22
-
23
- if (!tokenId) {
24
- res.status(404).end();
25
- return;
26
- }
27
-
28
- const token = await modules.warehousing.findToken({
29
- tokenId,
30
- });
31
-
32
- if (!token) {
33
- res.status(404).send('Token not found');
34
- return;
35
- }
36
-
37
- const { hash } = req.query;
38
- const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
39
- if (!hash || hash !== correctHash) {
40
- res.status(403).send('Token hash invalid for current owner');
41
- return;
42
- }
43
-
44
- const passFile = await modules.passes.upsertAppleWalletPass(token, resolvedContext);
45
-
46
- const fileUploadAdapter = getFileAdapter();
47
- const signedUrl = await fileUploadAdapter.createDownloadURL(passFile);
48
- const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
49
-
50
- if (!url) {
51
- res.status(500);
52
- res.send({
53
- success: false,
54
- message: 'Could not create download URL',
55
- name: 'URL_SIGNING_FAILED',
56
- });
57
- return;
58
- }
59
-
60
- const response = await fetch(url);
61
- const data = await response.arrayBuffer();
62
- const uint8View = new Uint8Array(data);
63
-
64
- res.status(200);
65
- res.setHeader('Content-Type', 'application/vnd.apple.pkpass');
66
- res.setHeader('Content-Disposition', `attachment; filename=${tokenId}.pkpass`);
67
- res.send(uint8View);
68
- return;
69
- } catch (e) {
70
- logger.error(e);
71
- }
72
- res.status(500).end();
73
- return;
74
- }
75
-
76
- const [, apiVersion, endpoint, ...pathComponents] = req.path.split("/"); /* eslint-disable-line */
77
- if (endpoint === 'devices') {
78
- if (req.method === 'POST') {
79
- // Register Device
80
- const [deviceLibraryIdentifier, , passTypeIdentifier, serialNumber] = pathComponents;
81
- const { pushToken } = req.body;
82
-
83
- const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
84
-
85
- if (pass) {
86
- if (
87
- !isAuthenticationTokenCorrect(
88
- req,
89
- (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
90
- )
91
- ) {
92
- res.status(401).end();
93
- return;
94
- }
95
-
96
- const newRegistration = await modules.passes.registerDeviceForAppleWalletPass(
97
- passTypeIdentifier,
98
- serialNumber,
99
- {
100
- deviceLibraryIdentifier,
101
- pushToken,
102
- },
103
- );
104
-
105
- if (!newRegistration) {
106
- res.status(200).end();
107
- return;
108
- }
109
-
110
- res.status(201).end();
111
- return;
112
- }
113
- } else if (req.method === 'GET') {
114
- // Get the List of Updatable Passes
115
- const lastUpdated = new Date();
116
- const [deviceLibraryIdentifier, , passTypeIdentifier] = pathComponents;
117
- const passesUpdatedSince =
118
- req.query?.passesUpdatedSince && new Date(req.query.passesUpdatedSince as string);
119
-
120
- const passes = await modules.passes.findUpdatedAppleWalletPasses(
121
- passTypeIdentifier,
122
- deviceLibraryIdentifier,
123
- passesUpdatedSince,
124
- );
125
- const serialNumbers = passes.map((t) => t.meta?.serialNumber).filter(Boolean) as string[];
126
-
127
- if (serialNumbers?.length) {
128
- res.status(200).send({ serialNumbers, lastUpdated });
129
- return;
130
- }
131
-
132
- res.status(204).end();
133
- return;
134
- } else if (req.method === 'DELETE') {
135
- // Unregister Device
136
- const [deviceLibraryIdentifier, , passTypeIdentifier, serialNumber] = pathComponents;
137
-
138
- const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
139
-
140
- if (pass) {
141
- if (
142
- !isAuthenticationTokenCorrect(
143
- req,
144
- (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
145
- )
146
- ) {
147
- res.status(401).end();
148
- return;
149
- }
150
-
151
- await modules.passes.unregisterDeviceForAppleWalletPass(
152
- passTypeIdentifier,
153
- serialNumber,
154
- deviceLibraryIdentifier,
155
- );
156
-
157
- // Unregistered
158
- res.status(200).end();
159
- return;
160
- }
161
- }
162
- } else if (endpoint === 'log') {
163
- // Log Mesage
164
- const { logs } = req.body;
165
- logs?.forEach((log) => {
166
- if (typeof log === 'string') {
167
- logger.info(log);
168
- }
169
- });
170
- res.status(200).end();
171
- return;
172
- } else if (endpoint === 'passes') {
173
- if (req.method === 'GET') {
174
- // Get an updated Pass
175
- const [passTypeIdentifier, serialNumber] = pathComponents;
176
-
177
- const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
178
-
179
- if (!pass) {
180
- res.status(404).end();
181
- return;
182
- }
183
-
184
- if (
185
- !isAuthenticationTokenCorrect(
186
- req,
187
- (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
188
- )
189
- ) {
190
- res.status(401).end();
191
- return;
192
- }
193
-
194
- const { updated, created } = pass;
195
-
196
- const lastModifiedDate = new Date(updated || created);
197
- lastModifiedDate.setMilliseconds(0);
198
-
199
- const ifModifiedSinceDate = new Date(req.header('if-modified-since')!);
200
- ifModifiedSinceDate.setMilliseconds(0);
201
-
202
- if (ifModifiedSinceDate.getTime() >= lastModifiedDate.getTime()) {
203
- res.status(304).end();
204
- return;
205
- }
206
-
207
- const fileUploadAdapter = getFileAdapter();
208
- const signedUrl = await fileUploadAdapter.createDownloadURL(pass);
209
- const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
210
-
211
- if (!url) {
212
- res.status(500);
213
- res.send({
214
- success: false,
215
- message: 'Could not create download URL',
216
- name: 'URL_SIGNING_FAILED',
217
- });
218
- return;
219
- }
220
-
221
- const result = await fetch(url);
222
- const data = await result.arrayBuffer();
223
- const uint8View = new Uint8Array(data);
224
-
225
- res.writeHead(200, {
226
- 'Content-Type': 'application/vnd.apple.pkpass',
227
- 'Last-Modified': lastModifiedDate.toUTCString(),
228
- });
229
- res.send(uint8View);
230
- return;
231
- }
232
- }
233
-
234
- res.status(404).end();
235
- };
236
-
237
- export default appleWalletHandler;
@@ -1,279 +0,0 @@
1
- import { createLogger } from '@unchainedshop/logger';
2
- import { TicketingAPI } from '../types.js';
3
- import { getFileAdapter } from '@unchainedshop/core-files';
4
- import type { FastifyRequest, RouteHandlerMethod } from 'fastify';
5
-
6
- const logger = createLogger('unchained:apple-wallet-webservice');
7
-
8
- const isAuthenticationTokenCorrect = (req, authenticationToken) => {
9
- const expectedAuthorizationValue = `ApplePass ${authenticationToken}`;
10
- return req.headers.authorization === expectedAuthorizationValue;
11
- };
12
-
13
- const appleWalletHandler: RouteHandlerMethod = async (
14
- req: FastifyRequest & {
15
- unchainedContext: TicketingAPI;
16
- },
17
- reply,
18
- ) => {
19
- const resolvedContext = req.unchainedContext;
20
- const { modules } = resolvedContext;
21
-
22
- const path = req.url;
23
-
24
- logger.info(`${path} (${JSON.stringify(req.query)})`);
25
-
26
- if (path.startsWith('/download/')) {
27
- try {
28
- const [, , passFileName] = path.split('/');
29
- const [tokenId] = passFileName.split('.pkpass');
30
-
31
- if (!tokenId) {
32
- reply.status(404);
33
- return reply.send();
34
- }
35
-
36
- const token = await modules.warehousing.findToken({
37
- tokenId,
38
- });
39
-
40
- if (!token) {
41
- logger.error('Token not found', { tokenId });
42
- reply.status(404);
43
- return reply.send();
44
- }
45
-
46
- const { hash } = req.query as Record<string, string>;
47
- const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
48
- if (!hash || hash !== correctHash) {
49
- logger.error('Token hash invalid for current owner', { tokenId });
50
- reply.status(403);
51
- return reply.send({
52
- success: false,
53
- message: 'Token hash invalid for current owner',
54
- name: 'HASH_MISMATCH',
55
- });
56
- }
57
-
58
- const passFile = await modules.passes.upsertAppleWalletPass(token, resolvedContext);
59
-
60
- const fileUploadAdapter = getFileAdapter();
61
- const signedUrl = await fileUploadAdapter.createDownloadURL(passFile);
62
- const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
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
-
73
- const response = await fetch(url);
74
- const data = await response.arrayBuffer();
75
- const uint8View = new Uint8Array(data);
76
-
77
- reply.status(200);
78
- reply.header('content-type', 'application/vnd.apple.pkpass');
79
- reply.header('Content-Disposition', `attachment; filename=${tokenId}.pkpass`);
80
- return reply.send(uint8View);
81
- } catch (e) {
82
- logger.error(e);
83
- reply.status(500);
84
- return reply.send({
85
- success: false,
86
- message: 'Error generating pass',
87
- name: 'PASS_GENERATION_ERROR',
88
- });
89
- }
90
- }
91
-
92
- const [, apiVersion, endpoint, ...pathComponents] = path.split("/"); /* eslint-disable-line */
93
- if (endpoint === 'devices') {
94
- if (req.method === 'POST') {
95
- // Register Device
96
- const [deviceLibraryIdentifier, , passTypeIdentifier, serialNumber] = pathComponents;
97
- const { pushToken } = req.body as Record<string, any>;
98
-
99
- const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
100
-
101
- if (pass) {
102
- if (
103
- !isAuthenticationTokenCorrect(
104
- req,
105
- (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
106
- )
107
- ) {
108
- logger.error('Unauthorized', { passTypeIdentifier, serialNumber });
109
- reply.status(401);
110
- return reply.send();
111
- }
112
-
113
- const newRegistration = await modules.passes.registerDeviceForAppleWalletPass(
114
- passTypeIdentifier,
115
- serialNumber,
116
- {
117
- deviceLibraryIdentifier,
118
- pushToken,
119
- },
120
- );
121
-
122
- if (!newRegistration) {
123
- reply.status(200);
124
- return reply.send({
125
- success: true,
126
- });
127
- }
128
-
129
- reply.status(201);
130
- return reply.send({
131
- success: true,
132
- });
133
- }
134
- } else if (req.method === 'GET') {
135
- // Get the List of Updatable Passes
136
- const lastUpdated = new Date();
137
- const [deviceLibraryIdentifier, , passTypeIdentifier] = pathComponents;
138
- const passesUpdatedSince =
139
- (req.query as Record<string, string>)?.passesUpdatedSince &&
140
- new Date((req.query as Record<string, string>).passesUpdatedSince as string);
141
-
142
- const passes = await modules.passes.findUpdatedAppleWalletPasses(
143
- passTypeIdentifier,
144
- deviceLibraryIdentifier,
145
- passesUpdatedSince,
146
- );
147
- const serialNumbers = passes.map((t) => t.meta?.serialNumber).filter(Boolean) as string[];
148
-
149
- if (serialNumbers?.length) {
150
- reply.status(200);
151
- return reply.send({
152
- success: true,
153
- serialNumbers,
154
- lastUpdated,
155
- });
156
- }
157
-
158
- reply.status(204);
159
- return reply.send({ success: true });
160
- } else if (req.method === 'DELETE') {
161
- // Unregister Device
162
- const [deviceLibraryIdentifier, , passTypeIdentifier, serialNumber] = pathComponents;
163
-
164
- const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
165
-
166
- if (pass) {
167
- if (
168
- !isAuthenticationTokenCorrect(
169
- req,
170
- (pass.meta?.rawData as any)?._id || (pass.meta?.rawData as any)?.tokenId,
171
- )
172
- ) {
173
- logger.error('Unauthorized', { passTypeIdentifier, serialNumber });
174
- reply.status(401);
175
- return reply.send({
176
- success: false,
177
- message: 'Unauthorized',
178
- name: 'UNAUTHORIZED',
179
- });
180
- }
181
-
182
- await modules.passes.unregisterDeviceForAppleWalletPass(
183
- passTypeIdentifier,
184
- serialNumber,
185
- deviceLibraryIdentifier,
186
- );
187
-
188
- // Unregistered
189
- reply.status(200);
190
- return reply.send({
191
- success: true,
192
- });
193
- }
194
- }
195
- } else if (endpoint === 'log') {
196
- // Log Mesage
197
- const { logs } = req.body as Record<string, any>;
198
- logs?.forEach((log) => {
199
- if (typeof log === 'string') {
200
- logger.info(log);
201
- }
202
- });
203
- reply.status(200);
204
- return reply.send({
205
- success: true,
206
- });
207
- } else if (endpoint === 'passes') {
208
- if (req.method === 'GET') {
209
- // Get an updated Pass
210
- const [passTypeIdentifier, serialNumber] = pathComponents;
211
-
212
- const pass = await modules.passes.findAppleWalletPass(passTypeIdentifier, serialNumber);
213
-
214
- if (!pass) {
215
- reply.status(404);
216
- return reply.send();
217
- }
218
-
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
- }
233
-
234
- const { updated, created } = pass;
235
-
236
- const lastModifiedDate = new Date(updated || created);
237
- lastModifiedDate.setMilliseconds(0);
238
-
239
- const ifModifiedSinceDate = new Date(req.headers['if-modified-since']!);
240
- ifModifiedSinceDate.setMilliseconds(0);
241
-
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
- }
250
-
251
- const fileUploadAdapter = getFileAdapter();
252
- const signedUrl = await fileUploadAdapter.createDownloadURL(pass);
253
- const url = signedUrl && (await modules.files.normalizeUrl(signedUrl, {}));
254
-
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
- });
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);
272
- }
273
- }
274
-
275
- reply.status(404);
276
- return reply.send();
277
- };
278
-
279
- export default appleWalletHandler;
@@ -1,31 +0,0 @@
1
- import apn from '@parse/node-apn';
2
- import { Readable } from 'node:stream';
3
-
4
- export const pushToApplePushNotificationService = async (deviceTokens) => {
5
- const apnProvider = new apn.Provider({
6
- cert: process.env.PASS_CERTIFICATE_PATH,
7
- key: process.env.PASS_CERTIFICATE_PATH,
8
- passphrase: process.env.PASS_CERTIFICATE_SECRET,
9
- production: true,
10
- });
11
-
12
- const note = new apn.Notification({});
13
- return apnProvider.send(note, deviceTokens);
14
- };
15
-
16
- export const buildPassBinary = async (
17
- tokenSerialNumber: string,
18
- pass: {
19
- serialNumber: string;
20
- asBuffer: () => Promise<Buffer>;
21
- },
22
- ) => {
23
- const passBuffer = await pass.asBuffer();
24
- const rawFile = {
25
- _id: pass.serialNumber,
26
- filename: `${tokenSerialNumber}-${new Date().getTime()}.pkpass`,
27
- createReadStream: () => Readable.from(passBuffer),
28
- mimetype: 'application/vnd.apple.pkpass',
29
- };
30
- return rawFile;
31
- };
@@ -1,57 +0,0 @@
1
- import { createLogger } from '@unchainedshop/logger';
2
- import type { Request, Response } from 'express';
3
- import { TicketingAPI } from '../types.js';
4
-
5
- const logger = createLogger('unchained:google-wallet-webservice');
6
-
7
- export const googleWalletHandler = async (
8
- req: Request & { unchainedContext: TicketingAPI },
9
- res: Response,
10
- ) => {
11
- const resolvedContext = req.unchainedContext;
12
- const { modules } = resolvedContext;
13
- logger.info(`${req.path} (${JSON.stringify(req.query)})`);
14
-
15
- if (req.path.includes('/download/')) {
16
- try {
17
- const { tokenId } = req.params as { tokenId: string };
18
- const { hash } = req.query as { hash?: string };
19
-
20
- if (!tokenId) {
21
- res.status(404).end();
22
- return;
23
- }
24
-
25
- const token = await modules.warehousing.findToken({
26
- tokenId,
27
- });
28
-
29
- if (!token) {
30
- res.status(404).send('Token not found');
31
- return;
32
- }
33
-
34
- const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
35
- if (!hash || hash !== correctHash) {
36
- res.status(403).send('Token hash invalid for current owner');
37
- return;
38
- }
39
-
40
- const pass = await modules.passes.upsertGoogleWalletPass(token, resolvedContext);
41
-
42
- if (!pass) {
43
- throw new Error('Could not create Google Wallet pass');
44
- }
45
-
46
- res.redirect(await pass.asURL());
47
- return;
48
- } catch (e) {
49
- logger.error(e);
50
- }
51
- res.status(500).end();
52
- return;
53
- }
54
- res.status(404).end();
55
- };
56
-
57
- export default googleWalletHandler;
@@ -1,69 +0,0 @@
1
- import { createLogger } from '@unchainedshop/logger';
2
- import { TicketingAPI } from '../types.js';
3
- import type { FastifyRequest, RouteHandlerMethod } from 'fastify';
4
-
5
- const logger = createLogger('unchained:google-wallet-webservice');
6
-
7
- const googleWalletHandler: RouteHandlerMethod = async (
8
- req: FastifyRequest & {
9
- unchainedContext: TicketingAPI;
10
- },
11
- reply,
12
- ) => {
13
- const resolvedContext = req.unchainedContext;
14
- const { modules } = resolvedContext;
15
-
16
- const path = req.url;
17
-
18
- logger.info(`${path} (${JSON.stringify(req.query)})`);
19
- if (path.includes('/download/')) {
20
- try {
21
- const { tokenId } = req.params as { tokenId: string };
22
- const { hash } = req.query as { hash?: string };
23
- if (!tokenId) {
24
- reply.status(404);
25
- return reply.send();
26
- }
27
-
28
- const token = await modules.warehousing.findToken({
29
- tokenId,
30
- });
31
-
32
- if (!token) {
33
- logger.error('Token not found', { tokenId });
34
- reply.status(404);
35
- return reply.send('Token not found');
36
- }
37
- const correctHash = await modules.warehousing.buildAccessKeyForToken(tokenId);
38
- if (!hash || hash !== correctHash) {
39
- logger.error('Token hash invalid for current owner', { tokenId });
40
- reply.status(403);
41
- return reply.send({
42
- success: false,
43
- message: 'Token hash invalid for current owner',
44
- name: 'HASH_MISMATCH',
45
- });
46
- }
47
-
48
- const pass = await modules.passes.upsertGoogleWalletPass(token, resolvedContext);
49
-
50
- if (!pass) {
51
- throw new Error('Could not create Google Wallet pass');
52
- }
53
-
54
- return reply.redirect(await pass.asURL());
55
- } catch (e) {
56
- logger.error(e);
57
- reply.status(500);
58
- return reply.send({
59
- success: false,
60
- message: 'Error generating pass',
61
- name: 'PASS_GENERATION_ERROR',
62
- });
63
- }
64
- }
65
- reply.status(404);
66
- return reply.send();
67
- };
68
-
69
- export default googleWalletHandler;