Skip to content

Commit

Permalink
feat: add different logout behaviors
Browse files Browse the repository at this point in the history
  • Loading branch information
hf committed May 23, 2023
1 parent 23c8b45 commit cd99434
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
42 changes: 39 additions & 3 deletions internal/api/logout.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
package api

import (
"fmt"
"net/http"

"github.com/supabase/gotrue/internal/models"
"github.com/supabase/gotrue/internal/storage"
)

type LogoutBehavior string

const (
LogoutGlobal LogoutBehavior = "global"
LogoutLocal LogoutBehavior = "local"
LogoutOthers LogoutBehavior = "others"
)

// Logout is the endpoint for logging out a user and thereby revoking any refresh tokens
func (a *API) Logout(w http.ResponseWriter, r *http.Request) error {
ctx := r.Context()
db := a.db.WithContext(ctx)
config := a.config

a.clearCookieTokens(config, w)
behavior := LogoutGlobal

switch r.URL.Query().Get("behavior") {
case "", "global":
behavior = LogoutGlobal

case "local":
behavior = LogoutLocal

case "others":
behavior = LogoutOthers

default:
return badRequestError(fmt.Sprintf("Unsupported logout behavior %q", r.URL.Query().Get("behavior")))
}

s := getSession(ctx)
u := getUser(ctx)
Expand All @@ -22,15 +45,28 @@ func (a *API) Logout(w http.ResponseWriter, r *http.Request) error {
if terr := models.NewAuditLogEntry(r, tx, u, models.LogoutAction, "", nil); terr != nil {
return terr
}

if s != nil {
return models.Logout(tx, u.ID)
return models.LogoutAllRefreshTokens(tx, u.ID)
}

switch behavior {
case LogoutLocal:
return models.LogoutSession(tx, s.ID)

case LogoutOthers:
return models.LogoutAllExceptMe(tx, s.ID, u.ID)
}
return models.LogoutAllRefreshTokens(tx, u.ID)

// default mode, log out everywhere
return models.Logout(tx, u.ID)
})
if err != nil {
return internalServerError("Error logging out user").WithInternalError(err)
}

a.clearCookieTokens(config, w)
w.WriteHeader(http.StatusNoContent)

return nil
}
11 changes: 11 additions & 0 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ paths:
security:
- APIKeyAuth: []
UserAuth: []
parameters:
- name: behavior
in: query
description: >
(Optional.) Determines how the user should be logged out. When `global` is used, the user is logged out from all active sessions. When `local` is used, the user is logged out from the current session. When `others` is used, the user is logged out from all other sessions except the current one. Clients should remove stored access and refresh tokens except when `others` is used.
schema:
type: string
enum:
- global
- local
- others
responses:
204:
description: No content returned on successful logout.
Expand Down

0 comments on commit cd99434

Please sign in to comment.