Skip to content

can not suppress the untrusted pop up with self sign certificate -- clue please! qz 2.2.4 #1315

Closed
@bunhin

Description

@bunhin

Hi i found this qz tray, and i am a beginner developer, want to try this qz for direct and silent printing from web application directly to the printer without user intervention at all.

I install qz-tray version 2.2.4 on windows laptop at the moment for trial and small development task. I believe qz tray seem the right tools, But this un-trusted pop up off course make the feature dont match the objective anymore.

I have spent quite lot of time to learn to suppress the un-trusted popup. Here what i have done:

  1. install qz 2.2.4 on windows machine
  2. I have generate private key and self signed certificate 2048 with openssl,
  3. I have put the certificate content in override.crt file inside QZ Tray install folde
  4. i also have edit qz-tray.properties to point to the certificate
  5. i already install the certificate (import) intu Trusted Root CA with certmgr.msc
    --> The site Manager on QZ has make my demo.site.tld as allowed
  6. The certificate and private-key has been placed in my demo web server (remote)
  7. I have created server side signing code on python, and the signature is returned (tested with postman)
  8. have include qz-tray.js libary in js bundle
  9. have create qz_print.js to handle the signing process and some basic test function:
  10. have try to read the log, only have a clue the certificate still missing but can not find more clues.

async function connectQZTray() {
    if (!qz.websocket.isActive()) {
        try {
            await qz.websocket.connect();
            console.log("QZ Tray connected.");
        } catch (err) {
            console.error("❌ QZ Tray connection failed:", err);
        }
    }
}

// Fetch the signature from server
async function signMessage(message) {
    try {
        let response = await fetch("/qz-tray/sign", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ message: message }),
        });

        let data = await response.json();
        if (data.error) {
            console.error("❌ Signing error:", data.error);
            return null;
        }
        return data.signature; // Return Base64 signature
    } catch (error) {
        console.error("❌ Failed to sign message:", error);
        return null;
    }
}

// Setup QZ Tray security configuration
async function setupQZSecurity() {
    if (!qz.websocket.isActive()) {
        await connectQZTray();
    }

    qz.security.setCertificatePromise((resolve, reject) => {
        fetch("/qz-tray/certificate")
            .then(response => response.text())
            .then(resolve)
            .catch(error => {
                console.error("❌ Failed to load certificate:", error);
                reject(error);
            });
    });

    qz.security.setSignaturePromise(async (toSign) => {
        let signature = await signMessage(toSign);
        return signature ? signature : Promise.reject("Signing failed.");
    });
}

