Skip to content

Commit c059e0b

Browse files
rosaclaude
andcommitted
Add JSON format support to session destroy for native API clients
This is so that native API clients can get the session record deleted server-side. They still need to take care of clearing any cookies they've set in web views. Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent ec1b8f2 commit c059e0b

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

app/controllers/sessions_controller.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ def create
2020

2121
def destroy
2222
terminate_session
23-
redirect_to_logout_url
23+
24+
respond_to do |format|
25+
format.html { redirect_to_logout_url }
26+
format.json { head :no_content }
27+
end
2428
end
2529

2630
private

docs/API.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,22 @@ __Error responses:__
118118
| `401 Unauthorized` | Invalid `pending_authentication_token` or `code` |
119119
| `429 Too Many Requests` | Rate limit exceeded |
120120

121+
122+
#### Delete server-side session (_log out_)
123+
124+
To log out and destroy the server-side session:
125+
126+
```bash
127+
curl -X DELETE \
128+
-H "Accept: application/json" \
129+
-H "Cookie: session_token=eyJfcmFpbHMi..." \
130+
https://app.fizzy.do/session
131+
```
132+
133+
__Response:__
134+
135+
Returns `204 No Content` on success.
136+
121137
## Caching
122138

123139
Most endpoints return [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/ETag) and [Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control) headers. You can use these to avoid re-downloading unchanged data.

test/controllers/api_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,26 @@ class ApiTest < ActionDispatch::IntegrationTest
2222
end
2323
end
2424

25+
test "logout with user credentials" do
26+
identity = identities(:david)
27+
28+
untenanted do
29+
post session_path(format: :json), params: { email_address: identity.email_address }
30+
magic_link = MagicLink.last
31+
32+
assert_difference -> { identity.sessions.count }, +1 do
33+
post session_magic_link_path(format: :json), params: { code: magic_link.code, pending_authentication_token: @response.parsed_body["pending_authentication_token"] }
34+
end
35+
assert cookies[:session_token].present?
36+
37+
assert_difference -> { identity.sessions.count }, -1 do
38+
delete session_path(format: :json)
39+
end
40+
assert_response :no_content
41+
assert_not cookies[:session_token].present?
42+
end
43+
end
44+
2545
test "authenticate with valid access token" do
2646
get boards_path(format: :json), env: @davids_bearer_token
2747
assert_response :success

test/controllers/sessions_controller_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,15 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
117117
assert_response :unprocessable_entity
118118
end
119119
end
120+
121+
test "destroy via JSON" do
122+
sign_in_as :kevin
123+
124+
untenanted do
125+
delete session_path(format: :json)
126+
127+
assert_response :no_content
128+
assert_not cookies[:session_token].present?
129+
end
130+
end
120131
end

0 commit comments

Comments
 (0)