Skip to content

dashmate ssl obtain --force is broken on the ZeroSSL provider #4249

Description

@shumkov

Expected Behavior

dashmate ssl obtain --force should obtain a new ZeroSSL certificate, bypassing the "certificate already exists and is not expiring soon" early exit.

Current Behavior

On the ZeroSSL provider (the default), --force cannot complete. It should fail during "Create a certificate" with an undefined API key; if it got past that, "Save certificate private key file" would call fs.writeFileSync(undefined, …).

The first task in the pipeline, "Check if certificate already exists and not expiring soon", is declared skip: (ctx) => ctx.force — and it is the only place that merges the validator's data into the Listr context:

  • packages/dashmate/src/listr/tasks/ssl/zerossl/obtainZeroSSLCertificateTaskFactory.js — the skip predicate on the first task, and the single lodash.merge(ctx, data) inside it.
  • packages/dashmate/src/ssl/zerossl/validateZeroSslCertificateFactory.js — where that data originates: sslConfigDir, apiKey, externalIp, certificate, csrFilePath, privateKeyFilePath, bundleFilePath, and the isXxxFilePresent flags.
  • packages/dashmate/src/commands/ssl/obtain.js — seeds the context with only { noRetry, force, expirationDays }.

So under --force, every one of those values is undefined for the remainder of the pipeline.

The intent of --force appears to be "get a new certificate regardless of the existing one" — which still needs the API key and the resolved file paths. Skipping the whole task discards the context setup along with the early exit.

Possible Solution

Separate context population from the early-exit decision. Either:

  • drop the skip and make only the "certificate is still valid, stop here" branch conditional on ctx.force, so the merge always runs; or
  • move the lodash.merge(ctx, data) into a preceding task that never skips.

Steps to Reproduce

  1. Configure a node with the ZeroSSL provider and a valid API key.
  2. Run dashmate ssl obtain --force.
  3. Observe the failure. Expected failure point is certificate creation with an undefined API key.

Context

Found by code inspection while fixing unrelated TLS private-key permission issues in the same files (see the private-key permission changes on feat/dashmate/update). Not reproduced end to end — doing so needs a real ZeroSSL API key and an externally reachable IP, which was not available. The exact failure point (API rejection vs. writeFileSync(undefined, …)) is therefore inferred from the code path rather than observed; the context-seeding, the skip predicate and the single merge site are all directly verifiable in the source.

The self-signed and Let's Encrypt providers do not share this path.

Your Environment

  • Version used: dashmate 4.1.0 (v4.1-dev, code path unchanged on feat/dashmate/update)
  • Link to your project: Dash Platform

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdashmateDashmate related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions