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 🙏

© 2024 – Pkg Stats / Ryan Hefner

wakatime-next-auth

v1.0.2

Published

Wakatime Authentication Provider for next-auth

Downloads

11

Readme

Wakatime Provider for NextAuth

This is a simple provider to integrate Wakatime authentication into your Next.js project using NextAuth.js. It's primarily for educational purposes but is fully functional and can be used as-is.

Getting Started

Create Your Wakatime App

First, you need to create a new application on Wakatime:

  1. Visit Wakatime Apps and create a new app.
  2. Note down the Client ID and Client Secret.

Installation

Install the necessary packages:

npm install next-auth wakatime-next-auth

Configuration

You can find all available scopes in the Wakatime Authentication Documentt

Configure the Wakatime provider inside your [...nextauth]/route.ts route:


import { NextAuthOptions } from "next-auth";
import NextAuth from "next-auth/next";
import WakatimeProvider, {UserWakatimeProfile} from "wakatime-next-auth"

 export const authHandler:NextAuthOptions = NextAuth({ providers: [
    WakatimeProvider({
        clientId:process.env.CLIENT_ID!,
        clientSecret:process.env.CLIENT_SECRET!,
        authorization: {
          params: {
            scope:"email,read_stats,read_summaries", // add more scopes from wakatime authentication docs
        }
      },
    }),     //...Add other providers if you need
    ], 
    secret:process.env.NEXTAUTH_SECRET, 
    session:{
      strategy: "jwt"
    }})

  // Add additional NextAuth configuration here
});

Usage

Implement the sign-in functionality using the NextAuth.js React hooks:

import { signIn } from "next-auth/react";

const LoginButton = () => (
  <button onClick={() => signIn("wakatime")}>
    Login with Wakatime
  </button>
);

export default LoginButton;

Handling User Sessions

To retrieve more data from useSession (client side), you may need to customize the callbacks inside NextAuth in [...nextauth]/route.ts:

import WakatimeProvider, { UserWakatimeProfile } from "wakatime-next-auth";

// Inside NextAuth Handler
// ... All provider code
callbacks: {
  async jwt({ token, account, user }) {

    if (user) {
      token.user = user;
    }

    /* -------- Retrieve more data  -------- 
    
    if (account && account.access_token) {
      // Use the access token to fetch additional data from an API
      const response = await fetch('https://api.wakatime.com/api/v1/users/heartbeat', {
        headers: {
          Authorization: `Bearer ${account.access_token}`
        }
      });

      // If the fetch operation is successful, add the data to the token
      if (response.ok) {
        const data = await response.json();
        // Add the fetched data to the token
        token.wakatimeData = data;
      } else {
        // Handle errors or unsuccessful fetch operations here
        console.error('Failed to fetch Wakatime data:', response.statusText);
      } ---------------------- */

    /* -----------Token Rotation-------------  
    // Check if the account object exists and if the access token is about to expire
    if (account && account.expires_at) {
      // Convert expiry time to milliseconds to compare with the current time
      const now = Date.now();
      const expiryTime = account.expires_at * 1000;

      // If the current time is close to the expiry time, request a new access token
      if (now + (60 * 1000) > expiryTime) { // Refresh the token 1 minute before it expires
        // Implement the logic to refresh the token here
        // This usually involves making a request to the OAuth provider's token endpoint
        // token.accessToken = await refreshAccessToken(account.refresh_token);
      }
    }  ---------------------- */

    return token;
  },

  async session({ session, token }) {

    if (token.user) {
      session.user = token.user as UserWakatimeProfile;
    }

    return session;
  },
}

obs: it will give only informations inside client component all the data you'll need, from server side, you'll just get email, name and image for security purposes.

User session

Front end data and Back-end data can be retrieved by its hooks useSession(authHandler) and getServerSession(authHandler), like any other provider. Don't forget to handle between user sessions like the example above to get data faster in front-end.

Type Session for Typescript

// next-auth.d.ts

import { DefaultSession } from "next-auth";
import {UserWakatimeProfile} from "wakatime-next-auth"

declare module "next-auth" {
  interface Session {
    user: UserWakatimeProfile & DefaultSession["user"];
  }
}

Server Session

// server
import { authOptions } from '@/app/api/auth/[...nextauth]/route'
import { getServerSession } from 'next-auth'

export default async function User() {
   const data = await getServerSession(authOptions)
  if(!!data)
    return (
      <p>
        {JSON.stringify(data)}
      </p>
  )
}

Front-end Session

don't forget to create a client component to wrap using <SessionProvider> from next-auth.

// front-end component
'use client'
import { useSession } from "next-auth/react";
import React from "react";


export default function Page() {
  const {data} = useSession()
  // get all profile data
  return <div>{JSON.stringify(data?.user)}</div>;
}

Remember to replace the placeholders with your current environment variables and adjust the configuration to suit your project’s needs.