Skip to content

Commit

Permalink
feat(authentication,config): remove Authentication's dependency on Em…
Browse files Browse the repository at this point in the history
…ail for unverified local email auth strategies (#103)
  • Loading branch information
kon14 committed Apr 4, 2022
1 parent 9b88a52 commit 9574848
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 121 deletions.
37 changes: 24 additions & 13 deletions modules/authentication/src/Authentication.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import {
ManagedModule,
ConfigController,
DatabaseProvider
} from "@conduitplatform/grpc-sdk";
DatabaseProvider,
} from '@conduitplatform/grpc-sdk';

import path from "path";
import { isNil } from "lodash";
import { status } from "@grpc/grpc-js";
import path from 'path';
import { isNil } from 'lodash';
import { status } from '@grpc/grpc-js';
import AppConfigSchema from './config';
import { AdminHandlers } from './admin/admin';
import { AuthenticationRoutes } from './routes/routes';
import * as models from './models';
import { ISignTokenOptions } from "./interfaces/ISignTokenOptions";
import { AuthUtils } from "./utils/auth";
import { TokenType } from "./constants/TokenType";
import { v4 as uuid } from "uuid";
import moment from "moment";
import { ISignTokenOptions } from './interfaces/ISignTokenOptions';
import { AuthUtils } from './utils/auth';
import { TokenType } from './constants/TokenType';
import { v4 as uuid } from 'uuid';
import moment from 'moment';
import { migrateLocalAuthConfig } from './migrations/localAuthConfig.migration';

export default class Authentication extends ManagedModule {
config = AppConfigSchema;
Expand All @@ -42,6 +43,7 @@ export default class Authentication extends ManagedModule {
async onServerStart() {
await this.grpcSdk.waitForExistence('database');
this.database = this.grpcSdk.databaseProvider!;
await migrateLocalAuthConfig(this.grpcSdk);
}

async onRegister() {
Expand Down Expand Up @@ -120,7 +122,16 @@ export default class Authentication extends ManagedModule {
async userCreate(call: any, callback: any) {
const email = call.request.email;
let password = call.request.password;
let verify = call.request.verify;
const verify = call.request.verify;

const verificationConfig = ConfigController.getInstance().config.local.verification;
if (verify && !(verificationConfig.required && verificationConfig.send_email)) {
return callback({
code: status.INVALID_ARGUMENT,
message: 'Email verification is disabled. Configuration required.',
});
}

if (isNil(password) || password.length === 0) {
password = AuthUtils.randomToken(8);
}
Expand All @@ -129,10 +140,10 @@ export default class Authentication extends ManagedModule {
if (user) {
return callback({ code: status.ALREADY_EXISTS, message: 'User already exists' });
}
if (email.indexOf('+') !== -1) {
if (AuthUtils.invalidEmailAddress(email)) {
return callback({
code: status.INVALID_ARGUMENT,
message: 'Email contains unsupported characters',
message: 'Invalid email address provided',
});
}
const hashedPassword = await AuthUtils.hashPassword(password);
Expand Down
24 changes: 8 additions & 16 deletions modules/authentication/src/admin/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import ConduitGrpcSdk, {
ConduitNumber,
ConduitBoolean,
TYPE,
ConfigController,
} from '@conduitplatform/grpc-sdk';
import { status} from '@grpc/grpc-js';
import { isNil } from 'lodash';
Expand Down Expand Up @@ -79,7 +78,7 @@ export class AdminHandlers {
path: '/users',
action: ConduitRouteActions.POST,
bodyParams: {
identification: ConduitString.Required,
email: ConduitString.Required,
password: ConduitString.Required,
},
},
Expand Down Expand Up @@ -241,14 +240,13 @@ export class AdminHandlers {
query[provider] = { $exists: true, $ne: null };
}
}
let identifier;
if (!isNil(search)) {
if (search.match(/^[a-fA-F0-9]{24}$/)) {
query = { _id : search }
}
else {
identifier = escapeStringRegexp(search);
query['email'] = { $regex: `.*${identifier}.*`, $options: 'i' };
const emailIdentifier = escapeStringRegexp(search);
query['email'] = { $regex: `.*${emailIdentifier}.*`, $options: 'i' };
}
}

Expand All @@ -265,27 +263,21 @@ export class AdminHandlers {
}

async createUser(call: ParsedRouterRequest): Promise<UnparsedRouterResponse> {
let { identification, password } = call.request.params;

const config = ConfigController.getInstance().config;
if (config.local.identifier === 'email') {
if (identification.indexOf('+') !== -1) {
throw new GrpcError(status.INVALID_ARGUMENT, 'Email contains unsupported characters');
}

identification = identification.toLowerCase();
let { email, password } = call.request.params;
if (AuthUtils.invalidEmailAddress(email)) {
throw new GrpcError(status.INVALID_ARGUMENT, 'Invalid email address provided');
}

let user: User | null = await User.getInstance().findOne({
email: identification,
email: email.toLowerCase(),
});
if (!isNil(user)) {
throw new GrpcError(status.ALREADY_EXISTS, 'User already exists');
}

let hashedPassword = await AuthUtils.hashPassword(password);
user = await User.getInstance().create({
email: identification,
email,
hashedPassword,
isVerified: true,
});
Expand Down
35 changes: 15 additions & 20 deletions modules/authentication/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,26 @@ export default {
default: true,
},
local: {
identifier: {
doc:
'The field name to use for id for a user logging in with local strategy ex. email/username',
format: 'String',
default: 'email',
},
enabled: {
doc: 'Defines if this strategy is active or not',
format: 'Boolean',
default: true,
},
sendVerificationEmail: {
doc:
'Defines if the authenticator should automatically send a verification e-mail to the user',
format: 'Boolean',
default: true,
},
verificationRequired: {
doc: 'Defines if email verification is required for login',
format: 'Boolean',
default: true,
},
verification_redirect_uri: {
format: 'String',
default: '',
verification: {
required: {
doc: 'Defines if email verification is required for login',
format: 'Boolean',
default: false,
},
send_email: {
doc: 'Defines if the authenticator should automatically send a verification e-mail to the user',
format: 'Boolean',
default: false,
},
redirect_uri: {
format: 'String',
default: '',
},
},
forgot_password_redirect_uri: {
format: 'String',
Expand Down
9 changes: 2 additions & 7 deletions modules/authentication/src/handlers/facebook/facebook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,16 @@ export class FacebookHandlers extends OAuth2<Payload, FacebookSettings> {
user_age_range: 'age_range',
user_likes: 'likes',
};
this.defaultScopes = ["public_profile","email"];

this.defaultScopes = ['public_profile', 'email'];
}

async makeFields(scopes: string[]): Promise<string> {

let mappedScopes = scopes.map((scope: any) => {
return scopes.map((scope: any) => {
return this.mapScopes[scope];
}).join(',');

return mappedScopes;
}

async constructScopes(scopes: string[]): Promise<string> {

return scopes.join(',');
}

Expand Down

0 comments on commit 9574848

Please sign in to comment.