Add admin dashboard and Replit authentication integration
Integrates Replit authentication using OpenID Connect, adds an admin dashboard route with video management and thumbnail upload capabilities, and updates dependencies. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 890577b1-c154-40a4-a177-a0c6d55320c3 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/890577b1-c154-40a4-a177-a0c6d55320c3/1jMBtLj
This commit is contained in:
@@ -29,6 +29,7 @@ export interface IStorage {
|
||||
getUserByUsername(username: string): Promise<User | undefined>;
|
||||
createUser(user: InsertUser): Promise<User>;
|
||||
updateUser(id: string, user: Partial<InsertUser>): Promise<User | undefined>;
|
||||
upsertUser(user: any): Promise<User>;
|
||||
validateUserPassword(email: string, password: string): Promise<User | null>;
|
||||
|
||||
// Upload operations
|
||||
@@ -166,6 +167,34 @@ export class DatabaseStorage implements IStorage {
|
||||
return result[0];
|
||||
}
|
||||
|
||||
async upsertUser(userData: any): Promise<User> {
|
||||
const [user] = await db
|
||||
.insert(users)
|
||||
.values({
|
||||
id: userData.id,
|
||||
email: userData.email,
|
||||
firstName: userData.firstName,
|
||||
lastName: userData.lastName,
|
||||
profileImageUrl: userData.profileImageUrl,
|
||||
username: userData.email || `user_${userData.id}`,
|
||||
password: '', // No password for OAuth users
|
||||
isAdmin: false,
|
||||
isSuperAdmin: false,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: users.id,
|
||||
set: {
|
||||
email: userData.email,
|
||||
firstName: userData.firstName,
|
||||
lastName: userData.lastName,
|
||||
profileImageUrl: userData.profileImageUrl,
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
})
|
||||
.returning();
|
||||
return user;
|
||||
}
|
||||
|
||||
async validateUserPassword(email: string, password: string): Promise<User | null> {
|
||||
const user = await this.getUserByEmail(email);
|
||||
if (!user) return null;
|
||||
@@ -521,6 +550,25 @@ export class MemStorage implements IStorage {
|
||||
return updatedUser;
|
||||
}
|
||||
|
||||
async upsertUser(userData: any): Promise<User> {
|
||||
const existingUser = this.users.get(userData.id);
|
||||
const user: User = {
|
||||
id: userData.id,
|
||||
email: userData.email,
|
||||
firstName: userData.firstName,
|
||||
lastName: userData.lastName,
|
||||
profileImageUrl: userData.profileImageUrl,
|
||||
username: userData.email || `user_${userData.id}`,
|
||||
password: '',
|
||||
isAdmin: existingUser?.isAdmin || false,
|
||||
isSuperAdmin: existingUser?.isSuperAdmin || false,
|
||||
createdAt: existingUser?.createdAt || new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
this.users.set(userData.id, user);
|
||||
return user;
|
||||
}
|
||||
|
||||
async validateUserPassword(email: string, password: string): Promise<User | null> {
|
||||
const user = await this.getUserByEmail(email);
|
||||
if (!user) return null;
|
||||
@@ -759,6 +807,10 @@ class BunnyStorage implements IStorage {
|
||||
throw new Error("User operations are not supported with Bunny.net integration");
|
||||
}
|
||||
|
||||
async upsertUser(userData: any): Promise<User> {
|
||||
throw new Error("User operations are not supported with Bunny.net integration");
|
||||
}
|
||||
|
||||
async validateUserPassword(email: string, password: string): Promise<User | null> {
|
||||
throw new Error("User operations are not supported with Bunny.net integration");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user