Skip to content

Bug: BrowserSessionManager doesn't survive page reload #55

@liborjelinek

Description

@liborjelinek

Prerequisites

Describe the issue

I believe that shipped BrowserSessionManager is broken since it does not survive page reload. After hitting F5, Kinde client lost its authenticated state (kinde.isAuthenticated() telling false).

The setSessionItem()/setSessionItemBrowser(), getSessionItem()/getSessionItemBrowser(), and removeSessionItem()/removeSessionItem() pairs must to the same - persist a key to the sessionStorage, but the current implementation of BrowserSessionManager' non-Browser() methods save item to memory only.

Also, BrowserSessionManager destroySession() erases all items from sessionStorage ( sessionStorage.clear()), not only its keys. Correct implementation must keep track of its keys.

I offer my sample implementation:

class SessionStorageBrowserSessionManager implements SessionManager {
  // Need to track all keys to delete on logout
  private PREFIX = "kinde_"

  private withPrefix(key: string): string {
    return this.PREFIX + key
  }

  async getSessionItem(itemKey: string) {
    return this.getSessionItemBrowser(itemKey)
  }
  async getSessionItemBrowser(itemKey: string) {
    itemKey = this.withPrefix(itemKey)
    return JSON.parse(sessionStorage.getItem(itemKey))
  }

  async setSessionItem(itemKey: string, itemValue: unknown) {
    this.setSessionItemBrowser(itemKey, itemValue)
  }
  async setSessionItemBrowser(itemKey: string, itemValue: unknown) {
    itemKey = this.withPrefix(itemKey)
    sessionStorage.setItem(itemKey, JSON.stringify(itemValue))
  }

  async removeSessionItem(itemKey: string) {
    this.removeSessionItemBrowser(itemKey)
  }
  async removeSessionItemBrowser(itemKey: string) {
    itemKey = this.withPrefix(itemKey)
    sessionStorage.removeItem(itemKey)
  }

  async destroySession() {
    // Called on logout
    // Collect keys with the prefix
    const keys = []
    for (let i = 0; i < sessionStorage.length; i++) {
        const key: string = sessionStorage.key(i)
        if (key.startsWith(this.PREFIX)) {
            keys.push(key)
        }
    }
    // Delete it
    for (let i = 0; i < keys.length; i++) {
        sessionStorage.removeItem(keys[i])
    }
    // Cannot do it within for loop because removeItem() change sessionStorage.length
  }
}

And later

export const kinde = createKindeBrowserClient({
  ...
  sessionManager: new SessionStorageBrowserSessionManager()
})

Library URL

https://github.com/kinde-oss/kinde-typescript-sdk

Library version

2.7.2

Operating system(s)

macOS

Operating system version(s)

macOS Sonoma

Further environment details

No response

Reproducible test case URL

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions