Skip to content

Commit b2ffa55

Browse files
committed
Convert some functions to web standards
1 parent 6682be6 commit b2ffa55

File tree

10 files changed

+50
-27
lines changed

10 files changed

+50
-27
lines changed

packages/api/src/express/createERCMetadataMiddleware.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import path from 'node:path';
21
import { createLogger } from '@unchainedshop/logger';
32
import { Context } from '../context.js';
43
import { Request, RequestHandler } from 'express';
@@ -25,16 +24,20 @@ const ercMetadataMiddleware: RequestHandler = async (
2524

2625
const { services, modules, loaders, locale } = req.unchainedContext;
2726
const url = new URL(req.url, ROOT_URL);
28-
const parsedPath = path.parse(url.pathname);
2927

30-
if (parsedPath.ext !== '.json') throw new Error('Invalid ERC Metadata URI');
28+
// Replace path.parse with URL/string methods
29+
const pathname = url.pathname;
30+
if (!pathname.toLowerCase().endsWith('.json')) throw new Error('Invalid ERC Metadata URI');
31+
32+
const fileName = pathname.split('/').pop();
33+
const chainTokenId = fileName.slice(0, fileName.lastIndexOf('.'));
3134

3235
const [, productId, localeOrTokenFilename, tokenFileName] = url.pathname.split('/');
3336

3437
const product = await loaders.productLoader.load({ productId });
3538

3639
const [token] = await modules.warehousing.findTokens({
37-
chainTokenId: parsedPath.name,
40+
chainTokenId,
3841
contractAddress: product?.tokenization?.contractAddress,
3942
});
4043

@@ -49,11 +52,10 @@ const ercMetadataMiddleware: RequestHandler = async (
4952
}
5053

5154
const body = JSON.stringify(ercMetadata);
52-
res.writeHead(200, {
53-
'Content-Length': Buffer.byteLength(body),
54-
'Content-Type': 'text/plain',
55-
});
56-
res.end(body);
55+
res.status(200);
56+
res.setHeader('Content-Type', 'application/json');
57+
res.setHeader('Content-Length', new TextEncoder().encode(body).length);
58+
return res.send(body);
5759
} catch (e) {
5860
logger.error(e.message);
5961
res.writeHead(503);

packages/api/src/fastify/bulkImportHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const bulkImportHandler: RouteHandlerMethod = async (
4646

4747
const body = JSON.stringify(work);
4848
res.status(200);
49-
res.header('Content-Length', Buffer.byteLength(body));
49+
res.header('Content-Length', new TextEncoder().encode(body).length);
5050
res.header('Content-Type', 'application/json');
5151
return res.send(body);
5252
} catch (e) {

packages/api/src/fastify/ercMetadataHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const ercMetadataHandler: RouteHandlerMethod = async (
4141

4242
const body = JSON.stringify(ercMetadata);
4343
res.status(200);
44-
res.header('Content-Length', Buffer.byteLength(body));
44+
res.header('Content-Length', new TextEncoder().encode(body).length);
4545
res.header('Content-Type', 'application/json');
4646
return res.send(body);
4747
} catch (e) {

packages/api/src/fastify/tempUploadHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const tempUploadHandler: RouteHandlerMethod = async (
3939
const url = context.modules.files.normalizeUrl(rawUrl, {});
4040
const body = JSON.stringify({ fileId: file._id, url, expires: expires.toISOString() });
4141
res.status(200);
42-
res.header('Content-Length', Buffer.byteLength(body));
42+
res.header('Content-Length', new TextEncoder().encode(body).length);
4343
res.header('Content-Type', 'application/json');
4444
return res.send(body);
4545
} catch (e) {

packages/core-users/src/module/configureUsersWebAuthnModule.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) =>
8686
if (!f2l) return null;
8787

8888
const registrationOptions = await f2l.attestationOptions(extensionOptions);
89-
const challenge = Buffer.from(registrationOptions.challenge).toString('base64');
89+
// Convert challenge to base64 without using Buffer
90+
const challenge = btoa(String.fromCharCode(...new Uint8Array(registrationOptions.challenge)));
9091
const { insertedId } = await WebAuthnCredentialsCreationRequests.insertOne({
9192
_id: new Date().getTime(),
9293
challenge,
@@ -110,7 +111,8 @@ export const configureUsersWebAuthnModule = async ({ db }: ModuleInput<any>) =>
110111
if (!f2l) return null;
111112

112113
const loginOptions = await f2l.assertionOptions(extensionOptions);
113-
const challenge = Buffer.from(loginOptions.challenge).toString('base64');
114+
// Convert challenge to base64 without using Buffer
115+
const challenge = btoa(String.fromCharCode(...new Uint8Array(loginOptions.challenge)));
114116
const { insertedId } = await WebAuthnCredentialsCreationRequests.insertOne({
115117
_id: new Date().getTime(),
116118
challenge,

packages/core-users/src/module/pbkdf2.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ const PBKDF2_SALT_LENGTH = 16; // Bytes
55

66
export function generateSalt(saltLength = PBKDF2_SALT_LENGTH) {
77
const array = new Uint8Array(saltLength);
8-
return Buffer.from(crypto.getRandomValues(array)).toString('hex');
8+
crypto.getRandomValues(array);
9+
// Convert to hex string without using Buffer
10+
return Array.from(array)
11+
.map((b) => b.toString(16).padStart(2, '0'))
12+
.join('');
913
}
1014

1115
export async function getDerivedKey(
@@ -30,7 +34,10 @@ export async function getDerivedKey(
3034
importedKey,
3135
keyLength,
3236
);
33-
return Buffer.from(bits).toString('hex');
37+
// Convert ArrayBuffer to hex string without using Buffer
38+
return Array.from(new Uint8Array(bits))
39+
.map((b) => b.toString(16).padStart(2, '0'))
40+
.join('');
3441
}
3542

3643
export async function compare(password: string, hash: string, salt: string) {

packages/plugins/src/payment/postfinance-checkout/api-client.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import crypto from 'crypto';
2-
31
const API_BASE_URL = 'https://checkout.postfinance.ch/api';
42

53
interface ApiConfig {
@@ -22,7 +20,7 @@ export class PostFinanceApiClient {
2220
this.config = config;
2321
}
2422

25-
private generateMacHeaders(method: string, path: string): MacHeaders {
23+
private async generateMacHeaders(method: string, path: string): Promise<MacHeaders> {
2624
const version = '1';
2725
const timestamp = Math.floor(Date.now() / 1000).toString();
2826
const userId = this.config.userId.toString();
@@ -32,10 +30,17 @@ export class PostFinanceApiClient {
3230

3331
const dataToSign = [version, userId, timestamp, method, resourcePath].join('|');
3432

35-
const macValue = crypto
36-
.createHmac('sha512', Buffer.from(this.config.apiSecret, 'base64'))
37-
.update(dataToSign, 'utf8')
38-
.digest('base64');
33+
// Use Web Crypto API instead of crypto.createHmac
34+
const secretBytes = Uint8Array.from(atob(this.config.apiSecret), (c) => c.charCodeAt(0));
35+
const key = await crypto.subtle.importKey(
36+
'raw',
37+
secretBytes,
38+
{ name: 'HMAC', hash: 'SHA-512' },
39+
false,
40+
['sign'],
41+
);
42+
const signature = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(dataToSign));
43+
const macValue = btoa(String.fromCharCode(...new Uint8Array(signature)));
3944

4045
return {
4146
'x-mac-version': version,
@@ -50,7 +55,7 @@ export class PostFinanceApiClient {
5055
const urlObj = new URL(url);
5156
// Include both pathname and search (query parameters) for MAC signature
5257
const pathWithQuery = urlObj.pathname + urlObj.search;
53-
const macHeaders = this.generateMacHeaders(method, pathWithQuery);
58+
const macHeaders = await this.generateMacHeaders(method, pathWithQuery);
5459

5560
const headers: Record<string, string> = {
5661
...macHeaders,

packages/ticketing/src/module.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,10 @@ const configurePasses = async ({ db }: ModuleInput<Record<string, never>>) => {
188188
const buildMagicKey = async (orderId: string) => {
189189
const msgUint8 = new TextEncoder().encode([orderId, process.env.UNCHAINED_SECRET].join(''));
190190
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
191-
return Buffer.from(hashBuffer).toString('hex');
191+
// Convert ArrayBuffer to hex string without using Buffer
192+
return Array.from(new Uint8Array(hashBuffer))
193+
.map((b) => b.toString(16).padStart(2, '0'))
194+
.join('');
192195
};
193196

194197
const cancelTicket = async (tokenId: string) => {

packages/utils/src/sha1.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export default async function sha1(message) {
22
const bytes = new TextEncoder().encode(message);
33
const hashBuffer = await crypto.subtle.digest('SHA-1', bytes);
4-
return Buffer.from(hashBuffer);
4+
// Return Uint8Array instead of Buffer
5+
return new Uint8Array(hashBuffer);
56
}

packages/utils/src/sha256.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
export default async function sha256(message) {
22
const bytes = new TextEncoder().encode(message);
33
const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
4-
return Buffer.from(hashBuffer).toString('hex');
4+
// Convert ArrayBuffer to hex string without using Buffer
5+
return Array.from(new Uint8Array(hashBuffer))
6+
.map((b) => b.toString(16).padStart(2, '0'))
7+
.join('');
58
}

0 commit comments

Comments
 (0)