mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-22 15:35:03 +00:00
sequelize, storage for userdata
This commit is contained in:
parent
9d540d6aa2
commit
09a3d83dc5
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,5 +6,5 @@ android/
|
|||||||
ios/
|
ios/
|
||||||
releases/
|
releases/
|
||||||
.vscode/
|
.vscode/
|
||||||
.env
|
.env.local
|
||||||
/server-node/jobs
|
/server-node/jobs
|
1254
package-lock.json
generated
1254
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
2
server-node/.env
Normal file
2
server-node/.env
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
JOBS_DIR="./jobs"
|
||||||
|
SESSION_SECRET="default-secret"
|
@ -41,6 +41,8 @@
|
|||||||
"pdf-lib": "^1.17.1",
|
"pdf-lib": "^1.17.1",
|
||||||
"rollup-plugin-copy": "^3.5.0",
|
"rollup-plugin-copy": "^3.5.0",
|
||||||
"rollup-plugin-dynamic-import-variables": "^1.1.0",
|
"rollup-plugin-dynamic-import-variables": "^1.1.0",
|
||||||
|
"sequelize": "^6.37.3",
|
||||||
|
"sqlite3": "^5.1.7",
|
||||||
"toml": "^3.0.0",
|
"toml": "^3.0.0",
|
||||||
"tsconfig-paths": "^4.2.0",
|
"tsconfig-paths": "^4.2.0",
|
||||||
"vite-plugin-compile-time": "^0.2.1",
|
"vite-plugin-compile-time": "^0.2.1",
|
||||||
|
@ -6,14 +6,14 @@ import { HeaderAPIKeyStrategy as HeaderAPIKeyStrategy } from "passport-headerapi
|
|||||||
export function initialize(passport: typeof import("passport")) {
|
export function initialize(passport: typeof import("passport")) {
|
||||||
passport.use("local", new LocalStrategy(
|
passport.use("local", new LocalStrategy(
|
||||||
function(username, password, done) {
|
function(username, password, done) {
|
||||||
User.findOne({ username: username }, function (err, user) {
|
User.findOne({ username: username }, async function (err, user) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err, false);
|
||||||
}
|
}
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return done(null, false);
|
return done(null, false);
|
||||||
}
|
}
|
||||||
if (!User.verifyPassword(user, password)) {
|
if (!await User.verifyPassword(user, password)) {
|
||||||
return done(null, false);
|
return done(null, false);
|
||||||
}
|
}
|
||||||
return done(null, user);
|
return done(null, user);
|
||||||
@ -35,7 +35,7 @@ export function initialize(passport: typeof import("passport")) {
|
|||||||
return done(null, user);
|
return done(null, user);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
passport.serializeUser((user, done) => {
|
passport.serializeUser((user, done) => {
|
||||||
done(null, user.id) //TODO: Extend Express.User to include id wich is set by passport
|
done(null, user.id) //TODO: Extend Express.User to include id wich is set by passport
|
||||||
|
@ -1,16 +1,55 @@
|
|||||||
import { User } from "./user-model";
|
import { Error as SequelizeError, Op } from "sequelize";
|
||||||
|
import { Password, User } from "./user-model";
|
||||||
|
|
||||||
export function findOne(params: {id?: number, username?: string, apikey?: string}, cb: (err: Error | null, user: User) => void): undefined {
|
type PickOne<T, F extends keyof T> = Pick<T, F> & { [K in keyof Omit<T, F>]?: never };
|
||||||
//TODO: replace with db connection.
|
|
||||||
cb(null, {
|
export function findOne(params: {id?: number, username?: string, apikey?: string}, cb: (err: Error | null, user: User | null) => void): undefined {
|
||||||
id: 1,
|
const query: any = params;
|
||||||
username: "test",
|
|
||||||
mail: "test@test.com",
|
for (let key in query) {
|
||||||
accessControlList: []
|
if (query[key] === undefined) {
|
||||||
});
|
delete query[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Object.keys(query).length == 0) {
|
||||||
|
cb(new Error("You need to provide at least one argument."), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
User.findOne({
|
||||||
|
where: query
|
||||||
|
}).then(user => {
|
||||||
|
if(user)
|
||||||
|
cb(null, user);
|
||||||
|
else
|
||||||
|
cb(new Error("The requested user was not found."), null);
|
||||||
|
}).catch(e =>
|
||||||
|
cb(e, null)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyPassword(user: User, password: string) {
|
export async function verifyPassword(user: User, password: string): Promise<boolean> {
|
||||||
//TODO: replace with db connection.
|
const passwordRecord = await user.getPassword();
|
||||||
return password == "test";
|
if(!passwordRecord) {
|
||||||
|
throw new Error("This user does not have a password set!");
|
||||||
|
}
|
||||||
|
return passwordRecord.password == password;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createUser(params: { username: string, password: string }, cb: (err: SequelizeError | null, user: User | null) => void ) {
|
||||||
|
User.create({ username: params.username, authenticationMethod: "password" }).then(async user => {
|
||||||
|
user.setPassword(await Password.create({
|
||||||
|
password: params.password,
|
||||||
|
})).then(password => {
|
||||||
|
cb(null, user as any as User)
|
||||||
|
}).catch(e =>
|
||||||
|
cb(e, null)
|
||||||
|
);
|
||||||
|
}).catch(e =>
|
||||||
|
cb(e, null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAPIKey(user: User, apikey?: string) {
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,80 @@
|
|||||||
export interface User {
|
import {
|
||||||
id: number,
|
Association, DataTypes, Model, ModelDefined, Optional,
|
||||||
username: string,
|
Sequelize, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ForeignKey,
|
||||||
mail: string,
|
|
||||||
accessControlList: string[],
|
HasManyAddAssociationMixin, HasManyCountAssociationsMixin,
|
||||||
|
HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, HasManyHasAssociationMixin,
|
||||||
|
HasManySetAssociationsMixin, HasManyAddAssociationsMixin, HasManyHasAssociationsMixin,
|
||||||
|
HasManyRemoveAssociationMixin, HasManyRemoveAssociationsMixin,
|
||||||
|
|
||||||
|
HasOneGetAssociationMixin, HasOneSetAssociationMixin, HasOneCreateAssociationMixin,
|
||||||
|
} from 'sequelize';
|
||||||
|
|
||||||
|
export class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
|
declare username: string;
|
||||||
|
declare mail?: string;
|
||||||
|
declare authenticationMethod: string;
|
||||||
|
|
||||||
|
declare getPassword: HasOneGetAssociationMixin<Password | undefined>; // Note the null assertions!
|
||||||
|
declare setPassword: HasOneSetAssociationMixin<Password | undefined, number>;
|
||||||
|
declare createPassword: HasOneCreateAssociationMixin<Password>;
|
||||||
|
|
||||||
|
declare getAccessRules: HasManyGetAssociationsMixin<AccessRule | undefined>; // Note the null assertions!
|
||||||
|
declare addAccessRule: HasManyAddAssociationMixin<AccessRule | undefined, number>;
|
||||||
|
declare addAccessRules: HasManyAddAssociationsMixin<AccessRule | undefined, number>;
|
||||||
|
declare setAccessRules: HasManySetAssociationsMixin<AccessRule | undefined, number>;
|
||||||
|
declare removeAccessRule: HasManyRemoveAssociationMixin<AccessRule | undefined, number>;
|
||||||
|
declare removeAccessRules: HasManyRemoveAssociationsMixin<AccessRule | undefined, number>;
|
||||||
|
declare hasAccessRule: HasManyHasAssociationMixin<AccessRule | undefined, number>;
|
||||||
|
declare hasAccessRules: HasManyHasAssociationsMixin<AccessRule | undefined, number>;
|
||||||
|
declare countAccessRules: HasManyCountAssociationsMixin;
|
||||||
|
declare createAccessRule: HasManyCreateAssociationMixin<AccessRule, 'userId'>;
|
||||||
|
|
||||||
|
declare getAPIKeys: HasManyGetAssociationsMixin<APIKey | undefined>; // Note the null assertions!
|
||||||
|
declare addAPIKey: HasManyAddAssociationMixin<APIKey | undefined, number>;
|
||||||
|
declare addAPIKeys: HasManyAddAssociationsMixin<APIKey | undefined, number>;
|
||||||
|
declare setAPIKeys: HasManySetAssociationsMixin<APIKey | undefined, number>;
|
||||||
|
declare removeAPIKey: HasManyRemoveAssociationMixin<APIKey | undefined, number>;
|
||||||
|
declare removeAPIKeys: HasManyRemoveAssociationsMixin<APIKey | undefined, number>;
|
||||||
|
declare hasAPIKey: HasManyHasAssociationMixin<APIKey | undefined, number>;
|
||||||
|
declare hasAPIKeys: HasManyHasAssociationsMixin<APIKey | undefined, number>;
|
||||||
|
declare countAPIKeys: HasManyCountAssociationsMixin;
|
||||||
|
declare createAPIKey: HasManyCreateAssociationMixin<APIKey, 'userId'>;
|
||||||
|
|
||||||
|
declare createdAt: CreationOptional<Date>;
|
||||||
|
declare updatedAt: CreationOptional<Date>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Password extends Model<InferAttributes<Password>, InferCreationAttributes<Password>> {
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
|
declare password: string;
|
||||||
|
|
||||||
|
declare ownerId: ForeignKey<User['id']>;
|
||||||
|
declare owner?: NonAttribute<User>;
|
||||||
|
|
||||||
|
declare createdAt: CreationOptional<Date>;
|
||||||
|
declare updatedAt: CreationOptional<Date>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AccessRule extends Model<InferAttributes<AccessRule>, InferCreationAttributes<AccessRule>> {
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
|
declare grants: string;
|
||||||
|
|
||||||
|
declare userId: ForeignKey<User['id']>;
|
||||||
|
declare user?: NonAttribute<User>;
|
||||||
|
|
||||||
|
declare createdAt: CreationOptional<Date>;
|
||||||
|
declare updatedAt: CreationOptional<Date>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class APIKey extends Model<InferAttributes<APIKey>, InferCreationAttributes<APIKey>> {
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
|
declare apikey: string;
|
||||||
|
|
||||||
|
declare userId: ForeignKey<User['id']>;
|
||||||
|
declare user?: NonAttribute<User>;
|
||||||
|
|
||||||
|
declare createdAt: CreationOptional<Date>;
|
||||||
|
declare updatedAt: CreationOptional<Date>;
|
||||||
}
|
}
|
87
server-node/src/data/sequelize-relations.ts
Normal file
87
server-node/src/data/sequelize-relations.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { Sequelize, DataTypes } from "sequelize";
|
||||||
|
|
||||||
|
//TODO: Make this configurable
|
||||||
|
const sequelize = new Sequelize("sqlite::memory:");
|
||||||
|
|
||||||
|
import { User, AccessRule, APIKey, Password } from "../auth/user/user-model";
|
||||||
|
|
||||||
|
User.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER.UNSIGNED,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
mail: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
authenticationMethod: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
createdAt: DataTypes.DATE,
|
||||||
|
updatedAt: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{ sequelize },
|
||||||
|
);
|
||||||
|
|
||||||
|
Password.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER.UNSIGNED,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
password: DataTypes.STRING,
|
||||||
|
createdAt: DataTypes.DATE,
|
||||||
|
updatedAt: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{ sequelize },
|
||||||
|
);
|
||||||
|
Password.hasOne(User);
|
||||||
|
User.hasOne(Password);
|
||||||
|
|
||||||
|
AccessRule.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER.UNSIGNED,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
grants: DataTypes.STRING,
|
||||||
|
createdAt: DataTypes.DATE,
|
||||||
|
updatedAt: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{ sequelize },
|
||||||
|
);
|
||||||
|
AccessRule.hasOne(User);
|
||||||
|
User.hasMany(AccessRule);
|
||||||
|
|
||||||
|
APIKey.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER.UNSIGNED,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true
|
||||||
|
},
|
||||||
|
apikey: DataTypes.STRING,
|
||||||
|
createdAt: DataTypes.DATE,
|
||||||
|
updatedAt: DataTypes.DATE,
|
||||||
|
},
|
||||||
|
{ sequelize },
|
||||||
|
);
|
||||||
|
APIKey.hasOne(User);
|
||||||
|
User.hasMany(APIKey);
|
||||||
|
|
||||||
|
export default sequelize;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await sequelize.sync({ force: true });
|
||||||
|
console.log("Database synced!")
|
||||||
|
})();
|
@ -27,6 +27,12 @@ console.log("Available Modules: ", listOperatorNames());
|
|||||||
|
|
||||||
import "./jobs/jobs-controller";
|
import "./jobs/jobs-controller";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* database
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "./data/sequelize-relations";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EXPRESS
|
* EXPRESS
|
||||||
*/
|
*/
|
||||||
|
@ -3,8 +3,8 @@ const router = express.Router();
|
|||||||
|
|
||||||
router.post('/logout', function(req, res, next) {
|
router.post('/logout', function(req, res, next) {
|
||||||
req.logout(function(err) {
|
req.logout(function(err) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err); }
|
||||||
res.redirect('/');
|
res.redirect('/');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,8 +1,35 @@
|
|||||||
|
import { error } from "pdf-lib";
|
||||||
|
import * as User from "../../auth/user/user-controller";
|
||||||
import express, { Request, Response } from "express";
|
import express, { Request, Response } from "express";
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.post('/register', async function(req: Request, res: Response) {
|
router.post('/register', async function(req: Request, res: Response) {
|
||||||
//TODO: Register new user
|
//TODO: Register new user
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post('/register/password', async function(req: Request, res: Response) {
|
||||||
|
if(req.query) {
|
||||||
|
if(!req.query.username) {
|
||||||
|
res.status(400).json({error: "no username was provided"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!req.query.password) {
|
||||||
|
res.status(400).json({error: "no password was provided"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
User.createUser({username: req.query.username as string, password: req.query.password as string}, async (err, user) => {
|
||||||
|
if(err) {
|
||||||
|
res.status(500).json(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.json(user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res.status(400).json({error: "no params were provided"})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
@ -10,6 +10,11 @@ export default defineConfig({
|
|||||||
// vite server configs, for details see [vite doc](https://vitejs.dev/config/#server-host)
|
// vite server configs, for details see [vite doc](https://vitejs.dev/config/#server-host)
|
||||||
port: 8000
|
port: 8000
|
||||||
},
|
},
|
||||||
|
optimizeDeps: {
|
||||||
|
exclude: [
|
||||||
|
"pg-hstore" // sequelize
|
||||||
|
]
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
...VitePluginNode({
|
...VitePluginNode({
|
||||||
// Nodejs native Request adapter
|
// Nodejs native Request adapter
|
||||||
|
Loading…
x
Reference in New Issue
Block a user