Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
f9ed5e1
deleted document manager test
ben-shepherd Dec 15, 2024
2220008
added where with objects, sql uses ILIKE
ben-shepherd Dec 15, 2024
2c4614d
Use eloquent queries in model crud actions
ben-shepherd Dec 15, 2024
f9a7c7a
resource all uses eloquent
ben-shepherd Dec 15, 2024
ce25fe5
short hand for request context
ben-shepherd Dec 15, 2024
abf3623
resource show to use eloquent
ben-shepherd Dec 15, 2024
4da531c
route resource comment
ben-shepherd Dec 15, 2024
0367c5f
fix double model creation in repository find one
ben-shepherd Dec 15, 2024
3e802a2
fix resource all filters
ben-shepherd Dec 15, 2024
cc72e34
remove useless assertion
ben-shepherd Dec 15, 2024
029ae64
improvement to resource all, query filters
ben-shepherd Dec 15, 2024
8629e60
deleted dbPartialSearch test, updated dbService test
ben-shepherd Dec 15, 2024
3fd9c7f
EloquentBuilderService initial structure for connection name (not fun…
ben-shepherd Dec 15, 2024
217bdd6
resource all use request context short hand
ben-shepherd Dec 15, 2024
8ef1ea6
dbSchema test fix
ben-shepherd Dec 15, 2024
b8f9e35
eloquent hasMany + test, remove tokens relationship from User
ben-shepherd Dec 15, 2024
3002751
deleted old model relationship tests
ben-shepherd Dec 15, 2024
47fc7a6
model declare broadcast methods
ben-shepherd Dec 15, 2024
a43e973
remove boot from logger provider
ben-shepherd Dec 15, 2024
2dbccf4
minor changes to model observer (still broken)
ben-shepherd Dec 15, 2024
2cca369
kernel warning fix
ben-shepherd Dec 15, 2024
1164023
model crud, dirty tests clean up
ben-shepherd Dec 16, 2024
0e67898
deprecated BaseSchema formatTableName
ben-shepherd Dec 16, 2024
39eafd2
fix seeder test
ben-shepherd Dec 16, 2024
8a077bb
clean up migraiton provider, remove useless function in provider
ben-shepherd Dec 16, 2024
98e40ab
Added prepareDocuments to db adapters
ben-shepherd Dec 16, 2024
86db73a
Bindings ignore undefined
ben-shepherd Dec 16, 2024
b289a5c
where sql does not transform array of bindings
ben-shepherd Dec 16, 2024
d0b77cc
Format table in Sql expression
ben-shepherd Dec 16, 2024
7f1aa0d
Check type before preparing document
ben-shepherd Dec 16, 2024
c8f2532
fix this.schema undefiend in MongoDbAdapter, wrong function name in M…
ben-shepherd Dec 16, 2024
d0ec269
initialize sequelize in connect default
ben-shepherd Dec 16, 2024
cf145be
table as property in worker models, updated create worker tables
ben-shepherd Dec 16, 2024
c752b62
format table in DeleteFrom
ben-shepherd Dec 16, 2024
50e97c7
safer getPayload object checks in WorkerModel
ben-shepherd Dec 16, 2024
1e520fe
short hand for accessing events
ben-shepherd Dec 16, 2024
76faa21
eventQueableSuccess changes
ben-shepherd Dec 16, 2024
e290fb0
fixes to event tests
ben-shepherd Dec 16, 2024
639eb12
short hand for console, comments
ben-shepherd Dec 16, 2024
f24c66e
removed legacy belongs to, has many relations + fix
ben-shepherd Dec 16, 2024
256382b
fix dbService test
ben-shepherd Dec 16, 2024
a5bc269
dbCreateDropDatabase fix, deleted postgres client connection test
ben-shepherd Dec 17, 2024
0e4a176
added close command to database adapters
ben-shepherd Dec 17, 2024
a73b6ab
improved yarn fix (changed order to fix imports then eslint)
ben-shepherd Dec 17, 2024
0b77e55
endTests fix
ben-shepherd Dec 17, 2024
63080b3
auth test fixes
ben-shepherd Dec 17, 2024
b8628e4
remove document manager references, deleted legacy belongs to file
ben-shepherd Dec 17, 2024
32fcb27
fixed issue in AuthRequest
ben-shepherd Dec 17, 2024
4717716
yarn fix
ben-shepherd Dec 17, 2024
5634a2b
removed deprecated formatTableName from BaseSchema
ben-shepherd Dec 17, 2024
53148c9
remove formatTableName references
ben-shepherd Dec 17, 2024
0363a35
specify connection to adapter when preparing documents in Model
ben-shepherd Dec 17, 2024
bc15005
commented back in lines in authLoginUser test
ben-shepherd Dec 17, 2024
0eeee8f
removed legacy method
ben-shepherd Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"build": "webpack --color",
"fix-imports": "node fix-imports.js",
"fix-eslint": "npx eslint --fix src",
"fix": "yarn run fix-eslint && yarn run fix-imports",
"fix": "yarn run fix-imports && yarn run fix-eslint",
"start": "node ./dist/app.js",
"dev": "nodemon --watch src --ext ts --exec ts-node -r tsconfig-paths/register ./src/app.ts",
"dev:tinker": "nodemon --watch src --ext ts --exec ts-node -r tsconfig-paths/register ./src/tinker.ts",
Expand Down
28 changes: 17 additions & 11 deletions src/app/models/auth/ApiToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import ApiTokenObserver from '@src/app/observers/ApiTokenObserver';
import IApiTokenModel, { IApiTokenData } from '@src/core/domains/auth/interfaces/IApitokenModel';
import IUserModel from '@src/core/domains/auth/interfaces/IUserModel';
import Scopes from '@src/core/domains/auth/services/Scopes';
import { ICtor } from '@src/core/interfaces/ICtor';
import BelongsTo from '@src/core/domains/eloquent/relational/BelongsTo';
import { ModelConstructor } from '@src/core/interfaces/IModel';
import Model from '@src/core/models/base/Model';

/**
Expand All @@ -16,7 +17,7 @@ class ApiToken extends Model<IApiTokenData> implements IApiTokenModel {
/**
* The user model constructor
*/
protected userModelCtor: ICtor<IUserModel> = User
protected userModelCtor: ModelConstructor<IUserModel> = User

/**
* Required ApiToken fields
Expand All @@ -36,6 +37,10 @@ class ApiToken extends Model<IApiTokenData> implements IApiTokenModel {
'scopes'
]

public relationships: string[] = [
'user'
]

public timestamps: boolean = false;

/**
Expand All @@ -52,30 +57,31 @@ class ApiToken extends Model<IApiTokenData> implements IApiTokenModel {

/**
* Sets the user model constructor to use for fetching the user of this ApiToken
* @param {ICtor<IUserModel>} userModelCtor The user model constructor
* @param {ModelConstructor<IUserModel>} userModelCtor The user model constructor
*/
setUserModelCtor(userModelCtor: ICtor<IUserModel>): void {
setUserModelCtor(userModelCtor: ModelConstructor<IUserModel>): void {
this.userModelCtor = userModelCtor
}

/**
* Retrieves the constructor for the user model associated with this ApiToken.
* @returns {ICtor<IUserModel>} The user model constructor.
* @returns {ModelConstructor<IUserModel>} The user model constructor.
*/
getUserModelCtor(): ICtor<IUserModel> {
getUserModelCtor(): ModelConstructor<IUserModel> {
return this.userModelCtor
}

/**
* Finds the related user for this ApiToken
* @returns The user model if found, or null if not
* Fetches the user that this ApiToken belongs to.
*
* @returns A BelongsTo relationship that resolves to the user model.
*/
async user(): Promise<IUserModel | null> {
return this.belongsToLegacy(this.userModelCtor, {
user(): BelongsTo {
return this.belongsTo(this.userModelCtor, {
localKey: 'userId',
foreignKey: 'id',
})
}
}

/**
* Checks if the given scope(s) are present in the scopes of this ApiToken
Expand Down
16 changes: 0 additions & 16 deletions src/app/models/auth/User.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import ApiToken from "@src/app/models/auth/ApiToken";
import UserObserver from "@src/app/observers/UserObserver";
import IUserModel from "@src/core/domains/auth/interfaces/IUserModel";
import IModelAttributes from "@src/core/interfaces/IModelData";
Expand Down Expand Up @@ -121,19 +120,4 @@ export default class User extends Model<IUserData> implements IUserModel {
return true;
}

/**
* @returns The tokens associated with this user
*
* Retrieves the ApiToken models associated with this user.
*/
async tokens(active: boolean = true): Promise<ApiToken[]> {
const filters = active ? { revokedAt: null } : {};

return this.hasMany(ApiToken, {
localKey: 'id',
foreignKey: 'userId',
filters
})
}

}
2 changes: 1 addition & 1 deletion src/core/Kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type KernelOptions = {

export default class Kernel<Config extends IAppConfig> extends Singleton<Config> {

private appConfig!: IAppConfig;
private readonly appConfig!: IAppConfig;

public containers: Map<keyof Containers, Containers[keyof Containers]> = new Map();

Expand Down
27 changes: 13 additions & 14 deletions src/core/base/BaseModel.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
/* eslint-disable no-unused-vars */

import HasObserverConcern from '@src/core/concerns/HasObserverConcern';
import HasPrepareDocumentConcern from '@src/core/concerns/HasPrepareDocumentConcern';
import Broadcaster from '@src/core/domains/broadcast/abstract/Broadcaster';
import compose from '@src/core/util/compose';
import { ObserveConstructor } from '@src/core/domains/observer/interfaces/IHasObserver';
import { IObserver } from '@src/core/domains/observer/interfaces/IObserver';
import IModelAttributes from '@src/core/interfaces/IModelData';

class BaseModel<Attributes extends IModelAttributes = IModelAttributes> extends compose(
class extends Broadcaster {},
HasPrepareDocumentConcern,
HasObserverConcern
) {
import compose from '@src/core/util/compose';
import { IBroadcastEvent } from '@src/core/domains/broadcast/interfaces/IBroadcastEvent';
import { BroadcastCallback } from '@src/core/domains/broadcast/interfaces/IBroadcaster';

class BaseModel extends compose(class extends Broadcaster {}, HasObserverConcern) {

/**
* Declare HasPrepareDocument concern
*/
declare json: string[];

declare prepareDocument: <T>() => T;
* Declare HasBroadcaster concern
*/
declare broadcast: (event: IBroadcastEvent) => Promise<void>;

declare createBroadcastListener: (eventName: string) => void;

declare subscribeToBroadcastListener: (id: string, eventName: string, callback: BroadcastCallback) => void;

declare unsubscribeFromBroadcastListener: (id: string, eventName: string) => void;


/**
Expand Down
2 changes: 1 addition & 1 deletion src/core/base/Factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default abstract class Factory<Model extends IModel = IModel> implements
* @returns A new instance of the model.
*/
createWithData<Data extends IModelAttributes = IModelAttributes>(data: Data | null = null): Model {
return new this.modelCtor(data)
return this.modelCtor.create(data);
}

}
9 changes: 0 additions & 9 deletions src/core/base/Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,4 @@ export default abstract class BaseProvider implements IProvider {
App.container('logger').info(message, ...args);
}

/**
* Gets the name of the provider
*
* @returns {string|null} - The name of the provider, or null if not set
*/
public getProviderName(): string | null {
return this.providerName;
}

}
7 changes: 3 additions & 4 deletions src/core/base/Repository.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { IEloquent } from "@src/core/domains/eloquent/interfaces/IEloquent";
import { queryBuilder } from "@src/core/domains/eloquent/services/EloquentQueryBuilderService";
import ModelNotFound from "@src/core/exceptions/ModelNotFound";
import { IModel, ModelConstructor } from "@src/core/interfaces/IModel";
import { IRepository } from "@src/core/interfaces/IRepository";
import { IEloquent } from "@src/core/domains/eloquent/interfaces/IEloquent";
import { queryBuilder } from "@src/core/domains/eloquent/services/EloquentQueryBuilderService";

/**
* Base class for repositories
Expand Down Expand Up @@ -88,8 +88,7 @@ export default class Repository<Model extends IModel> implements IRepository<Mod
builder.where(key, filter[key]);
})

const data = await builder.first();
return data ? this.modelConstructor.create(data) : null;
return await builder.first();
}

/**
Expand Down
43 changes: 0 additions & 43 deletions src/core/concerns/HasPrepareDocumentConcern.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/core/domains/auth/factory/apiTokenFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class ApiTokenFactory extends Factory<IApiTokenModel> implements IApiTokenFactor
*/
createFromUser(user: IUserModel, scopes: string[] = []): IApiTokenModel {
return this.createWithData({
userId: user.attributes?.id,
userId: user?.id,
token: tokenFactory(),
scopes: scopes,
revokedAt: null,
Expand Down
4 changes: 3 additions & 1 deletion src/core/domains/auth/interfaces/IApitokenModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ import IUserModel from "@src/core/domains/auth/interfaces/IUserModel";
import { ICtor } from "@src/core/interfaces/ICtor";
import { IModel } from "@src/core/interfaces/IModel";
import IModelAttributes from "@src/core/interfaces/IModelData";
import BelongsTo from "@src/core/domains/eloquent/relational/BelongsTo";

export interface IApiTokenData extends IModelAttributes {
userId: string;
token: string;
scopes: string[];
revokedAt: Date | null;
user: IUserModel | null;
}

export default interface IApiTokenModel extends IModel<IApiTokenData> {
setUserModelCtor(userModelCtor: ICtor<IUserModel>): void;
getUserModelCtor(): ICtor<IUserModel>;
user(): Promise<IUserModel | null>;
user(): BelongsTo;
hasScope(scopes: string | string[], exactMatch?: boolean): boolean;
}
1 change: 0 additions & 1 deletion src/core/domains/auth/interfaces/IUserModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { IUserData } from "@src/app/models/auth/User";
import { IModel } from "@src/core/interfaces/IModel";

export default interface IUserModel extends IModel<IUserData> {
tokens(...args: any[]): Promise<any>;
hasRole(...args: any[]): any;
hasGroup(...args: any[]): any;
}
6 changes: 4 additions & 2 deletions src/core/domains/auth/services/AuthRequest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import UnauthorizedError from "@src/core/domains/auth/exceptions/UnauthorizedError";
import IUserModel from "@src/core/domains/auth/interfaces/IUserModel";
import { auth } from "@src/core/domains/auth/services/AuthService";
import { BaseRequest } from "@src/core/domains/express/types/BaseRequest.t";
import { App } from "@src/core/services/App";

Expand All @@ -16,9 +18,9 @@ class AuthRequest {
public static async attemptAuthorizeRequest(req: BaseRequest): Promise<BaseRequest> {
const authorization = (req.headers.authorization ?? '').replace('Bearer ', '');

const apiToken = await App.container('auth').attemptAuthenticateToken(authorization)
const apiToken = await auth().attemptAuthenticateToken(authorization)

const user = await apiToken?.user()
const user = await apiToken?.getAttribute('user') as IUserModel | null;

if(!user || !apiToken) {
throw new UnauthorizedError();
Expand Down
25 changes: 16 additions & 9 deletions src/core/domains/auth/services/AuthService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import decodeJwt from '@src/core/domains/auth/utils/decodeJwt';
import { IRoute } from '@src/core/domains/express/interfaces/IRoute';
import { app } from '@src/core/services/App';
import { JsonWebTokenError } from 'jsonwebtoken';
import { queryBuilder } from '@src/core/domains/eloquent/services/EloquentQueryBuilderService';

/**
* Shorthand for accessing the auth service
Expand Down Expand Up @@ -90,11 +91,14 @@ export default class AuthService extends Service<IAuthConfig> implements IAuthSe
* @returns
*/
jwt(apiToken: IApiTokenModel): string {
if (!apiToken?.attributes?.userId) {
if (!apiToken?.userId) {
throw new Error('Invalid token');
}

const payload = JWTTokenFactory.create(apiToken.attributes?.userId?.toString(), apiToken.attributes?.token);
const userId = apiToken.getAttributeSync('userId')?.toString() ?? '';
const token = apiToken.getAttributeSync('token') ?? '';

const payload = JWTTokenFactory.create(userId, token);
return createJwt(this.config.jwtSecret, payload, `${this.config.expiresInMinutes}m`);
}

Expand All @@ -104,12 +108,13 @@ export default class AuthService extends Service<IAuthConfig> implements IAuthSe
* @returns
*/
async revokeToken(apiToken: IApiTokenModel): Promise<void> {
if (apiToken?.attributes?.revokedAt) {
if (apiToken?.revokedAt) {
return;
}

apiToken.setAttribute('revokedAt', new Date());
await apiToken.save();
await queryBuilder(this.apiTokenRepository.modelConstructor)
.where('userId', apiToken.userId as string)
.update({ revokedAt: new Date() });
}

/**
Expand Down Expand Up @@ -151,17 +156,19 @@ export default class AuthService extends Service<IAuthConfig> implements IAuthSe
* @returns
*/
async attemptCredentials(email: string, password: string, scopes: string[] = []): Promise<string> {
const user = await this.userRepository.findOneByEmail(email) as IUserModel;
const user = await this.userRepository.findOneByEmail(email);

if (!user?.attributes?.id) {
if (!user) {
throw new UnauthorizedError()
}

if (user?.attributes?.hashedPassword && !comparePassword(password, user.attributes?.hashedPassword)) {
const hashedPassword = user.getAttributeSync('hashedPassword')

if (hashedPassword && !comparePassword(password, hashedPassword)) {
throw new UnauthorizedError()
}

return this.createJwtFromUser(user, scopes)
return await this.createJwtFromUser(user, scopes)
}

/**
Expand Down
12 changes: 8 additions & 4 deletions src/core/domains/console/service/CommandReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import { App } from "@src/core/services/App";

export default class CommandReader implements ICommandReader {

private argv: string[] = [];

/**
* Command signature
*
* Example:
* my:command --id=123 --name="My Name"
["--id=123", "--name=\"My Name\""]
*/
private readonly argv: string[] = [];

/**
* Command signature
*
* @param argv
* Example:
["my:command", "--id=123", "--name=\"My Name\""]
*/
constructor(argv: string[]) {
this.argv = argv;
Expand Down
Loading