1.0.6 • Published 7 months ago

socialauthify v1.0.6

Weekly downloads
-
License
MIT
Repository
-
Last release
7 months ago

socialauthify

A flexible social authentication package supporting multiple OAuth providers for React, Vue, and Svelte applications.

Features

  • Multiple OAuth providers:
    • Google
    • Microsoft
    • Facebook
    • LinkedIn
    • GitHub
  • Built-in token management
  • Loading and error states
  • TypeScript support
  • Framework-agnostic
  • Customizable styling

Installation

npm install socialauthify

Quick Start

React

import React, { useState } from 'react';
import { setConfig, googleLogin, microsoftLogin, /* ... */ } from 'socialauthify';

// Configure OAuth providers
setConfig({
  google: {
    clientId: 'YOUR_GOOGLE_CLIENT_ID',
    clientSecret: 'YOUR_GOOGLE_CLIENT_SECRET',
    redirectUri: 'http://localhost:3000/home',
    scope: 'email profile openid'
  },
  microsoft: {
    clientId: 'YOUR_MICROSOFT_CLIENT_ID',
    clientSecret: 'YOUR_MICROSOFT_CLIENT_SECRET',
    redirectUri: 'http://localhost:3000/home',
    scope: 'user.read openid profile email'
  }
  // ... other providers
});

function Login({ onLoginSuccess, onError }) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const handleLogin = async (provider, loginFunction) => {
    setLoading(true);
    try {
      sessionStorage.setItem('oauth_provider', provider.toLowerCase());
      await loginFunction();
    } catch (error) {
      const errorMessage = `${provider} login failed: ${error.message}`;
      setError(errorMessage);
      onError?.(errorMessage);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      {error && <div>{error}</div>}
      {loading && <div>Loading...</div>}
      
      <button onClick={() => handleLogin('Google', googleLogin)}>
        Login with Google
      </button>
      <button onClick={() => handleLogin('Microsoft', microsoftLogin)}>
        Login with Microsoft
      </button>
      {/* Add other provider buttons */}
    </div>
  );
}

Vue

<!-- Login.vue -->
<template>
  <div>
    <div v-if="error" class="error">{{ error }}</div>
    <div v-if="loading" class="loading">Loading...</div>

    <button 
      v-for="provider in providers" 
      :key="provider.name"
      @click="handleLogin(provider.name, provider.login)"
      :style="provider.style"
    >
      Login with {{ provider.name }}
    </button>
  </div>
</template>

<script>
import { ref } from 'vue';
import { 
  setConfig, 
  googleLogin, 
  microsoftLogin,
  handleGoogleCallback,
  handleMicrosoftCallback
} from 'socialauthify';

// Configure OAuth providers
setConfig({
  google: {
    clientId: 'YOUR_GOOGLE_CLIENT_ID',
    clientSecret: 'YOUR_GOOGLE_CLIENT_SECRET',
    redirectUri: 'http://localhost:3000/home',
    scope: 'email profile openid'
  },
  microsoft: {
    clientId: 'YOUR_MICROSOFT_CLIENT_ID',
    clientSecret: 'YOUR_MICROSOFT_CLIENT_SECRET',
    redirectUri: 'http://localhost:3000/home',
    scope: 'user.read openid profile email'
  }
});

export default {
  setup() {
    const loading = ref(false);
    const error = ref(null);

    const providers = [
      { 
        name: 'Google', 
        login: googleLogin,
        callback: handleGoogleCallback,
        style: { backgroundColor: '#4285f4', color: 'white' }
      },
      { 
        name: 'Microsoft', 
        login: microsoftLogin,
        callback: handleMicrosoftCallback,
        style: { backgroundColor: '#00a4ef', color: 'white' }
      }
      // Add other providers
    ];

    const handleLogin = async (provider, loginFunction) => {
      loading.value = true;
      try {
        sessionStorage.setItem('oauth_provider', provider.toLowerCase());
        await loginFunction();
      } catch (err) {
        error.value = `${provider} login failed: ${err.message}`;
      } finally {
        loading.value = false;
      }
    };

    return {
      loading,
      error,
      providers,
      handleLogin
    };
  }
};
</script>

Svelte

<!-- Login.svelte -->
<script>
  import { onMount } from 'svelte';
  import { 
    setConfig, 
    googleLogin, 
    microsoftLogin,
    handleGoogleCallback,
    handleMicrosoftCallback 
  } from 'socialauthify';

  // Configure OAuth providers
  setConfig({
    google: {
      clientId: 'YOUR_GOOGLE_CLIENT_ID',
      clientSecret: 'YOUR_GOOGLE_CLIENT_SECRET',
      redirectUri: 'http://localhost:3000/home',
      scope: 'email profile openid'
    },
    microsoft: {
      clientId: 'YOUR_MICROSOFT_CLIENT_ID',
      clientSecret: 'YOUR_MICROSOFT_CLIENT_SECRET',
      redirectUri: 'http://localhost:3000/home',
      scope: 'user.read openid profile email'
    }
  });

  let loading = false;
  let error = null;

  const providers = [
    {
      name: 'Google',
      login: googleLogin,
      callback: handleGoogleCallback,
      style: 'background-color: #4285f4; color: white;'
    },
    {
      name: 'Microsoft',
      login: microsoftLogin,
      callback: handleMicrosoftCallback,
      style: 'background-color: #00a4ef; color: white;'
    }
    // Add other providers
  ];

  async function handleLogin(provider, loginFunction) {
    loading = true;
    try {
      sessionStorage.setItem('oauth_provider', provider.toLowerCase());
      await loginFunction();
    } catch (err) {
      error = `${provider} login failed: ${err.message}`;
    } finally {
      loading = false;
    }
  }

  onMount(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const code = urlParams.get('code');
    const provider = sessionStorage.getItem('oauth_provider');
    
    if (code && provider) {
      handleCallback(code, provider);
    }
  });
</script>

{#if error}
  <div class="error">{error}</div>
{/if}

{#if loading}
  <div class="loading">Loading...</div>
{/if}

<div class="button-container">
  {#each providers as provider}
    <button
      on:click={() => handleLogin(provider.name, provider.login)}
      style={provider.style}
      disabled={loading}
    >
      Login with {provider.name}
    </button>
  {/each}
</div>

<style>
  .button-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 400px;
    margin: 40px auto;
  }

  button {
    padding: 12px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
    font-weight: 500;
  }

  .error {
    color: red;
    text-align: center;
    margin-bottom: 10px;
    padding: 10px;
    background-color: #ffebee;
    border-radius: 4px;
  }

  .loading {
    text-align: center;
    color: #666;
    margin-bottom: 10px;
  }
</style>

Configuration Options

ProviderRequired Scopes
Googleemail profile openid
Microsoftuser.read openid profile email
Facebookemail public_profile
LinkedInopenid profile email
GitHubread:user user:email

TypeScript Support

Types are included and no separate @types package is needed.

Error Handling

The package provides detailed error information that you can handle in your application:

try {
  await handleGoogleCallback(code);
} catch (error) {
  console.error('Provider error:', error.message);
}

Security Best Practices

  1. Always use environment variables for client secrets
  2. Implement proper state validation
  3. Use HTTPS in production
  4. Never store tokens in localStorage
  5. Implement proper session management

License

MIT

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

1.0.6

7 months ago

1.0.5

7 months ago

1.0.4

7 months ago

1.0.3

7 months ago