Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions modules/authentication/src/Authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
GrpcRequest,
HealthCheckStatus,
Indexable,
Query,
} from '@conduitplatform/grpc-sdk';
import path from 'path';
import { isEmpty, isNil } from 'lodash-es';
Expand Down Expand Up @@ -788,10 +789,9 @@ export default class Authentication extends ManagedModule<Config> {

try {
const deletedToken = await Token.getInstance().deleteOne({
// @ts-expect-error Unsafe nested property access
'data.teamId': teamId,
'data.email': email,
});
} as Query<Token>);

if (deletedToken.deletedCount === 0) {
return callback({
Expand Down
10 changes: 4 additions & 6 deletions modules/authentication/src/handlers/metamask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ConduitRouteReturnDefinition,
GrpcError,
ParsedRouterRequest,
Query,
UnparsedRouterResponse,
} from '@conduitplatform/grpc-sdk';
import { User } from '../models/index.js';
Expand Down Expand Up @@ -80,9 +81,8 @@ export class MetamaskHandlers implements IAuthenticationStrategy {
const normalizedEthPublicAddress = ethPublicAddress.toLowerCase();

const existingUser: User | null = await User.getInstance().findOne({
// @ts-expect-error Unsafe nested property access
'metamask.ethPublicAddress': normalizedEthPublicAddress,
});
} as Query<User>);

if (existingUser) {
return { nonce: existingUser.metamask!.nonce };
Expand Down Expand Up @@ -110,9 +110,8 @@ export class MetamaskHandlers implements IAuthenticationStrategy {
}

const user = await User.getInstance().findOne({
// @ts-expect-error Unsafe nested property access
'metamask.ethPublicAddress': normalizedEthPublicAddress,
});
} as Query<User>);

if (isNil(user)) {
throw new GrpcError(
Expand Down Expand Up @@ -155,9 +154,8 @@ export class MetamaskHandlers implements IAuthenticationStrategy {
}

await User.getInstance().findByIdAndUpdate(user._id, {
// @ts-expect-error Unsafe nested property access
'metamask.nonce': uuid(),
});
} as Query<User>);

