74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/supabase/auth/internal/models"
|
|
"github.com/supabase/auth/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)
|
|
scope := LogoutGlobal
|
|
|
|
if r.URL.Query() != nil {
|
|
switch r.URL.Query().Get("scope") {
|
|
case "", "global":
|
|
scope = LogoutGlobal
|
|
|
|
case "local":
|
|
scope = LogoutLocal
|
|
|
|
case "others":
|
|
scope = LogoutOthers
|
|
|
|
default:
|
|
return badRequestError(ErrorCodeValidationFailed, fmt.Sprintf("Unsupported logout scope %q", r.URL.Query().Get("scope")))
|
|
}
|
|
}
|
|
|
|
s := getSession(ctx)
|
|
u := getUser(ctx)
|
|
|
|
err := db.Transaction(func(tx *storage.Connection) error {
|
|
if terr := models.NewAuditLogEntry(r, tx, u, models.LogoutAction, "", nil); terr != nil {
|
|
return terr
|
|
}
|
|
|
|
if s == nil {
|
|
logrus.Infof("user has an empty session_id claim: %s", u.ID)
|
|
} else {
|
|
//exhaustive:ignore Default case is handled below.
|
|
switch scope {
|
|
case LogoutLocal:
|
|
return models.LogoutSession(tx, s.ID)
|
|
|
|
case LogoutOthers:
|
|
return models.LogoutAllExceptMe(tx, s.ID, u.ID)
|
|
}
|
|
}
|
|
|
|
// default mode, log out everywhere
|
|
return models.Logout(tx, u.ID)
|
|
})
|
|
if err != nil {
|
|
return internalServerError("Error logging out user").WithInternalError(err)
|
|
}
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
|
|
return nil
|
|
}
|