Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]: Unable to use search client in cloudflare workers: Cannot bundle Node.js built-in "crypto" #1567

Closed
TorbjornHoltmon opened this issue Oct 25, 2024 · 6 comments · Fixed by algolia/api-clients-automation#4249
Labels

Comments

@TorbjornHoltmon
Copy link
Contributor

Description

Using version 5.10.2 we cannot bundle algolia search client for cloudflare workers since it uses Node built ins.

We tried updating from 5.2.1, which still works fine.

Client

All

Version

5.10.2

Relevant log output

No response

@TorbjornHoltmon
Copy link
Contributor Author

Its hard to point at any code in the repo since everything is generated.

Browsing the code in npm, the import is at:

@algolia/client-search/dist/builds/fetch.js line number 2294 in 5.10.2

image

@Haroenv
Copy link
Contributor

Haroenv commented Oct 25, 2024

In the source code I'm seeing node:crypto being used

import { createHmac } from 'node:crypto';
, but maybe that would also be problematic. I wonder if the global crypto.subtle.importKey and crypto.subtle.sign instead would work for this build?

As a workaround if you're not using that function, you can in the mean time remove the import of createHmac from node:crypto and your deploy likely works

@TorbjornHoltmon
Copy link
Contributor Author

TorbjornHoltmon commented Oct 25, 2024

I took a look at it, and it gets complicated fast, it would require some code to make it work with crypto.subtle
Using crypto.subtle would also make the function async.

Some examples of hmac sha256:
https://github.com/aws/aws-sdk-js-crypto-helpers/blob/master/packages/sha256-browser/src/webCryptoSha256.ts

https://lukasmurdock.com/web-hmac/

I am sure there are better examples or libraries to use as a starting point.
I can run polyfills, but I would prefer that a worker build had no node imports.

EDIT
Boils down to an implementation looking something like this: (not tested)

// Utility function to convert string to Uint8Array
const str2buf = (str) => {
  return new TextEncoder().encode(str);
};

// Utility function to convert ArrayBuffer to hex string
const buf2hex = (buffer) => {
  return Array.from(new Uint8Array(buffer))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
};

// Create key material from parent API key
const keyMaterial = await crypto.subtle.importKey(
  'raw',
  str2buf(parentApiKey),
  { name: 'HMAC', hash: 'SHA-256' },
  false,
  ['sign']
);

// Generate HMAC
const signature = await crypto.subtle.sign(
  'HMAC',
  keyMaterial,
  str2buf(queryParameters)
);

// Convert signature to hex and concatenate with query parameters
const combined = buf2hex(signature) + queryParameters;

// Convert to base64 
// In our code base we use our own base64 implementation instead of btoa, I think it has something to do with "URL safe" base64
// btoa also does not exist in node, and since we work in node until we build and deploy its better to not use btoa
return btoa(combined);

@lassediercks
Copy link

Because we are thinking about levering the new method browse in order to ssr initial page views on cloudflare I was wondering if this is something algolia is planning on addressing

@Haroenv
Copy link
Contributor

Haroenv commented Nov 21, 2024

@lassediercks for now the workaround would be to remove the createHmac import with eg. patch-package. Any enduring solution is probably what @TorbjornHoltmon suggested, but that's up to @shortcuts to implement

@lassediercks
Copy link

thanks for the answer @Haroenv

I was actually able to use the browse method of the v5 js sdk on a cloudflare worker without any problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants