Skip to content

fix(zalouser): fix setup-only onboarding flow#49219

Merged
darkamenosa merged 6 commits intomainfrom
fix/zalouser-login-onboarding
Mar 17, 2026
Merged

fix(zalouser): fix setup-only onboarding flow#49219
darkamenosa merged 6 commits intomainfrom
fix/zalouser-login-onboarding

Conversation

@darkamenosa
Copy link
Copy Markdown
Member

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: Zalouser quickstart/setup-only flow still assumed the full plugin runtime in a few paths and forced non-empty DM/group allowlists during onboarding.
  • Why it matters: Setup-only status could fail before a runtime was initialized, and quickstart onboarding could block users who wanted to defer allowlist configuration.
  • What changed: shared the plugin base between runtime/setup entrypoints, switched state-dir lookup to the plugin state-path helpers, prompted DM policy during quickstart, allowed empty DM/group allowlists with warnings, and aligned the zca-js lockfile bump to 2.1.2.
  • What did NOT change (scope boundary): no changes to live inbound/outbound Zalouser message handling beyond existing config defaults.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes: None
  • Related: None

User-visible / Behavior Changes

  • Quickstart onboarding now asks for Zalo Personal DM policy before group access.
  • DM and group allowlists can be left empty during onboarding; the channel remains blocked until entries are added later.
  • Setup-only status for Zalouser no longer depends on an initialized runtime state store.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: None.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22, pnpm 10.23.0
  • Model/provider: N/A
  • Integration/channel (if any): zalouser
  • Relevant config (redacted): default local setup config only

Steps

  1. Run the Zalouser setup flow in quickstart/setup-only mode on a clean config.
  2. Choose allowlist for DM policy and leave the allowlist blank; optionally configure groups and leave that blank too.
  3. Run dependency/install validation after the zca-js bump.

Expected

  • Setup-only status renders without runtime initialization.
  • Onboarding allows blank DM/group allowlists with warnings and leaves the channel blocked until later configuration.
  • Frozen lockfile installs succeed.

Actual

  • Before this change, setup-only paths could depend on runtime state resolution, onboarding rejected blank allowlists, and the zca-js manifest/lockfile mismatch broke frozen installs.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: pnpm test -- extensions/zalouser/src/setup-surface.test.ts extensions/zalouser/src/channel.setup.test.ts; pnpm build; pnpm install --frozen-lockfile --ignore-scripts.
  • Edge cases checked: empty DM allowlist warning; empty group allowlist warning; setup-only status without initialized runtime; plugin allowlist append behavior.
  • What you did not verify: live QR login against a real Zalo Personal account.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: None.

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert this PR or set plugins.entries.zalouser.enabled false.
  • Files/config to restore: channels.zalouser.* and plugins.entries.zalouser.
  • Known bad symptoms reviewers should watch for: setup-only status failures, quickstart still requiring non-empty allowlists, or frozen install lockfile errors.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: zca-js 2.1.2 could change QR/session behavior in ways not covered by local setup tests.
    • Mitigation: the dependency bump is scoped to extensions/zalouser, and local verification covered setup, build, and frozen-lockfile installation paths.

@openclaw-barnacle openclaw-barnacle bot added channel: zalouser Channel integration: zalouser size: L maintainer Maintainer-authored PR labels Mar 17, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR correctly fixes the Zalouser setup-only onboarding flow by: (1) introducing a dedicated zalouserSetupPlugin in channel.setup.ts that uses createZalouserPluginBase (extracted to shared.ts) without runtime-only adapters, (2) switching resolveStateDir in zalo-js.ts to use resolvePluginStateDir from the plugin SDK instead of getZalouserRuntime(), removing the runtime initialization dependency from credential path resolution, and (3) improving the quickstart wizard to prompt for DM policy explicitly and allow empty DM/group allowlists with helpful warnings.

  • zalo-js.ts: Core fix — resolveStateDir no longer calls getZalouserRuntime(), eliminating the crash on setup-only status checks.
  • shared.ts + channel.setup.ts: Clean extraction of shared plugin base; the setup plugin correctly omits security/inbound/outbound that only belong to the full runtime plugin.
  • setup-surface.ts: New promptZalouserQuickstartDmPolicy in prepare (guarded by options?.quickstartDefaults) and graceful empty-allowlist handling in both DM and group paths. finalize is simplified to ensureZalouserPluginEnabled.
  • setup-entry.ts: Now correctly imports the lightweight zalouserSetupPlugin instead of the full zalouserPlugin.
  • Test coverage: New channel.setup.test.ts verifies status without runtime init; setup-surface.test.ts extended with 4 scenarios covering DM policy ordering, empty allowlists, and plugin allowlist append.
  • One minor concern: quickstartAllowFrom: true in zalouserMeta (shared.ts:27) is stale — finalize no longer inspects forceAllowFrom, and the quickstart allowFrom flow is now handled entirely in prepare. This flag may mislead the framework or future maintainers.