const config = ConfigController.getInstance().config;
return TokenProvider.getInstance().provideUserTokens({
Expand Down
22 changes: 8 additions & 14 deletions modules/authentication/src/handlers/team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,8 @@ export class TeamsHandler implements IAuthenticationStrategy {
async getUserInvites(call: ParsedRouterRequest): Promise<UnparsedRouterResponse> {
const invites = await Token.getInstance().findMany({
tokenType: TokenType.TEAM_INVITE_TOKEN,
// @ts-ignore
'data.email': call.request.context.user.email,
});
} as Query<Token>);
return {
invites: invites.map(invite => ({
teamId: invite.data.teamId,
Expand Down Expand Up @@ -597,10 +596,9 @@ export class TeamsHandler implements IAuthenticationStrategy {
// Delete any existing invite for the same email and team
await Token.getInstance().deleteOne({
tokenType: TokenType.TEAM_INVITE_TOKEN,
// @ts-expect-error Unsafe nested property access
'data.teamId': teamId,
'data.email': email,
});
} as Query<Token>);

const invitation = await this.createUserInvitation({
teamId,
Expand Down Expand Up @@ -663,10 +661,9 @@ export class TeamsHandler implements IAuthenticationStrategy {
// Delete any existing invite for the same email and team
await Token.getInstance().deleteOne({
tokenType: TokenType.TEAM_INVITE_TOKEN,
// @ts-expect-error Unsafe nested property access
'data.teamId': teamId,
'data.email': email,
});
} as Query<Token>);

return 'OK';
}
Expand Down Expand Up @@ -698,17 +695,14 @@ export class TeamsHandler implements IAuthenticationStrategy {
);
}

const invites = await Token.getInstance().findMany({
const teamInvitesQuery = {
tokenType: TokenType.TEAM_INVITE_TOKEN,
// @ts-expect-error Unsafe nested property access
'data.teamId': teamId,
});
} as Query<Token>;

const count = await Token.getInstance().countDocuments({
tokenType: TokenType.TEAM_INVITE_TOKEN,
// @ts-expect-error Unsafe nested property access
'data.teamId': teamId,
});
const invites = await Token.getInstance().findMany(teamInvitesQuery);

const count = await Token.getInstance().countDocuments(teamInvitesQuery);

return {
invites,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import { MandrillBuilder } from './mandrillBuilder.js';
import { getHandleBarsValues } from '../utils/index.js';
import { MandrillTemplate } from '../interfaces/mandrill/MandrillTemplate.js';

// @ts-expect-error — CJS package without bundled types
import mailchimpFactory from '@mailchimp/mailchimp_transactional';

// @ts-expect-error
// missing typings for nodemailer-mandrill-transport
import mandrillTransport from 'nodemailer-mandrill-transport';
import { Indexable } from '@conduitplatform/grpc-sdk';

Expand Down
23 changes: 23 additions & 0 deletions modules/communications/src/types/mailchimp-transactional.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
declare module '@mailchimp/mailchimp_transactional' {
interface MailchimpTransactional {
templates: {
list(body?: Record<string, unknown>): Promise<any>;
info(body: { name: string }): Promise<any>;
add(body: {
name: string;
subject?: string;
code?: string;
publish?: boolean;
}): Promise<any>;
update(body: { name: string; code?: string; subject?: string }): Promise<any>;
delete(body: { name: string }): Promise<any>;
};
messages: {
info(body: { id: string }): Promise<any>;
};
}

function mailchimpFactory(apiKey: string): MailchimpTransactional;

export default mailchimpFactory;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module 'nodemailer-mandrill-transport' {
function mandrillTransport(options: { auth: { apiKey: string } }): any;

export default mandrillTransport;
}
23 changes: 10 additions & 13 deletions modules/database/src/adapters/DatabaseAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -582,24 +582,21 @@ export abstract class DatabaseAdapter<T extends Schema> {
}

protected addSchemaPermissions(schema: ConduitSchema) {
const defaultPermissions = {
const defaultPermissions: NonNullable<
NonNullable<ConduitSchema['modelOptions']['conduit']>['permissions']
> = {
extendable: true,
canCreate: true,
canModify: 'Everything',
canDelete: true,
} as const;
};

if (isNil(schema.modelOptions.conduit)) schema.modelOptions.conduit = {};
if (isNil(schema.modelOptions.conduit.permissions)) {
schema.modelOptions.conduit!.permissions = defaultPermissions;
} else {
Object.keys(defaultPermissions).forEach(perm => {
if (!schema.modelOptions.conduit!.permissions!.hasOwnProperty(perm)) {
// @ts-ignore
schema.modelOptions.conduit!.permissions![perm] =
defaultPermissions[perm as keyof typeof defaultPermissions];
}
});
}

schema.modelOptions.conduit.permissions = {
...defaultPermissions,
...schema.modelOptions.conduit.permissions,
};
return schema;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ export function extractFieldProperties(
res.unique = objectField.unique ?? false;
res.allowNull = false;
} else if (objectField.hasOwnProperty('required') && objectField.required) {
// @ts-expect-error
res.allowNull = !objectField.required ?? true;
res.allowNull = !objectField.required;
}

return res;
Expand Down
32 changes: 19 additions & 13 deletions modules/database/src/utils/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@

import * as deepdash from 'deepdash-es/standalone';

type CrudOperationConfig = { enabled?: boolean; authenticated?: boolean };

type CrudOperations = {
create?: { enabled?: boolean; authenticated?: boolean };
read?: { enabled?: boolean; authenticated?: boolean };
update?: { enabled?: boolean; authenticated?: boolean };
delete?: { enabled?: boolean; authenticated?: boolean };
create?: CrudOperationConfig;
read?: CrudOperationConfig;
update?: CrudOperationConfig;
delete?: CrudOperationConfig;
};

interface Permissions {
Expand Down Expand Up @@ -78,57 +80,57 @@
let fieldsErrorFlag = false;
deepdash.eachDeep(
fields,
(value: any, key: string, parent: Indexable, ctx: Indexable) => {
if (fieldsErrorFlag) {
ctx.break();
return false;
}

if (isObject(value) && !value.hasOwnProperty('type')) return true;
else if (isString(value) && key !== 'default') {
fieldsErrorFlag = !Object.keys(TYPE).includes(value);
return false;
} else if (isPlainObject(value) && value.hasOwnProperty('type')) {
if (!fieldsErrorFlag && isObject(value.type)) {
return true;
} else if (!fieldsErrorFlag && isArray(value.type)) {
if (value.type.length > 1) fieldsErrorFlag = true;
if (!fieldsErrorFlag)
fieldsErrorFlag = !Object.values(TYPE).includes(value.type[0]);
return false;
} else fieldsErrorFlag = !Object.keys(TYPE).includes(value.type);
if (!fieldsErrorFlag && value.type === TYPE.Relation) {
if (value.hasOwnProperty('model')) {
if (!isString(value.model)) fieldsErrorFlag = true;
} else {
fieldsErrorFlag = true;
}
}
if (!fieldsErrorFlag && value.hasOwnProperty('select')) {
fieldsErrorFlag = !isBoolean(value.select);
}
if (!fieldsErrorFlag && value.hasOwnProperty('unique')) {
fieldsErrorFlag = !isBoolean(value.unique);
}
if (!fieldsErrorFlag && value.hasOwnProperty('required')) {
fieldsErrorFlag = !isBoolean(value.required);
}

return false;
} else if (isArray(value)) {
if (value.length > 1) fieldsErrorFlag = true;
if (!fieldsErrorFlag) fieldsErrorFlag = !Object.values(TYPE).includes(value[0]);
return false;
} else if (key === 'select' || key === 'required' || key === 'unique') {
fieldsErrorFlag = !isBoolean(value);
} else if (key === 'default') {
fieldsErrorFlag = !isString(value);
} else if (key === 'type') return true;
else {
fieldsErrorFlag = true;
return false;
}
},

Check notice on line 133 in modules/database/src/utils/utilities.ts

View check run for this annotation

codefactor.io / CodeFactor

modules/database/src/utils/utilities.ts#L83-L133

Complex Method
);
if (fieldsErrorFlag) throw new Error('Invalid schema fields configuration');
}
Expand Down Expand Up @@ -221,23 +223,27 @@
if (!isObject(crudOperations))
throw new Error(`CMS field 'crudOperations' must be of type Object`);

Object.keys(crudOperations).forEach(op => {
if (!allowedCrudOperations.includes(op as keyof CrudOperations)) {
(Object.keys(crudOperations) as Array<keyof CrudOperations>).forEach(op => {
if (!allowedCrudOperations.includes(op)) {
throw new Error(`Unrecognized CRUD operation '${op}' provided`);
}
// @ts-ignore
if (!isObject(crudOperations[op])) {

const operationConfig = crudOperations[op];

if (!isObject(operationConfig)) {
throw new Error(`Crud operation field '${op}' must be of type Object`);
}
// @ts-ignore
Object.keys(crudOperations[op]).forEach(opField => {
if (!['enabled', 'authenticated'].includes(opField)) {

const config = operationConfig as CrudOperationConfig;

Object.keys(config).forEach(opField => {
if (opField !== 'enabled' && opField !== 'authenticated') {
throw new Error(
`Unrecognized crud operation field '${opField}' for operation '${op}' provided`,
);
}
// @ts-ignore
if (!isBoolean(crudOperations[op][opField])) {

if (!isBoolean(config[opField])) {
throw new Error(
`Crud operation field '${opField}' for operation '${op}' must be of type Boolean`,
);
Expand Down
Loading