// βœ… Print using QZ Tray
async function printWithQZTray() {
    await connectQZTray();
    setupQZSecurity(); 

.......

but qz keep still keep untrused.

Question:
I read the author comment on a tutorial that overriding this untrusted pop up ca be override with Self Signing Cert without need compiling from the source, IS IT STILL THAT WAY on 2.2.4? i still believe that statement that is why i keep scratching

Need Clue or Help, please help with some clue or guidance what do i still miss or not righly done and what and how the right way is.

I understand the author is not willing to have official and followable tutorial, but some clue please.

Or community here may help me. Thank you.

Activity

tresf

tresf commented on Feb 20, 2025

@tresf
Contributor

I have put the certificate content in override.crt file inside QZ Tray install folde
i also have edit qz-tray.properties to point to the certificate

Only one of these steps is needed. I would recommend only using one to improve your baseline testing.

i already install the certificate (import) intu Trusted Root CA with certmgr.msc

Please do not do this. Our licensing bypass has nothing to do with SSL. ❀

I read the author comment on a tutorial that overriding this untrusted pop up ca be override with Self Signing Cert without need compiling from the source, IS IT STILL THAT WAY on 2.2.4?

Yes, we have it built into Site Manager now, just click the little tiny + icon. Your cert should work too. No import should be needed if you copy the file in manually.

Your code is missing setCertificatePromise and setSignaturePromise. It would also be helpful to share the logs, specifically one call that contains a value for "certificate": and another that contains a value for "signature": (although once you realize this, you'll probably get it working.)

tresf

tresf commented on Feb 20, 2025

@tresf
Contributor

Oh... make sure to setup the security before connecting please. That's probably your only problem.

bunhin

bunhin commented on Feb 22, 2025

@bunhin
Author

Hi @tresf , I very appreciate for your kind responses,

Only one of these steps is needed. I would recommend only using one to improve your baseline testing.

ok i will choose one only using the override.crt

Please do not do this. Our licensing bypass has nothing to do with SSL. ❀

OK, i get a safer feeling. will remove the remove the import.

Oh... make sure to setup the security before connecting please. That's probably your only problem.

yes, this morning i just find that the setup security should be earlier than the connect, the untrusted pop up suppressed and i see in the qz tray log, that the my demo site is added to allowed list,

but now my printing test is just hanging, i found in the qz tray log this: 2025-02-22T15:18:13,818 [WARN] Failed to retrieve QZ CRL, skipping CRL check and i still dont know what is that mean.

It seem the the process is stuck on this line ... resolve(data.result.signature); of the function:

            // βœ… Step 2: Set Signing Signature
            qz.security.setSignaturePromise(function (toSign) {
                console.log("πŸ“œ Signing Message:", toSign);

                return new Promise((resolve, reject) => {
                    fetch('/qz-tray/sign', {
                        method: 'POST',
                        cache: 'no-store',  // βœ… Prevent caching
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            jsonrpc: "2.0",
                            method: "call",
                            params: { "message": toSign }
                        })
                    })
                    .then(response => {
                        if (!response.ok) {
                            throw new Error(`Server responded with ${response.status} ${response.statusText}`);
                        }
                        return response.json();
                    })
                    .then(data => {
                        console.log("πŸ” Server Full Response:", JSON.stringify(data, null, 2));

                        if (data?.result?.signature) {
                            console.log("βœ… Signature received:", data.result.signature);
                            resolve(data.result.signature);
                        } else {
                            const errorMessage = "❌ Error: 'signature' field is missing in response.";
                            console.error(errorMessage, data);
                            reject(new Error(errorMessage));
                        }
                    })
                    .catch(error => {
                        console.error("❌ Signature Request Failed:", error);
                        reject(error);
                    });
                });
            });
            console.log("βœ… QZ Tray Security Configured Successfully!");

and i tried to leg every step on console, here are they:

πŸ”‘ Setting up QZ Tray Security... qz_print.js:9:21
βœ… QZ Tray Security Configured Successfully! qz_print.js:74:21
πŸ”„ Connecting to QZ Tray... qz_print.js:81:21

Established connection with QZ Tray on wss://localhost:8181 qz-tray.js:37:45
πŸ“Œ [Step 1] Fetching certificate... qz_print.js:13:25
πŸ“Œ [Step 2] Certificate response status: 200 qz_print.js:16:33
βœ… [Step 3] Certificate fetched successfully: -----BEGIN CERTIFICATE-----

MIIDzzCCAregAwIBAgIUOlVlkE2cvf9N2lnAUAl+WjPds+gwDQYJKoZIhvcNAQEL

BQAwd qz_print.js:21:33

