npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wink-identity-sdk

v0.3.0

Published

A JavaScript/TypeScript client to integrate **Wink Identity Web SDK**, manage authentication flows, and handle session lifecycle.

Readme

Wink ID

A JavaScript/TypeScript client to integrate Wink Identity Web SDK, manage authentication flows, and handle session lifecycle.

CDNs

<!-- jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/wink-id.umd.min.js"></script>

<!-- unpkg -->
<script src="https://unpkg.com/[email protected]/dist/wink-id.umd.js"></script>

Installation

npm install wink-identity-sdk
# or
yarn add wink-identity-sdk
# or
pnpm add wink-identity-sdk

Import

import { getWinkLoginClient, WinkError } from "wink-identity-sdk";

API Overview

Core Methods

| Method | Description | |--------|-------------| | winkInit(params?: WinkInitParams): Promise<void> | Initializes the Wink login system, performs silent SSO check, and fires callbacks. | | winkLogin(params?: WinkLoginParams): Promise<void> | Starts the Wink authentication flow and redirects to the Wink login page. | | winkLogout(params?: WinkLogoutParams): Promise<void> | Clears the local session and redirects to the OIDC logout endpoint. | | getParsed(): WinkIdToken \| null | Returns the decoded Wink ID token if the user is authenticated. |

Properties

| Property | Description | |----------|-------------| | token?: string | OAuth2 access token (5-minute lifetime). | | idToken?: string | OIDC ID token. Required for logout. | | refreshToken?: string | Token used to extend the session. | | winkSessionId?: string | The active Wink session ID. Updated by winkLogin({ sessionId }). |


Usage

1. Create the Wink Login Client

The client must be created server-side session first. Never call the Wink session API directly from the browser — use a backend route as a proxy.

// 1. Fetch a sessionId from your backend (never from the browser directly)
const { sessionId } = await fetch("/api/wink/session").then(r => r.json());

// 2. Create the client
const winkLoginClient = getWinkLoginClient({
  clientId: "__client_id__",
  realm: "wink",
  sessionId,
  loggingEnabled: true,
  cancelUrl: `${window.location.origin}/callback`,
  onAuthErrorFailure: (error) => console.error(error),
});

sessionId lifetime: The session is created at the moment you call your backend. If the user stays on the page for a long time before clicking "Login", the session may expire. See Keeping the sessionId fresh.

2. Initialize Wink Login

Call winkInit on every page load to check for an existing SSO session.

winkLoginClient.winkInit({
  // Full URL recommended — relative paths can break in some routing setups
  silentCheckSsoRedirectUri: `${window.location.origin}/silent-check-sso.html`,

  onInitEnd() {
    // SSO check is complete — safe to render auth-gated UI
  },

  onFailure(error) {
    console.error(error); // error is a WinkError instance
  },

  async onSuccess() {
    // User has an active session — fetch their profile
    console.log("Authenticated:", winkLoginClient.token);
  },
});

Preventing auto-redirect on specific pages

The SDK can automatically resume an interrupted login flow. If you need to suppress this on a page that should never trigger an automatic redirect (e.g. a public landing page or post-logout screen):

winkLoginClient.winkInit({
  disableAutoRedirect: true,
  onFailure(error) { console.error(error); },
});

3. Trigger Login

winkLoginClient.winkLogin({
  redirectUri: `${window.location.origin}/auth/callback`,
  onFailure(error) {
    console.error(error); // error is a WinkError instance
  },
});

Keeping the sessionId fresh

If the user may stay on the page for a long time before clicking "Login", the original sessionId passed to getWinkLoginClient() may have expired. Pass a fresh one at login time without recreating the client:

// Fetch a new session from your backend right before redirecting
const { sessionId: freshSessionId } = await fetch("/api/wink/session").then(r => r.json());

await winkLoginClient.winkLogin({
  redirectUri: `${window.location.origin}/auth/callback`,
  sessionId: freshSessionId, // overrides the one from getWinkLoginClient()
});

Important: Never pass sessionId on the callback/return page. It is only needed when starting a new login flow.

4. Handle the OAuth Callback

Wink uses response_mode=fragment — the OAuth code arrives in the URL hash, not the query string.

# Correct — code is in the hash
https://yourapp.com/auth/callback#code=abc&state=xyz

# Wrong assumption — nothing in the query string
https://yourapp.com/auth/callback?code=abc  ← will be empty

On your callback page, call winkInit without silentCheckSsoRedirectUri. The SDK will automatically complete the token exchange using the #code=... in the hash:

winkLoginClient.winkInit({
  onSuccess() {
    // Token exchange completed — user is authenticated
    console.log("token:", winkLoginClient.token);
  },
  onFailure(error) {
    console.error(error);
  },
});

5. Trigger Logout

winkLoginClient.winkLogout({
  redirectUri: window.location.origin,
  onFailure(error) {
    console.error(error);
  },
});

winkLogout fully signs the user out of Wink. After logout, the next login will always require biometric verification — no silent re-authentication.


Error Handling

All onFailure callbacks receive a WinkError instance with additional context beyond a generic Error("Load failed").

import { WinkError } from "wink-identity-sdk";

winkLoginClient.winkInit({
  onFailure(error) {
    if (error instanceof WinkError) {
      console.error("Code:", error.oidcCode);           // e.g. "access_denied"
      console.error("Description:", error.oidcDescription); // Wink error description
    }
    console.error(error.message); // always a readable string
  },
});

Common error codes

| oidcCode | Cause | Fix | |------------|-------|-----| | access_denied | User cancelled or was denied | Show a retry prompt | | login_required | No active session for silent SSO | Expected — proceed to login | | authentication_expired | Session timed out | Re-initialize and re-login | | (network error) | CORS / connectivity issue | Contact Wink support to verify your app's origin is allowlisted |

Network errors: If you see "Network error — check CORS (Web Origins) and connectivity", your app's origin may not be allowlisted for this Wink client. Contact Wink support to have it added.


Silent Check SSO File

Create public/silent-check-sso.html in your app:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Wink Silent Check</title>
  </head>
  <body>
    <script>
      window.parent.postMessage(location.href, location.origin);
    </script>
  </body>
</html>

Known Caveats

Safari / iOS — iframe blocked by default

checkLoginIframe and silentCheckSsoFallback are disabled by default in this SDK. Enabling them causes a 10-second timeout in all modern browsers and they are incompatible with iOS Safari and modern browsers that restrict 3rd-party cookies.

If your environment explicitly supports 3rd-party cookies, you can re-enable them:

winkLoginClient.winkInit({
  checkLoginIframe: true,
  silentCheckSsoFallback: true,
  // ...
});

The tradeoff: with checkLoginIframe: false, logout in one tab does not propagate to other open tabs in real time. Tabs will detect the expired session on the next token refresh (within 5 minutes).

Redirect loop from login_session_state

If login_session_state=1 appears in the URL and no SSO session is found, winkInit will call winkLogin() automatically. This is intentional behavior to resume an interrupted flow. If it causes unexpected redirects on a specific page, pass disableAutoRedirect: true to that page's winkInit call.

SSO session termination

winkLogout() fully terminates the Wink session. Without calling it, the next login on any Wink-integrated app would silently re-authenticate without biometric verification. This is handled automatically — no extra configuration needed.


License

This project is private and not licensed for public use, distribution, or modification.