Enhance deployment script and update package dependencies

- Added detailed labels to the deployment script for IndeedHub, including title, version, description, license, icon, and repository URL.
- Updated package dependencies in package.json and package-lock.json, including upgrading 'nostr-tools' to version 2.23.0 and adding 'axios' and '@tanstack/vue-query'.
- Improved README with a modern description of the platform and updated project structure details.

This commit enhances the clarity of the deployment process and ensures the project is using the latest dependencies for better performance and features.
This commit is contained in:
Dorian
2026-02-12 10:30:47 +00:00
parent dacfa7a822
commit c970f5b29f
43 changed files with 6906 additions and 603 deletions

412
src/stores/auth.ts Normal file
View File

@@ -0,0 +1,412 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { authService } from '../services/auth.service'
import type { ApiUser } from '../types/api'
export type AuthType = 'cognito' | 'nostr' | null
export interface AuthState {
user: ApiUser | null
authType: AuthType
isAuthenticated: boolean
nostrPubkey: string | null
cognitoToken: string | null
isLoading: boolean
}
/**
* Authentication Store
* Manages user authentication state with dual Cognito/Nostr support
*/
export const useAuthStore = defineStore('auth', () => {
// State
const user = ref<ApiUser | null>(null)
const authType = ref<AuthType>(null)
const isAuthenticated = ref(false)
const nostrPubkey = ref<string | null>(null)
const cognitoToken = ref<string | null>(null)
const isLoading = ref(false)
/**
* Initialize auth state from stored tokens
*/
async function initialize() {
isLoading.value = true
try {
// Check for existing tokens
const storedCognitoToken = sessionStorage.getItem('auth_token')
const storedNostrToken = sessionStorage.getItem('nostr_token')
if (storedCognitoToken || storedNostrToken) {
// Validate session and fetch user
const isValid = await authService.validateSession()
if (isValid) {
await fetchCurrentUser()
if (storedCognitoToken) {
authType.value = 'cognito'
cognitoToken.value = storedCognitoToken
} else {
authType.value = 'nostr'
}
isAuthenticated.value = true
} else {
// Session invalid - clear auth
await logout()
}
}
} catch (error) {
console.error('Failed to initialize auth:', error)
await logout()
} finally {
isLoading.value = false
}
}
/**
* Login with email and password (Cognito)
*/
async function loginWithCognito(email: string, password: string) {
isLoading.value = true
try {
// Check if we're in development mode without backend
const useMockData = import.meta.env.VITE_USE_MOCK_DATA === 'true' || import.meta.env.DEV
if (useMockData) {
// Mock Cognito login for development
console.log('🔧 Development mode: Using mock Cognito authentication')
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500))
// Create a mock user with active subscription
const mockUser = {
id: 'mock-user-' + email.split('@')[0],
email: email,
legalName: email.split('@')[0].charAt(0).toUpperCase() + email.split('@')[0].slice(1),
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
subscriptions: [{
id: 'mock-sub-cinephile',
userId: 'mock-user-' + email.split('@')[0],
tier: 'cinephile' as const,
status: 'active' as const,
currentPeriodStart: new Date().toISOString(),
currentPeriodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days from now
cancelAtPeriodEnd: false,
stripePriceId: 'mock-price-cinephile',
stripeCustomerId: 'mock-customer-' + email.split('@')[0],
}],
}
console.log('✅ Mock user created with Cinephile subscription (full access)')
cognitoToken.value = 'mock-jwt-token-' + Date.now()
authType.value = 'cognito'
user.value = mockUser
isAuthenticated.value = true
// Store mock tokens
sessionStorage.setItem('auth_token', cognitoToken.value)
sessionStorage.setItem('refresh_token', 'mock-refresh-token')
return {
accessToken: cognitoToken.value,
idToken: 'mock-id-token',
refreshToken: 'mock-refresh-token',
expiresIn: 3600,
}
}
// Real API call
const response = await authService.login({ email, password })
cognitoToken.value = response.accessToken
authType.value = 'cognito'
await fetchCurrentUser()
isAuthenticated.value = true
return response
} catch (error: any) {
// Provide helpful error message
if (error.message?.includes('Unable to connect')) {
throw new Error(
'Backend API not available. To use real authentication, start the backend server and set VITE_USE_MOCK_DATA=false in .env'
)
}
throw error
} finally {
isLoading.value = false
}
}
/**
* Login with Nostr signature
*/
async function loginWithNostr(pubkey: string, signature: string, event: any) {
isLoading.value = true
try {
// Check if we're in development mode without backend
const useMockData = import.meta.env.VITE_USE_MOCK_DATA === 'true' || import.meta.env.DEV
if (useMockData) {
// Mock Nostr login for development
console.log('🔧 Development mode: Using mock Nostr authentication')
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500))
// Create a mock Nostr user with active subscription
const mockUser = {
id: 'mock-nostr-user-' + pubkey.slice(0, 8),
email: `${pubkey.slice(0, 8)}@nostr.local`,
legalName: 'Nostr User',
nostrPubkey: pubkey,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
subscriptions: [{
id: 'mock-sub-cinephile',
userId: 'mock-nostr-user-' + pubkey.slice(0, 8),
tier: 'cinephile' as const,
status: 'active' as const,
currentPeriodStart: new Date().toISOString(),
currentPeriodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days from now
cancelAtPeriodEnd: false,
stripePriceId: 'mock-price-cinephile',
stripeCustomerId: 'mock-customer-' + pubkey.slice(0, 8),
}],
}
console.log('✅ Mock Nostr user created with Cinephile subscription (full access)')
console.log('📝 Nostr Pubkey:', pubkey)
nostrPubkey.value = pubkey
authType.value = 'nostr'
user.value = mockUser
isAuthenticated.value = true
// Store mock session
sessionStorage.setItem('nostr_token', 'mock-nostr-token-' + pubkey.slice(0, 16))
return {
token: 'mock-nostr-token',
user: mockUser,
}
}
// Real API call
const response = await authService.createNostrSession({
pubkey,
signature,
event,
})
nostrPubkey.value = pubkey
authType.value = 'nostr'
user.value = response.user
isAuthenticated.value = true
return response
} catch (error: any) {
// Provide helpful error message
if (error.message?.includes('Unable to connect')) {
throw new Error(
'Backend API not available. To use real Nostr authentication, start the backend server and set VITE_USE_MOCK_DATA=false in .env'
)
}
throw error
} finally {
isLoading.value = false
}
}
/**
* Register new user
*/
async function register(email: string, password: string, legalName: string) {
isLoading.value = true
try {
// Check if we're in development mode without backend
const useMockData = import.meta.env.VITE_USE_MOCK_DATA === 'true' || import.meta.env.DEV
if (useMockData) {
// Mock registration for development
console.log('🔧 Development mode: Using mock registration')
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 500))
// Create a mock user with active subscription
const mockUser = {
id: 'mock-user-' + email.split('@')[0],
email: email,
legalName: legalName,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
subscriptions: [{
id: 'mock-sub-cinephile',
userId: 'mock-user-' + email.split('@')[0],
tier: 'cinephile' as const,
status: 'active' as const,
currentPeriodStart: new Date().toISOString(),
currentPeriodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days from now
cancelAtPeriodEnd: false,
stripePriceId: 'mock-price-cinephile',
stripeCustomerId: 'mock-customer-' + email.split('@')[0],
}],
}
console.log('✅ Mock user registered with Cinephile subscription (full access)')
cognitoToken.value = 'mock-jwt-token-' + Date.now()
authType.value = 'cognito'
user.value = mockUser
isAuthenticated.value = true
// Store mock tokens
sessionStorage.setItem('auth_token', cognitoToken.value)
sessionStorage.setItem('refresh_token', 'mock-refresh-token')
return {
accessToken: cognitoToken.value,
idToken: 'mock-id-token',
refreshToken: 'mock-refresh-token',
expiresIn: 3600,
}
}
// Real API call
const response = await authService.register({
email,
password,
legalName,
})
cognitoToken.value = response.accessToken
authType.value = 'cognito'
await fetchCurrentUser()
isAuthenticated.value = true
return response
} catch (error: any) {
// Provide helpful error message
if (error.message?.includes('Unable to connect')) {
throw new Error(
'Backend API not available. To use real authentication, start the backend server and set VITE_USE_MOCK_DATA=false in .env'
)
}
throw error
} finally {
isLoading.value = false
}
}
/**
* Fetch current user data
*/
async function fetchCurrentUser() {
try {
const userData = await authService.getCurrentUser()
user.value = userData
if (userData.nostrPubkey) {
nostrPubkey.value = userData.nostrPubkey
}
return userData
} catch (error) {
console.error('Failed to fetch user:', error)
throw error
}
}
/**
* Logout user
*/
async function logout() {
await authService.logout()
user.value = null
authType.value = null
isAuthenticated.value = false
nostrPubkey.value = null
cognitoToken.value = null
}
/**
* Link Nostr pubkey to account
*/
async function linkNostr(pubkey: string, signature: string) {
try {
const updatedUser = await authService.linkNostrPubkey(pubkey, signature)
user.value = updatedUser
nostrPubkey.value = pubkey
return updatedUser
} catch (error) {
throw error
}
}
/**
* Unlink Nostr pubkey from account
*/
async function unlinkNostr() {
try {
const updatedUser = await authService.unlinkNostrPubkey()
user.value = updatedUser
nostrPubkey.value = null
return updatedUser
} catch (error) {
throw error
}
}
/**
* Check if user is filmmaker
*/
function isFilmmaker(): boolean {
return !!user.value?.filmmaker
}
/**
* Check if user has active subscription
*/
function hasActiveSubscription(): boolean {
if (!user.value?.subscriptions) return false
return user.value.subscriptions.some((sub) => sub.status === 'active')
}
return {
// State
user,
authType,
isAuthenticated,
nostrPubkey,
cognitoToken,
isLoading,
// Actions
initialize,
loginWithCognito,
loginWithNostr,
register,
fetchCurrentUser,
logout,
linkNostr,
unlinkNostr,
// Getters
isFilmmaker,
hasActiveSubscription,
}
})