Skip to content

Answer deleted or left organizations with distinct JSON errors - #153

Merged
dadachi merged 2 commits into
mainfrom
fix/account-membership-errors
Oct 13, 2026
Merged

dadachi merged 2 commits into
mainfrom
fix/account-membership-errors

Conversation

@dadachi

@dadachi dadachi commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Problem

  • /<unknown account uuid>/api/... was answered by AccountMiddleware with 302 Location: /, so clients saw the Rails welcome page (dev) or an HTML/JSON 404 (prod).
  • A signed-in shopkeeper who is no longer a member of the account in the URL got Pundit's generic 401 {"code":401,"error_message":"You are not authorized to perform this action."} (BasePolicy's "must be signed in", because current_accounts_shopkeeper is nil). Android signs out on it; iOS shows a generic error.

Change (shared contract with myturntagapi)

Case Response
/<uuid>/api/... for a deleted account 404 {"code":404,"error_code":"account_not_found","error_message":"This organization no longer exists."} (ja: この組織は削除されました。), application/json regardless of Accept / Content-Type
Signed in, account exists, not a member 403 {"code":403,"error_code":"not_account_member","error_message":"You are no longer a member of this organization."} (ja: この組織のメンバーではなくなりました。)
Pundit denial inside an account the shopkeeper belongs to unchanged 401 {code, error_message}
devise_token_auth invalid token unchanged 401 {"errors":[...]}
Non-API path with an unknown account id unchanged 302 /
  • AccountMiddleware dispatches unknown-account API requests to Api::V1::Shopkeeper::AccountNotFoundController#show (no route). It includes devise_token_auth's SetUserByToken only to pick the locale: the shopkeeper's saved locale with a valid token, otherwise Accept-Language.
  • Api::V1::Shopkeeper::BaseController gets before_action :require_account_membership after authentication and locale selection.
  • Messages in en.yml / ja.yml (api.shopkeeper.account_not_found, api.shopkeeper.not_account_member).

Clients will switch to the personal organization on these error codes instead of signing out.

Tests

  • New test/integration/account_membership_errors_test.rb (17 tests). Written first and seen red: 13 failed (302 / 401 instead of 404 / 403), and the 4 unchanged-behavior tests passed. Also broke the locale selection deliberately to confirm the saved-locale test fails.
  • test/lib/account_middleware_test.rb: unknown id in an API path returns 404 JSON; outside the API it still redirects.
  • test/integration/tenant_and_admin_routes_test.rb: non-member now 403 not_account_member (was 401).
  • Local: bin/rails test 602 runs, 1514 assertions, 0 failures; bin/rubocop, bin/brakeman, bin/bundler-audit and erb_lint clean.
  • Checked with curl against a local server on this branch: en and ja bodies for both cases, with no Content-Type, JSON Content-Type, and Accept: application/vnd.api+json.

🤖 Generated with Claude Code

https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH

dadachi and others added 2 commits October 13, 2026 14:38
An /<account uuid>/api/... request for a deleted account was redirected to
/ (302), and a signed-in shopkeeper who was no longer a member got Pundit's
generic 401, which the apps treat as a sign-out. Now:

- deleted account: 404 {code, error_code: "account_not_found", error_message}
  from AccountMiddleware via Api::V1::Shopkeeper::AccountNotFoundController,
  JSON whatever the request headers, in the shopkeeper's saved locale (or
  Accept-Language without a valid token)
- not a member: 403 {code, error_code: "not_account_member", error_message}
  from Api::V1::Shopkeeper::BaseController

Pundit denials inside an organization the shopkeeper belongs to stay 401,
devise_token_auth's invalid-token 401 is unchanged, and non-API paths with
an unknown account id still redirect to /.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K5hZEFqXhBsUQwSWsgR6eH
@dadachi
dadachi merged commit 589d655 into main Oct 13, 2026
3 checks passed
@dadachi
dadachi deleted the fix/account-membership-errors branch October 13, 2026 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant