repack icon indicating copy to clipboard operation
repack copied to clipboard

A clear working example of how code signing works with repack

Open Nazehs opened this issue 1 year ago • 12 comments

Ask your Question

I am using repack and I am not absolutely sure how repack works with code signing. When i add the below configurations to Webpack config my bundling seems to fail and I need a clear understanding of which file/folder i need to make a change to get the mini app to work with code signing

I have generated a private and public key using the below shell command

ssh-keygen -t rsa -b 4096 -m PEM -f code-signing.key
# Don't add passphrase
openssl rsa -in jwtRS256.key -pubout -outform PEM -out code-signing.key.pub
cat code-signing.key
cat code-signing.key.pub

wepack config

  new Repack.plugins.CodeSigningPlugin({
                privateKeyPath: './code-signing.key',
                outputFile: 'code_signing_mapping.json',
                outputPath: path.join(dirname, 'build/outputs', platform, 'remotes'),
            })

index.js

/**
 * @format
 */

import { AppRegistry } from 'react-native';
import App from './src/App';
import { name as appName } from './app.json';
import { ScriptManager, Script, Federated } from '@callstack/repack/client';

const resolveURL = Federated.createURLResolver({
    containers: {
        ECG: 'http://localhost:9000/[name][ext]',
    },
});
ScriptManager.shared.addResolver(async (scriptId, caller) => {
    // obtain your code-signing-mapping.json from filesystem?
    // how do i read the file locally based on the platform? for the tokens
    const resolveToken = Federated.createTokenResolver(tokens);
    let url;
    let token;
    if (caller === 'main') {
        url = Script.getDevServerURL(scriptId);
    } else {
        url = resolveURL(scriptId, caller);
        token = resolveToken(scriptId, caller);
    }
    if (!url) {
        return undefined;
    }
    return {
        url,
        token,
        cache: false,
        // verifyScriptSignature: true,
        verifyScriptSignature: __DEV__ ? 'off' : 'strict',
        query: {
            platform: Platform.OS,
        },
    };
});

AppRegistry.registerComponent(appName, () => App);

Nazehs avatar Mar 08 '24 10:03 Nazehs

Hi @Nazehs,

you seem to got almost everything right, I think you forgot to add the generated public key to android strings.xml and/or ios Info.plist

check out this PR: https://github.com/callstack/super-app-showcase/pull/43

the only thing that isn't included in there is this:

verifyScriptSignature: __DEV__ ? 'off' : 'strict',

if it's failing during compilation please provide some logs

jbroma avatar Mar 14 '24 13:03 jbroma

@jbroma thank you. Quick question does this apply that i would have the same key for all the mini apps that i would include in the host app? or each would have it private/public key differently?

Nazehs avatar Mar 18 '24 10:03 Nazehs

@Nazehs only sam key is supported for now

jbroma avatar Mar 18 '24 10:03 jbroma

@jbroma i am still not sure of how i am suppose to get the below. I'd see in the example something was stated as below - getting the token or something

 // obtain your code-signing-mapping.json from filesystem?
    // how do i read the file locally based on the platform? for the tokens
    const resolveToken = Federated.createTokenResolver(tokens);

Update: The below is the same error i have been getting from the compiler in the mini app when i add the code sign config

[ecg-app] node:internal/event_target:1088
[ecg-app]   process.nextTick(() => { throw err; });
[ecg-app]                            ^
[ecg-app] 
[ecg-app] Error: ENOENT: no such file or directory, open '/packages/ECG/build/generated/android/node_modules_react-native-click-outside_src_index_tsx-_e7fd1.chunk.bundle'
[ecg-app] Emitted 'error' event on Compiler instance at:
[ecg-app]     at Worker.<anonymous> /packages/ECG/node_modules/@callstack/repack/dist/webpack/Compiler.js:110:14)
[ecg-app]     at Worker.emit (node:events:514:28)
[ecg-app]     at MessagePort.<anonymous> (node:internal/worker:263:53)
[ecg-app]     at [nodejs.internal.kHybridDispatch] (node:internal/event_target:814:20)
[ecg-app]     at exports.emitMessage (node:internal/per_context/messageport:23:28)
[ecg-app] 
[ecg-app] Node.js v20.10.0
[ecg-app] yarn run start:ecg-app  exited with code 1

Nazehs avatar Mar 18 '24 18:03 Nazehs

@Nazehs I missed the fact that you are using TokenResolver, which I'm not sure was ever published.

The tokens are now integrated, this PR has some more insights on this matter, and contains some examples as well.

jbroma avatar Mar 19 '24 09:03 jbroma

@jbroma Sorry, but it's still not clear how I can resolve the token, can you give an example?

jefmoraes avatar Mar 19 '24 13:03 jefmoraes

@jbroma i am still struggling to get this working because it stops bundling when i add the code signing plugin and i have different errors from the compiler each time i run it. I have a draft PR that i might want you to assist and look into and see if you are able to figure out what i am missing https://github.com/Nazehs/super-app-react-native/pull/3

Thank you in advance

Nazehs avatar Mar 19 '24 13:03 Nazehs

@jefmoraes If you setup CodeSigningPlugin then the integrity tokens will be generated and automatically attached to the bundle itself. When you load the bundle from a remote origin, we split the bundle into two parts: the code and the token, verify it and return just the code to the JS runtime. So there is no need to setup TokenResolver at all (not to mention it's not a valid import).

@Nazehs Thanks for providing your setup, I'll take a look when I have a chance

Saying all that, I do apologise for the lack of better documentation, it's clear that the PR's are not enough and are confusing.

jbroma avatar Mar 19 '24 13:03 jbroma

@jbroma Thanks for the answer, it's clearer, but I'm dealing with the same problem as @Nazehs. I will follow this issue and your responses in order to resolve this.

jefmoraes avatar Mar 19 '24 13:03 jefmoraes

@jbroma any update on this?

jefmoraes avatar Apr 05 '24 13:04 jefmoraes

@Nazehs @jefmoraes

regarding the repository I did check it out and found two issues:

  1. In packages/mini-app/webpack.config.mjs please change the privateKeyPath to './code-signing.pem' to make it work properly - only relatives path are supported for that field, this is fixed in Re.Pack v4 (available as 4.0.0-rc.0 as of right now).
  2. Different versions of Re.Pack are being used in the project, that might be potential cause of some issues (e.g. enabled field of CodeSigningPlugin was introduced in 3.4.0)

jbroma avatar Apr 08 '24 13:04 jbroma

@Nazehs @jefmoraes

I've added a draft of CodeSigningPlugin docs, please take a look and let me know what you think, and whether it is clear enough now. Your feedback would be greatly appreciated 🙏

jbroma avatar May 07 '24 17:05 jbroma

Docs are now available here: https://re-pack.dev/4.x/docs/plugins/code-signing

jbroma avatar May 08 '24 11:05 jbroma

Hi @jbroma how do you validate the proper configuration of code signing? Are there any methods to do so?

DivyatejaChe avatar May 27 '24 04:05 DivyatejaChe

The easiest way to validate if your configuration is right is to simply run the app with verifyScriptSignature set to strict in the ScriptManager and verify that it works.

jbroma avatar May 27 '24 14:05 jbroma

The easiest way to validate if your configuration is right is to simply run the app with verifyScriptSignature set to strict in the ScriptManager and verify that it works.

Hello @jbroma As you mentioned, I tried this but encountered the following error when start:  Screenshot 2567-07-04 at 14 38 48

Do you have any idea how to resolve this?

pttchsswk avatar Jul 04 '24 07:07 pttchsswk