Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jul 30, 2025

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original description:

refactor the auth source based on the following spec. Please do use API endpoint https://mixcore.net/swagger/v2/swagger.json.

Mixcore SPA Portal Authentication Integration Guide

For Svelte 5 and SvelteKit 2 Source Base


Table of Contents

  1. Overview
  2. API Endpoints (I/O)
  3. Authentication Flow (Sequence Diagram)
  4. Step-by-Step SvelteKit 2 Integration

Overview

Mixcore SPA Portal uses a secure authentication system with these features:

  • User registration and login (with client-side AES encryption)
  • Token-based authentication (JWT)
  • Token refresh flow
  • External provider login (OAuth, e.g., Google)
  • Role and permission-based access
  • Password reset

You’ll interact with the Mixcore API via RESTful endpoints, handling tokens and user state in your Svelte/SvelteKit app.


API Endpoints (I/O)

Action Method Endpoint Request Body/Params Response
Register POST /account/register { username, email, password, ... } { isSucceed, errors }
Login POST /account/login { message: <AES-encrypted JSON> } { isSucceed, data: {accessToken, refreshToken, userInfo}, errors }
Refresh Token POST /account/refresh-token { refreshToken, accessToken } { isSucceed, data: {accessToken, refreshToken}, errors }
Logout GET* /account/logout - { isSucceed }
Forgot Password POST /account/forgot-password { email } { isSucceed, errors }
Reset Password POST /account/reset-password { token, newPassword } { isSucceed, errors }
External Login GET /api/Account/ExternalLogin?provider=... Redirect URL params OAuth login redirect flow
External Callback POST /account/external-login { message: <AES-encrypted JSON> } { isSucceed, data: {accessToken, refreshToken}, errors }
Protected Data GET Any protected endpoint Header: Authorization: Bearer <token> { ... } or 401

* Logout is usually handled by removing local tokens and redirecting the user.


Authentication Flow (Sequence Diagram)

sequenceDiagram
    participant User
    participant SvelteApp
    participant API as Mixcore API
    participant OAuth as OAuth Provider

    %% Registration
    User->>SvelteApp: Fills registration form
    SvelteApp->>API: POST /account/register
    API-->>SvelteApp: { isSucceed, errors }

    %% Login
    User->>SvelteApp: Enters credentials
    SvelteApp->>API: POST /account/login (AES-encrypted)
    API-->>SvelteApp: { accessToken, refreshToken, userInfo }

    %% Protected Request
    SvelteApp->>API: GET /protected (Bearer token)
    API-->>SvelteApp: { data } or 401

    %% Token Refresh
    SvelteApp->>API: POST /account/refresh-token
    API-->>SvelteApp: { accessToken, refreshToken }

    %% Logout
    User->>SvelteApp: Clicks logout
    SvelteApp->>API: (Clear tokens, redirect)

    %% Forgot/Reset Password
    User->>SvelteApp: Request reset
    SvelteApp->>API: POST /account/forgot-password
    API-->>User: Email with link
    User->>SvelteApp: Submit new password + token
    SvelteApp->>API: POST /account/reset-password
    API-->>SvelteApp: { isSucceed }

    %% External Login
    User->>SvelteApp: Clicks external login
    SvelteApp->>OAuth: OAuth flow
    OAuth-->>SvelteApp: Callback with token
    SvelteApp->>API: POST /account/external-login
    API-->>SvelteApp: { accessToken, refreshToken }
Loading

Integration Instructions for Svelte 5 / SvelteKit 2

1. Project Setup

  • Install dependencies:
    npm install @auth/core axios aes-js

2. Create an Auth Store

  • Use Svelte stores to manage authentication state:
    import { writable } from 'svelte/store';
    
    export const auth = writable({
      accessToken: null,
      refreshToken: null,
      user: null,
      isAuthenticated: false
    });