βœ… QZ Tray Connected qz_print.js:84:25
βœ… QZ Tray Connected qz_test_print.js:28:25
βœ… Print Data Received: 
Object { success: true, message: "Test ZPL retrieved", printer_name: "Sato-Generic / Text-Only", zpl_data: "^XA\n            ^FWB\n            ; ---- Outer Border ----\n            ^FO20,20^GB1612,980,6^FS\n\n            ; ---- Row 1 (TAG CONTROL + Part No) ----\n            ^FO20,20^GB530,140,2^FS\n            ^FO550,20^GB530,140,2^FS\n            ^FO1080,20^GB550,140,2^FS\n\n            ^FO60,60^A0N,52,52^FDTAG CONTROL^FS\n            ^FO570,60^A0N,52,52^FDPart No.^FS\n            ^FO1100,60^A0N,52,52^FDTAB-TOP^FS\n\n            ; ---- Row 2 (BACK NUMBER + Cust Part No) ----\n            ^FO20,160^GB530,140,2^FS\n            
....
^XZ" }
qz_test_print.js:41:25

πŸ“œ Signing Message: e155bb82212c7ca4ecf20932ab2ee40b4c8e15e2c1eaf698d38b891af127ff85 qz_print.js:35:25

Signing failed TypeError: resolver is not a function
    promise https://demo.....
qz-tray.js:43:47

❌ Test Print Error: Error: Failed to sign request
    sendData https://demo. ..js/lib/qz-tray.js:268
    promise callback*openConnection/_qz.websocket.connection.sendData https://demo....js/lib/qz-tray.js:264

qz_test_print.js:57:25
πŸ” Server Full Response: {
  "jsonrpc": "2.0",
  "id": null,
  "result": {
    "signature": "KLRIuDF+fJkfWhCCSa2JnrvcDiUZlsWUUgLusadyLd........SsHr4R0opNNYKEJg8d5g=="
  }
} qz_print.js:55:33

βœ… Signature received: KLRIuDF+fJkfWhCCSa2JnrvcDiUZlsWUUgLusady......SsHr4R0opNNYKEJg8d5g== qz_print.js:58:37

HANGING ....

tresf

tresf commented on Feb 22, 2025

@tresf
Contributor

Your problem is here:

Signing failed TypeError: resolver is not a function

I would recommend switching your code to use a function for a baseline, then changing it to async/await once you know it's working.

   qz.security.setSignaturePromise(function(toSign) {
        return function(resolve, reject) {
            /// YOUR CODE
            resolve(/** YOUR SIGNATURE **/);
        };
    });
bunhin

bunhin commented on Feb 24, 2025

@bunhin
Author

Ok finaly i can manage for the successful signing process, Thank you @tresf for your help. Now i need to render the label printed on SATO at ZPL mode, is there any references to the parameters name or key, at now i am still getting labels's length less than i need while i specified the length already.

tresf

tresf commented on Feb 24, 2025

@tresf
Contributor

Ok finaly i can manage for the successful signing process, Thank you @tresf for your help. Now i need to render the label printed on SATO at ZPL mode, is there any references to the parameters name or key, at now i am still getting labels's length less than i need while i specified the length already.

The best reference for ZPL designing is Labelary: https://labelary.com/viewer.html

bunhin

bunhin commented on Feb 25, 2025

@bunhin
Author

--"The best reference for ZPL designing is Labelary: https://labelary.com/viewer.html"--

Yes sure, i have been there for designing the label, and have the label template layout already, when printed the length of label just not follow what is already good on labelary. Suspect on the printer config or in the parameter to pass in the printing function.

tresf

tresf commented on Feb 25, 2025

@tresf
Contributor

You should replace your ; Comment with ^FX Comment.

The label length can be set with ^LL, but this would only be for continuous media. Fixed-size labels should automatically sense the end of a label.

If using fixed-size labels, running the printer's calibration will be needed for fixed-size labels that are not printing completely. Usually a series of button presses/holds (or special calibration button in the device driver) will calibrate the printer. Please contact your printer's manual for the specific procedure.

QZ Tray does not send any label size information when using RAW mode unless provided -- by you -- through commands. The commands shared above do not appear to contain any label size information. Any size information passed to QZ Tray via config values is ignored when using RAW.

tresf

tresf commented on Mar 14, 2025

@tresf
Contributor

I assume this is resolved, closing. If it's still an issue please request a reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      can not suppress the untrusted pop up with self sign certificate -- clue please! qz 2.2.4 Β· Issue #1315 Β· qzind/tray