Confidence Score: 4/5

  • Safe to merge — logic is correct and well-tested; one stale metadata flag is worth a follow-up but does not affect runtime correctness.
  • The root-cause fix (resolvePluginStateDir replacing the runtime-dependent call) is correct and targeted. The refactoring is clean and does not regress the existing channel behavior. Test coverage is thorough for the new scenarios. The only concern is the stale quickstartAllowFrom: true flag in shared meta, which is a code-smell/clarity issue rather than a correctness bug — finalize safely ignores forceAllowFrom whether or not the framework still passes it.
  • extensions/zalouser/src/shared.tsquickstartAllowFrom: true should be revisited now that finalize no longer handles forceAllowFrom.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/zalouser/src/shared.ts
Line: 27

Comment:
**`quickstartAllowFrom: true` may be stale**

This flag previously drove `forceAllowFrom: true` into `finalize`, where `promptZalouserAllowFrom` was called. Now that `finalize` is `async ({ cfg }) => ({ cfg: ensureZalouserPluginEnabled(cfg) })` and no longer inspects `forceAllowFrom`, any framework logic that reads `meta.quickstartAllowFrom` and passes `forceAllowFrom` to `finalize` will silently no-op.

The new quickstart DM/allowFrom prompting lives entirely in `prepare` via `promptZalouserQuickstartDmPolicy` (guarded by `options?.quickstartDefaults`). Keeping `quickstartAllowFrom: true` here signals the opposite of the actual control flow, and may confuse future readers or tooling that inspects this flag.

Consider setting it to `false` (or removing the field entirely) to accurately reflect that quickstart allowFrom is now managed explicitly in `prepare`.