3. AES Encrypt Credentials Before Login

  • Use aes-js or another crypto library for client-side encryption:

    import aesjs from 'aes-js';
    
    export function encryptAES(plainText: string, key: Uint8Array) {
      const textBytes = aesjs.utils.utf8.toBytes(plainText);
      const aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(5));
      const encryptedBytes = aesCtr.encrypt(textBytes);
      return aesjs.utils.hex.fromBytes(encryptedBytes);
    }
  • Note: The encryption key should match what the Mixcore backend expects. For POC/dev, skip encryption, but for prod, coordinate with backend for secure key exchange.

4. Write API Request Helpers

  • Use axios for HTTP requests and attach the Bearer token as needed:
    import axios from 'axios';
    import { get } from 'svelte/store';
    import { auth } from './stores/auth';
    
    const API_BASE = 'https://your-mixcore-api-url';
    
    export async function login(username: string, password: string) {
      // Encrypt credentials as needed
      // const message = encryptAES(JSON.stringify({ UserName: username, Password: password }), key);
      const message = JSON.stringify({ UserName: username, Password: password });
    
      const res = await axios.post(`${API_BASE}/account/login`, { message });
      if (res.data.isSucceed) {
        const { accessToken, refreshToken, userInfo } = res.data.data;
        auth.set({ accessToken, refreshToken, user: userInfo, isAuthenticated: true });
        // Store tokens in localStorage/sessionStorage
        localStorage.setItem('accessToken', accessToken);
        localStorage.setItem('refreshToken', refreshToken);
      }
      return res.data;
    }
    
    export function setAuthHeader() {
      const { accessToken } = get(auth);
      return {
        headers: {
          Authorization: `Bearer ${accessToken}`
        }
      };
    }
    
    export async function refreshToken() {
      const { refreshToken, accessToken } = get(auth);
      const res = await axios.post(`${API_BASE}/account/refresh-token`, { refreshToken, accessToken });
      if (res.data.isSucceed) {
        auth.update(a => ({ ...a, accessToken: res.data.data.accessToken, refreshToken: res.data.data.refreshToken }));
        localStorage.setItem('accessToken', res.data.data.accessToken);
        localStorage.setItem('refreshToken', res.data.data.refreshToken);
      }
    }

5. Protect SvelteKit Endpoints/Routes

  • Use hooks to check authentication for protected pages:

    import { auth } from '$lib/stores/auth';
    
    export async function handle({ event, resolve }) {
      const accessToken = event.cookies.get('accessToken');
      if (accessToken) {
        auth.set({ ...auth, accessToken, isAuthenticated: true });
      }
      return resolve(event);
    }
  • In SvelteKit load functions or page guards, check for auth.isAuthenticated.

6. External Login (OAuth)

  • To initiate external login:

    // Redirect user to: `${API_BASE}/api/Account/ExternalLogin?provider=Google&redirect_uri=${YOUR_CALLBACK_URL}`
  • On redirect/callback, handle the access token exchange as per the Mixcore API.

7. Logout

  • Clear tokens from store and storage, redirect user:
    export function logout() {
      auth.set({ accessToken: null, refreshToken: null, user: null, isAuthenticated: false });
      localStorage.removeItem('accessToken');
      localStorage.removeItem('refreshToken');
      // Optionally call API /account/logout
    }

8. Password Reset

  • POST /account/forgot-password with the user’s email.
  • POST /account/reset-password with the reset token and new password.

Summary

  • Encrypt credentials client-side before login if required.
  • Store tokens securely (localStorage, cookies, or SvelteKit session as appropriate).
  • Refresh tokens as needed when 401/unauthorized responses are received.
  • Protect routes using SvelteKit hooks and page logic.
  • Support OAuth by redirecting to the provider and handling the callback.
  • Handle registration, password reset, and logout per API contract.

References:


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copy link

vercel bot commented Jul 30, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
mix-portal-einstein ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 30, 2025 0:16am

@Smilefounder
Copy link
Member

continue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants