Skip to content

Commit eb00d69

Browse files
Chris Loperhimichaelrobertsbertrmz
authored
Psg 831 (#20)
* Implement Revoke Refresh Tokens * update endpoint and add test * fix test * update app model * Update app.go Co-authored-by: Bert Ramirez <[email protected]> * Update user.go Co-authored-by: Bert Ramirez <[email protected]> Co-authored-by: Michael Roberts <[email protected]> Co-authored-by: Bert Ramirez <[email protected]>
1 parent e4363a9 commit eb00d69

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

app.go

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ type AppInfo struct {
8181
AllowedIdentifier string `json:"allowed_identifier"` // Which identifier(s) are allowed for this app (email, phone, both)
8282
RequireIdentifierVerification bool `json:"require_identifier_verification"` // Whether this app requires identifier verification
8383
SessionTimeoutLength int `json:"session_timeout_length"` // How long a JWT will last for the app when a user logs in
84+
RefreshEnabled bool `json:"refresh_enabled"` // Whether this app has refresh tokens enabled
85+
RefreshAbsoluteLifetime int `json:"refresh_absolute_lifetime"` // The absolute lifetime of a refresh token in seconds
86+
RefreshInactivityLifetime int `json:"refresh_inactivity_lifetime"` // The inactivity lifetime of a refresh token in seconds
8487
UserMetadataSchemaResponse []UserMetadataField `json:"user_metadata_schema"` // The schema for user_metadata that will be stored about users
8588
Layouts Layouts `json:"layouts"` // The layouts of user_metadata on the register/profile element
8689
}

user.go

+19
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,22 @@ func (a *App) RevokeUserDevice(userID, deviceID string) (bool, error) {
245245

246246
return true, nil
247247
}
248+
249+
// Signout revokes a users refresh tokens
250+
// returns true on success, error on failure
251+
func (a *App) SignOut(userID string) (bool, error) {
252+
response, err := resty.New().R().
253+
SetAuthToken(a.Config.APIKey).
254+
Delete(fmt.Sprintf("https://api.passage.id/v1/apps/%v/users/%v/tokens/", a.ID, userID))
255+
if err != nil {
256+
return false, errors.New("network error: could not get Passage User")
257+
}
258+
if response.StatusCode() == http.StatusNotFound {
259+
return false, fmt.Errorf("passage User with ID \"%v\" does not exist", userID)
260+
}
261+
if response.StatusCode() != http.StatusOK {
262+
return false, fmt.Errorf("failed to revoke all refresh tokens for a Passage User")
263+
}
264+
265+
return true, nil
266+
}

user_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,14 @@ func TestListUserDevices(t *testing.T) {
136136
}
137137

138138
// NOTE RevokeUserDevice is not tested because it is impossible to spoof webauthn to create a device to then revoke
139+
140+
func TestSignOutUser(t *testing.T) {
141+
psg, err := passage.New(PassageAppID, &passage.Config{
142+
APIKey: PassageApiKey, // An API_KEY environment variable is required for testing.
143+
})
144+
require.Nil(t, err)
145+
146+
result, err := psg.SignOut(PassageUserID)
147+
require.Nil(t, err)
148+
assert.Equal(t, result, true)
149+
}

0 commit comments

Comments
 (0)