```suggestion
  quickstartAllowFrom: false,
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: bf29eee

blurb: "Zalo personal account via QR code login.",
aliases: ["zlu"],
order: 85,
quickstartAllowFrom: true,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 quickstartAllowFrom: true may be stale

This flag previously drove forceAllowFrom: true into finalize, where promptZalouserAllowFrom was called. Now that finalize is async ({ cfg }) => ({ cfg: ensureZalouserPluginEnabled(cfg) }) and no longer inspects forceAllowFrom, any framework logic that reads meta.quickstartAllowFrom and passes forceAllowFrom to finalize will silently no-op.

The new quickstart DM/allowFrom prompting lives entirely in prepare via promptZalouserQuickstartDmPolicy (guarded by options?.quickstartDefaults). Keeping quickstartAllowFrom: true here signals the opposite of the actual control flow, and may confuse future readers or tooling that inspects this flag.

Consider setting it to false (or removing the field entirely) to accurately reflect that quickstart allowFrom is now managed explicitly in prepare.

Suggested change
quickstartAllowFrom: true,
quickstartAllowFrom: false,
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/zalouser/src/shared.ts
Line: 27

Comment:
**`quickstartAllowFrom: true` may be stale**

This flag previously drove `forceAllowFrom: true` into `finalize`, where `promptZalouserAllowFrom` was called. Now that `finalize` is `async ({ cfg }) => ({ cfg: ensureZalouserPluginEnabled(cfg) })` and no longer inspects `forceAllowFrom`, any framework logic that reads `meta.quickstartAllowFrom` and passes `forceAllowFrom` to `finalize` will silently no-op.

The new quickstart DM/allowFrom prompting lives entirely in `prepare` via `promptZalouserQuickstartDmPolicy` (guarded by `options?.quickstartDefaults`). Keeping `quickstartAllowFrom: true` here signals the opposite of the actual control flow, and may confuse future readers or tooling that inspects this flag.

Consider setting it to `false` (or removing the field entirely) to accurately reflect that quickstart allowFrom is now managed explicitly in `prepare`.

```suggestion
  quickstartAllowFrom: false,
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf29eeecec

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +362 to +364
if (options?.quickstartDefaults) {
next = await promptZalouserQuickstartDmPolicy({
cfg: next,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve forceAllowFrom behavior when not using quickstart

This change makes Zalouser’s allowlist prompt conditional on options?.quickstartDefaults, and the old finalize fallback that handled forceAllowFrom was removed. As a result, callers that set forceAllowFrom without enabling quickstart defaults (which setupChannels supports via forceAllowFromChannels independently of quickstartDefaults) no longer get the forced DM allowlist step for this channel, so the setup can silently skip the intended allowlist enforcement.

Useful? React with 👍 / 👎.

@darkamenosa darkamenosa merged commit b31b681 into main Mar 17, 2026
9 checks passed
@darkamenosa darkamenosa deleted the fix/zalouser-login-onboarding branch March 17, 2026 20:33
mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 17, 2026
* main: (142 commits)
  fix(zalouser): fix setup-only onboarding flow (openclaw#49219)
  CI: add built plugin singleton smoke (openclaw#48710)
  update contributing focus areas
  docs(providers): clarify provider capabilities vs public capability model
  docs(refactor): align plugin SDK plan with public capability model
  docs(cli): add plugins inspect command reference
  docs(plugins): document public capability model, plugin shapes, and inspection
  Plugins: internalize diagnostics OTel imports
  Plugins: internalize diffs SDK imports
  Plugins: internalize more extension SDK imports
  Plugins: add local extension API barrels
  Plugins: add inspect matrix and trim export
  Plugins: add inspect command and capability report
  fix(telegram): unify transport fallback chain (openclaw#49148)
  Plugins: add binding resolution callbacks (openclaw#48678)
  fix(gateway): clear trusted-proxy control ui scopes
  refactor: narrow extension public seams
  test: stabilize memory async search close
  docs(hooks): clarify trust model and audit guidance
  feat(mattermost): add retry logic and timeout handling for DM channel creation (openclaw#42398)
  ...
nikolaisid pushed a commit to nikolaisid/openclaw that referenced this pull request Mar 18, 2026
* zalouser: extract shared plugin base to reduce duplication

* fix(zalouser): bump zca-js to 2.1.2 and fix state dir resolution

* fix(zalouser): allow empty allowlist during onboarding and add quickstart DM policy prompt

* fix minor review

* fix(zalouser): restore forceAllowFrom setup flow

* fix(zalouser): default group access to allowlist
brandontyler pushed a commit to brandontyler/clawdbot that referenced this pull request Mar 19, 2026
* zalouser: extract shared plugin base to reduce duplication

* fix(zalouser): bump zca-js to 2.1.2 and fix state dir resolution

* fix(zalouser): allow empty allowlist during onboarding and add quickstart DM policy prompt

* fix minor review

* fix(zalouser): restore forceAllowFrom setup flow

* fix(zalouser): default group access to allowlist
pholpaphankorn pushed a commit to pholpaphankorn/openclaw that referenced this pull request Mar 22, 2026
* zalouser: extract shared plugin base to reduce duplication

* fix(zalouser): bump zca-js to 2.1.2 and fix state dir resolution

* fix(zalouser): allow empty allowlist during onboarding and add quickstart DM policy prompt

* fix minor review

* fix(zalouser): restore forceAllowFrom setup flow

* fix(zalouser): default group access to allowlist
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 24, 2026
* zalouser: extract shared plugin base to reduce duplication

* fix(zalouser): bump zca-js to 2.1.2 and fix state dir resolution

* fix(zalouser): allow empty allowlist during onboarding and add quickstart DM policy prompt

* fix minor review

* fix(zalouser): restore forceAllowFrom setup flow

* fix(zalouser): default group access to allowlist

(cherry picked from commit b31b681)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 24, 2026
* zalouser: extract shared plugin base to reduce duplication

* fix(zalouser): bump zca-js to 2.1.2 and fix state dir resolution

* fix(zalouser): allow empty allowlist during onboarding and add quickstart DM policy prompt

* fix minor review

* fix(zalouser): restore forceAllowFrom setup flow

* fix(zalouser): default group access to allowlist

(cherry picked from commit b31b681)
ralyodio pushed a commit to ralyodio/openclaw that referenced this pull request Apr 3, 2026
* zalouser: extract shared plugin base to reduce duplication

* fix(zalouser): bump zca-js to 2.1.2 and fix state dir resolution

* fix(zalouser): allow empty allowlist during onboarding and add quickstart DM policy prompt

* fix minor review

* fix(zalouser): restore forceAllowFrom setup flow

* fix(zalouser): default group access to allowlist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: zalouser Channel integration: zalouser maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant