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

@solidstart-auth/server

v1.0.0

Published

authentication tools for SolidStart

Downloads

70

Readme

@solidstart-auth/server

A secure, flexible authentication library designed for SolidStart applications, providing essential authentication features with TypeScript support.

Overview

@solidstart-auth/server provides a robust authentication system that includes:

  • Session management compatible with SolidStart/Vinxi
  • User authentication (login/register flows)
  • Optional password hashing integration
  • Built-in validation for usernames, passwords, and emails
  • TypeScript support with full type definitions
  • Secure session handling with customizable secrets

Installation

npm install @solidstart-auth/server

Quick Start

Here's a basic example of setting up authentication in a SolidStart application:

import { createAuthCallbacks } from '@solidstart-auth/server';
import { useSession } from 'vinxi/http';

// Basic setup with default configuration
const auth = createAuthCallbacks(useSession);

// Example with bcrypt password hashing
import bcrypt from 'bcryptjs';

const authWithHashing = createAuthCallbacks(useSession, {
  hash: (password) => bcrypt.hash(password, 10),
  compare: (password, hashedPassword) =>
    bcrypt.compare(password, hashedPassword),
});

Core Concepts

1. Session Management

Sessions are handled through Vinxi's session system. The library automatically manages:

  • Session creation and storage
  • User authentication state
  • Secure session updates
// Get current session
const session = await auth.getSession();

// Access session data
const userId = session.data.userId;

// Update session
await session.update((data) => {
  data.customField = 'value';
});

// Clear session
await session.clear();

2. User Authentication

Login Flow

try {
  const user = await auth.login(
    username,
    password,
    // Your database lookup function
    async (username) => {
      return await db.user.findUnique({
        where: { username },
      });
    }
  );

  // Get session to store user ID
  const session = await auth.getSession();
  await session.update((data) => {
    data.userId = user.id.toString();
  });
} catch (error) {
  // Handle login errors
}

Registration Flow

try {
  const user = await auth.register(
    username,
    password,
    // Lookup function to check for existing users
    async (username) => {
      return await db.user.findUnique({
        where: { username },
      });
    },
    // Creation function to store new user
    async (username, hashedPassword) => {
      return await db.user.create({
        data: {
          username,
          password: hashedPassword,
        },
      });
    }
  );
} catch (error) {
  // Handle registration errors
}

3. Input Validation

The library provides built-in validation functions:

// Username validation (minimum 3 characters)
const usernameError = auth.validateUsername(username);
if (usernameError) {
  // Handle invalid username
}

// Password validation (minimum 6 characters)
const passwordError = auth.validatePassword(password);
if (passwordError) {
  // Handle invalid password
}

// Email validation
import { isValidEmail } from '@solidstart-auth/server';
if (!isValidEmail(email)) {
  // Handle invalid email
}

Configuration

Environment Variables

SESSION_SECRET=your_secure_secret_here

If SESSION_SECRET is not provided, a default value is used in development. Always set a secure secret in production.

Types

The library exports these TypeScript interfaces:

interface User {
  id: number;
  username: string;
  password: string;
  email?: string;
  provider?: string;
}

interface Session {
  data: {
    userId?: string;
    [key: string]: unknown;
  };
  update: (updater: (data: Session['data']) => void) => Promise<void>;
  clear: () => Promise<void>;
}

interface AuthCallbacks {
  getSession: () => Promise<Session>;
  login: (
    username: string,
    password: string,
    userLookupFunction: (username: string) => Promise<User | undefined>
  ) => Promise<User>;
  register: (
    username: string,
    password: string,
    userLookupFunction: (username: string) => Promise<User | undefined>,
    userCreateFunction: (username: string, password: string) => Promise<User>
  ) => Promise<User>;
  logout: () => Promise<void>;
  validateUsername: (username: string) => string | undefined;
  validatePassword: (password: string) => string | undefined;
}

Security Best Practices

  1. Password Hashing: Always implement password hashing in production:
import bcrypt from 'bcryptjs';

const auth = createAuthCallbacks(useSession, {
  hash: (password) => bcrypt.hash(password, 10),
  compare: bcrypt.compare,
});
  1. Session Security:

    • Set a strong SESSION_SECRET in production
    • Use HTTPS in production
    • Implement CSRF protection
    • Consider session expiration policies
  2. Rate Limiting: Implement rate limiting for login/register endpoints

  3. Input Validation: Always validate and sanitize user input before processing

Common Integration Patterns

1. Protected Routes

import { createAuthCallbacks } from '@solidstart-auth/server';
import { useSession } from 'vinxi/http';
import { redirect } from '@solidjs/router';

const auth = createAuthCallbacks(useSession);

export async function protectedLoader() {
  const session = await auth.getSession();
  if (!session.data.userId) {
    throw redirect('/login');
  }
  return {};
}

2. User Context

import { createContext, useContext } from 'solid-js';
import type { User } from '@solidstart-auth/server';

const UserContext = createContext<User>();

export function UserProvider(props) {
  // Implement user loading logic
  return (
    <UserContext.Provider value={props.user}>
      {props.children}
    </UserContext.Provider>
  );
}

Error Handling

The library throws errors in these cases:

  • User not found during login
  • Invalid password during login
  • Username already exists during registration
  • Invalid username format
  • Invalid password format

Example error handling:

try {
  await auth.login(username, password, lookupFn);
} catch (error) {
  if (error.message === 'User not found') {
    // Handle unknown user
  } else if (error.message === 'Invalid login') {
    // Handle wrong password
  }
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT