mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 11:30:12 +08:00
feat: user sessions history & fix ts <any>
This commit is contained in:
1 parent
94ae2d7df4
commit
218a25daee
7 files changed
+95
-43
No files matched your search
@@ -1,8 +1,8 @@
|
|||||||
import { userCount } from '../models/users.js'
|
import { userCount } from '../models/users.js'
|
||||||
import { questList } from '../models/quests.ts'
|
import { questList } from '../models/quests.ts'
|
||||||
|
import { Request, Response } from 'express'
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export async function homeController(req: any, res: any) {
|
export async function homeController(req: Request, res: Response) {
|
||||||
const quests = await questList()
|
const quests = await questList()
|
||||||
const [totalQuests, totalCompleted] = quests.reduce(
|
const [totalQuests, totalCompleted] = quests.reduce(
|
||||||
([total, completed], quest) => [
|
([total, completed], quest) => [
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { questList } from '../models/quests.js'
|
import { questList } from '../models/quests.js'
|
||||||
|
import { Request, Response } from 'express'
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export async function questListController(req: any, res: any) {
|
export async function questListController(req: Request, res: Response) {
|
||||||
const quests = await questList()
|
const quests = await questList()
|
||||||
quests.forEach((quest) => {
|
quests.forEach((quest) => {
|
||||||
quest.failed = quest.started - quest.completed
|
quest.failed = quest.started - quest.completed
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import Pagination from '../models/pagination.ts'
|
import Pagination from '../models/pagination.ts'
|
||||||
import { sessionList, sessionDetail } from '../models/sessions.ts'
|
import { sessionList, sessionDetail } from '../models/sessions.ts'
|
||||||
import { Request, Response } from 'express'
|
import { Request, Response } from 'express'
|
||||||
export async function sessionListController(req: any, res: any) {
|
export async function sessionListController(req: Request, res: Response) {
|
||||||
const { nextKey, order } = req.query
|
const { nextKey, order } = req.query as { nextKey: string; order: string }
|
||||||
const itemsPerPage = 50
|
const itemsPerPage = 50
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -21,7 +21,7 @@ export async function sessionListController(req: any, res: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sessionDetailController(req: any, res: any) {
|
export async function sessionDetailController(req: Request, res: Response) {
|
||||||
const { id } = req.params
|
const { id } = req.params
|
||||||
const session = await sessionDetail(id)
|
const session = await sessionDetail(id)
|
||||||
res.render('sessionDetail', { session })
|
res.render('sessionDetail', { session })
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
<<<<<<< HEAD
|
import mongoose from 'mongoose'
|
||||||
import Pagination from '../models/pagination.ts'
|
import Pagination from '../models/pagination.ts'
|
||||||
import { userList, userDetail, idToUser } from '../models/users.js'
|
import { userList, userDetail, idToUser } from '../models/users.js'
|
||||||
=======
|
import { Request, Response } from 'express'
|
||||||
import Pagination from '../models/pagination.js'
|
export async function userListController(req: Request, res: Response) {
|
||||||
import { userList } from '../models/users.js'
|
const { nextKey, order } = req.query as { nextKey: string; order: string }
|
||||||
>>>>>>> bb4a11b20c8fdad8459ac3b7a0fdb8d9d9221e31
|
|
||||||
|
|
||||||
export async function userListController(req: any, res: any) {
|
|
||||||
const { nextKey, order } = req.query
|
|
||||||
const itemsPerPage = 50
|
const itemsPerPage = 50
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -25,9 +21,8 @@ export async function userListController(req: any, res: any) {
|
|||||||
res.status(500).send('Error fetching user data')
|
res.status(500).send('Error fetching user data')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
export async function userDetailController(req: Request, res: Response) {
|
||||||
export async function userDetailController(req: any, res: any) {
|
const id = new mongoose.Types.ObjectId(req.params.id)
|
||||||
const { id } = req.params
|
|
||||||
const sessions = await userDetail(id)
|
const sessions = await userDetail(id)
|
||||||
try {
|
try {
|
||||||
const user = await idToUser(id)
|
const user = await idToUser(id)
|
||||||
@@ -37,5 +32,3 @@ export async function userDetailController(req: any, res: any) {
|
|||||||
res.status(500).send('Error fetching user data')
|
res.status(500).send('Error fetching user data')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
=======
|
|
||||||
>>>>>>> bb4a11b20c8fdad8459ac3b7a0fdb8d9d9221e31
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { Types } from 'mongoose'
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
username: string
|
||||||
|
}
|
||||||
|
export interface SessionDocument {
|
||||||
|
_id: Types.ObjectId
|
||||||
|
user: User
|
||||||
|
quest: string
|
||||||
|
status: string
|
||||||
|
createdAt: Date
|
||||||
|
finishedAt: Date
|
||||||
|
}
|
||||||
|
export interface CommandObject {
|
||||||
|
command: string
|
||||||
|
pwd: string
|
||||||
|
stage: string | null | undefined
|
||||||
|
output: string | undefined
|
||||||
|
error: string | undefined
|
||||||
|
createdAt: string
|
||||||
|
}
|
||||||
|
export interface SessionObject {
|
||||||
|
_id: Types.ObjectId
|
||||||
|
user: string
|
||||||
|
quest: string
|
||||||
|
status: string
|
||||||
|
createdAt: string
|
||||||
|
finishedAt: string
|
||||||
|
lastActivityAt: string
|
||||||
|
usedTime: string
|
||||||
|
commandCount: number
|
||||||
|
commands: CommandObject[]
|
||||||
|
}
|
||||||
|
export interface SessionDetail {
|
||||||
|
_id: Types.ObjectId
|
||||||
|
user: string
|
||||||
|
quest: string
|
||||||
|
status: string
|
||||||
|
createdAt: string
|
||||||
|
finishedAt: string
|
||||||
|
usedTime: string
|
||||||
|
commands: CommandObject[]
|
||||||
|
}
|
||||||
|
export interface IUser extends Document {
|
||||||
|
hashedPassword?: string
|
||||||
|
socialLogins?: Record<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
id: string
|
||||||
|
provider: string
|
||||||
|
displayName?: string | null | undefined
|
||||||
|
}
|
||||||
|
>
|
||||||
|
}
|
||||||
|
export interface UserSessionDetail {
|
||||||
|
_id: Types.ObjectId
|
||||||
|
quest: string
|
||||||
|
status: string
|
||||||
|
createdAt: string
|
||||||
|
usedTime: string
|
||||||
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
import { Command, Session } from '@linux-odyssey/models'
|
import { Command, Session } from '@linux-odyssey/models'
|
||||||
import Pagination from './pagination.ts'
|
import Pagination from './pagination.ts'
|
||||||
import { Types } from 'mongoose'
|
import {
|
||||||
|
CommandObject,
|
||||||
|
SessionDetail,
|
||||||
|
SessionDocument,
|
||||||
|
SessionObject,
|
||||||
|
} from '../interface.ts'
|
||||||
|
|
||||||
function formatTime(time: number) {
|
function formatTime(time: number) {
|
||||||
const seconds = Math.floor(time / 1000)
|
const seconds = Math.floor(time / 1000)
|
||||||
@@ -9,7 +14,9 @@ function formatTime(time: number) {
|
|||||||
return `${hours}h ${minutes % 60}m ${seconds % 60}s`
|
return `${hours}h ${minutes % 60}m ${seconds % 60}s`
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sessionList(pagination: Pagination): Promise<any[]> {
|
export async function sessionList(
|
||||||
|
pagination: Pagination
|
||||||
|
): Promise<SessionObject[]> {
|
||||||
const sessions = await Session.aggregate([
|
const sessions = await Session.aggregate([
|
||||||
pagination.match('_id'),
|
pagination.match('_id'),
|
||||||
{
|
{
|
||||||
@@ -57,26 +64,16 @@ export async function sessionList(pagination: Pagination): Promise<any[]> {
|
|||||||
? formatTime(lastActivityAt.getTime() - createdAt.getTime())
|
? formatTime(lastActivityAt.getTime() - createdAt.getTime())
|
||||||
: 'N/A', // Ensure both dates are present
|
: 'N/A', // Ensure both dates are present
|
||||||
commandCount: commands?.length || 0,
|
commandCount: commands?.length || 0,
|
||||||
|
commands,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
interface User {
|
|
||||||
username: string
|
|
||||||
}
|
|
||||||
interface SessionDocument {
|
|
||||||
_id: Types.ObjectId
|
|
||||||
user: User
|
|
||||||
quest: string
|
|
||||||
status: string
|
|
||||||
createdAt: Date
|
|
||||||
finishedAt: Date
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function sessionDetail(id: string): Promise<any> {
|
export async function sessionDetail(id: string): Promise<SessionDetail> {
|
||||||
const session = (await Session.findById(id)
|
const session = (await Session.findById(id)
|
||||||
.populate('user')
|
.populate('user')
|
||||||
.exec()) as unknown as SessionDocument
|
.exec()) as unknown as SessionDocument
|
||||||
const commands = (await Command.find({ session: id })).map(
|
const commands: CommandObject[] = (await Command.find({ session: id })).map(
|
||||||
({ command, pwd, output, error, createdAt, stage }) => ({
|
({ command, pwd, output, error, createdAt, stage }) => ({
|
||||||
command: command?.slice(0, 20),
|
command: command?.slice(0, 20),
|
||||||
pwd,
|
pwd,
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import { Session, User } from '@linux-odyssey/models'
|
import { Session, User } from '@linux-odyssey/models'
|
||||||
import Pagination from './pagination.ts'
|
import Pagination from './pagination.ts'
|
||||||
import { ObjectId, Model } from 'mongoose'
|
import { Types } from 'mongoose'
|
||||||
|
import { IUser, UserSessionDetail } from '../interface.ts'
|
||||||
interface IUser extends Document {
|
|
||||||
hashedPassword?: string
|
|
||||||
socialLogins?: Record<string, any>
|
|
||||||
}
|
|
||||||
|
|
||||||
function loginMethods(user: IUser): string[] {
|
function loginMethods(user: IUser): string[] {
|
||||||
const methods: string[] = []
|
const methods: string[] = []
|
||||||
@@ -62,12 +58,15 @@ export async function userList(pagination: Pagination) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export async function userDetail(id: ObjectId): Promise<Object> {
|
|
||||||
|
export async function userDetail(
|
||||||
|
id: Types.ObjectId
|
||||||
|
): Promise<UserSessionDetail[]> {
|
||||||
const sessions = await Session.find({
|
const sessions = await Session.find({
|
||||||
user: id,
|
user: id,
|
||||||
})
|
})
|
||||||
return sessions.map((session) => {
|
return sessions.map((session) => {
|
||||||
const { _id, user, quest, status, createdAt, lastActivityAt } = session
|
const { _id, quest, status, createdAt, lastActivityAt } = session
|
||||||
return {
|
return {
|
||||||
_id,
|
_id,
|
||||||
quest,
|
quest,
|
||||||
@@ -81,7 +80,8 @@ export async function userDetail(id: ObjectId): Promise<Object> {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export async function idToUser(id: ObjectId): Promise<String> {
|
|
||||||
|
export async function idToUser(id: Types.ObjectId): Promise<String> {
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
_id: id,
|
_id: id,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in new issue
Block a user