This commit is contained in:
Flatlogic Bot 2026-03-04 23:01:37 +00:00
parent 3a1a9af2f7
commit c56b38d9e4
7 changed files with 136 additions and 26 deletions

View File

@ -0,0 +1,40 @@
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Sessions', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
id: {
type: Sequelize.UUID
},
status: {
type: Sequelize.STRING
},
containerId: {
type: Sequelize.STRING
},
websocketUrl: {
type: Sequelize.STRING
},
userId: {
type: Sequelize.INTEGER
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Sessions');
}
};

View File

@ -0,0 +1,25 @@
'use strict';
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Session extends Model {
static associate(models) {
}
}
Session.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
status: DataTypes.STRING,
containerId: DataTypes.STRING,
websocketUrl: DataTypes.STRING,
userId: DataTypes.INTEGER
}, {
sequelize,
modelName: 'Session',
});
return Session;
};

View File

@ -1,4 +1,3 @@
const express = require('express');
const cors = require('cors');
const app = express();
@ -40,6 +39,7 @@ const session_eventsRoutes = require('./routes/session_events');
const network_policiesRoutes = require('./routes/network_policies');
const audit_logsRoutes = require('./routes/audit_logs');
const sessionsRoutes = require('./routes/sessions');
const getBaseUrl = (url) => {
@ -118,6 +118,8 @@ app.use('/api/session_events', passport.authenticate('jwt', {session: false}), s
app.use('/api/network_policies', passport.authenticate('jwt', {session: false}), network_policiesRoutes);
app.use('/api/audit_logs', passport.authenticate('jwt', {session: false}), audit_logsRoutes);
app.use('/api/sessions', passport.authenticate('jwt', {session: false}), sessionsRoutes);
app.use(
'/api/openai',
@ -163,4 +165,4 @@ db.sequelize.sync().then(function () {
});
});
module.exports = app;
module.exports = app;

View File

@ -0,0 +1,25 @@
const express = require('express');
const router = express.Router();
const { Session } = require('../db/models');
const { wrapAsync, checkCrudPermissions } = require('../helpers');
router.get('/', checkCrudPermissions('sessions'), wrapAsync(async (req, res) => {
const sessions = await Session.findAll({ where: { userId: req.currentUser.id } });
res.status(200).json({ rows: sessions, count: sessions.length });
}));
router.post('/', checkCrudPermissions('sessions'), wrapAsync(async (req, res) => {
const newSession = await Session.create({
id: require('crypto').randomUUID(),
status: 'starting',
userId: req.currentUser.id
});
res.status(201).json(newSession);
}));
router.delete('/:id', checkCrudPermissions('sessions'), wrapAsync(async (req, res) => {
await Session.destroy({ where: { id: req.params.id, userId: req.currentUser.id } });
res.status(204).send();
}));
module.exports = router;

View File

@ -2,7 +2,7 @@ import axios from 'axios';
export async function getPexelsImage() {
try {
const response = await axios.get(`/pexels/image`);
const response = await axios.get('pexels/image');
return response.data;
} catch (error) {
console.error('Error fetching image:', error);
@ -12,7 +12,7 @@ export async function getPexelsImage() {
export async function getPexelsVideo() {
try {
const response = await axios.get(`/pexels/video`);
const response = await axios.get('pexels/video');
return response.data;
} catch (error) {
console.error('Error fetching video:', error);
@ -50,7 +50,7 @@ export async function getMultiplePexelsImages(
const queryString = missingQueries.join(',');
try {
const response = await axios.get(`/pexels/multiple-images`, {
const response = await axios.get('pexels/multiple-images', {
params: { queries: queryString },
});
@ -73,4 +73,4 @@ export async function getMultiplePexelsImages(
localStorageLock = false;
return result;
}
}

View File

@ -40,23 +40,30 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const [stepName, setStepName] = React.useState('');
const [steps, setSteps] = React.useState([]);
axios.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
} else {
delete config.headers.Authorization;
}
return config;
},
error => {
return Promise.reject(error);
React.useEffect(() => {
const interceptorId = axios.interceptors.request.use(
(config) => {
if (typeof window === 'undefined') {
return config;
}
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
} else {
delete config.headers.Authorization;
}
return config;
},
(error) => Promise.reject(error),
);
return () => {
axios.interceptors.request.eject(interceptorId);
};
}, []);
// TODO: Remove this code in future releases
React.useEffect(() => {
const allowedOrigin = (() => {

View File

@ -31,7 +31,7 @@ export const loginUser = createAsyncThunk(
try {
const response = await axios.post('auth/signin/local', creds);
return response.data;
} catch (error) {
} catch (error: any) {
if (!error.response) {
throw error;
}
@ -51,7 +51,7 @@ export const passwordReset = createAsyncThunk(
});
return response.data;
} catch (error) {
} catch (error: any) {
if (!error.response) {
throw error;
}
@ -76,18 +76,22 @@ export const authSlice = createSlice({
axios.defaults.headers.common['Authorization'] = '';
state.currentUser = null;
state.token = '';
state.isFetching = false;
},
},
extraReducers: (builder) => {
builder.addCase(loginUser.pending, (state) => {
state.isFetching = true;
state.errorMessage = '';
});
builder.addCase(loginUser.fulfilled, (state, action) => {
const token = action.payload;
const user = jwt.decode(token);
state.errorMessage = '';
state.token = token;
state.isFetching = false;
localStorage.setItem('token', token);
localStorage.setItem('user', JSON.stringify(user));
axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
@ -97,20 +101,27 @@ export const authSlice = createSlice({
state.errorMessage = String(action.payload) || 'Something went wrong. Try again';
state.isFetching = false;
});
builder.addCase(findMe.pending, () => {
console.log('Pending findMe');
builder.addCase(findMe.pending, (state) => {
state.isFetching = true;
});
builder.addCase(findMe.fulfilled, (state, action) => {
state.currentUser = action.payload;
state.isFetching = false;
});
builder.addCase(passwordReset.fulfilled, (state, action) => {
builder.addCase(findMe.rejected, (state) => {
state.isFetching = false;
state.currentUser = null;
});
builder.addCase(passwordReset.fulfilled, (state) => {
state.notify.showNotification = true;
state.notify.textNotification = 'Password has been reset successfully';
});
builder.addCase(resetAction, (state) => initialState);
builder.addCase(resetAction, () => initialState);
builder.addCase(passwordReset.rejected, (state) => {
state.errorMessage = 'Something was wrong. Try again';