AuthMethod: add weight to choose when no method was specified
This commit is contained in:
parent
a5ee9922ec
commit
70d80d1f0a
@ -7,6 +7,8 @@ import User from "./models/User";
|
|||||||
import UserPasswordComponent from "./password/UserPasswordComponent";
|
import UserPasswordComponent from "./password/UserPasswordComponent";
|
||||||
import UserNameComponent from "./models/UserNameComponent";
|
import UserNameComponent from "./models/UserNameComponent";
|
||||||
import {UnknownRelationValidationError} from "../db/Validator";
|
import {UnknownRelationValidationError} from "../db/Validator";
|
||||||
|
import AuthMethod from "./AuthMethod";
|
||||||
|
import AuthProof from "./AuthProof";
|
||||||
|
|
||||||
export default class AuthController extends Controller {
|
export default class AuthController extends Controller {
|
||||||
public getRoutesPrefix(): string {
|
public getRoutesPrefix(): string {
|
||||||
@ -83,8 +85,23 @@ export default class AuthController extends Controller {
|
|||||||
// Redirect to registration if user not found
|
// Redirect to registration if user not found
|
||||||
if (methods.length === 0) return await this.redirectToRegistration(req, res, identifier);
|
if (methods.length === 0) return await this.redirectToRegistration(req, res, identifier);
|
||||||
|
|
||||||
|
// Choose best matching method
|
||||||
|
let user: User | null = null;
|
||||||
|
let method: AuthMethod<AuthProof<User>> | null = null;
|
||||||
|
let weight = -1;
|
||||||
|
|
||||||
|
for (const entry of methods) {
|
||||||
|
const methodWeight = entry.method.getWeightForRequest(req);
|
||||||
|
if (methodWeight > weight) {
|
||||||
|
user = entry.user;
|
||||||
|
method = entry.method;
|
||||||
|
weight = methodWeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!method || !user) ({method, user} = methods[0]); // Default to first method
|
||||||
|
|
||||||
// Login
|
// Login
|
||||||
const {user, method} = methods[0];
|
|
||||||
return await method.attemptLogin(req, res, user);
|
return await method.attemptLogin(req, res, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,14 @@ export default interface AuthMethod<P extends AuthProof<User>> {
|
|||||||
*/
|
*/
|
||||||
getName(): string;
|
getName(): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for automatic auth method detection. Won't affect forced auth method.
|
||||||
|
*
|
||||||
|
* @return {@code 0} if the request is not conform to this auth method, otherwise the exact count of matching
|
||||||
|
* fields.
|
||||||
|
*/
|
||||||
|
getWeightForRequest(req: Request): number;
|
||||||
|
|
||||||
findUserByIdentifier(identifier: string): Promise<User | null>;
|
findUserByIdentifier(identifier: string): Promise<User | null>;
|
||||||
|
|
||||||
getProofsForSession?(session: Express.Session): Promise<P[]>;
|
getProofsForSession?(session: Express.Session): Promise<P[]>;
|
||||||
|
@ -11,7 +11,7 @@ import RedirectBackComponent from "../../components/RedirectBackComponent";
|
|||||||
import Application from "../../Application";
|
import Application from "../../Application";
|
||||||
import {MailTemplate} from "../../mail/Mail";
|
import {MailTemplate} from "../../mail/Mail";
|
||||||
import AuthMagicLinkActionType from "./AuthMagicLinkActionType";
|
import AuthMagicLinkActionType from "./AuthMagicLinkActionType";
|
||||||
import Validator from "../../db/Validator";
|
import Validator, {EMAIL_REGEX} from "../../db/Validator";
|
||||||
import ModelFactory from "../../db/ModelFactory";
|
import ModelFactory from "../../db/ModelFactory";
|
||||||
import UserNameComponent from "../models/UserNameComponent";
|
import UserNameComponent from "../models/UserNameComponent";
|
||||||
|
|
||||||
@ -26,6 +26,12 @@ export default class MagicLinkAuthMethod implements AuthMethod<MagicLink> {
|
|||||||
return 'magic_link';
|
return 'magic_link';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getWeightForRequest(req: Request): number {
|
||||||
|
return !req.body.identifier || !EMAIL_REGEX.test(req.body.identifier) ?
|
||||||
|
0 :
|
||||||
|
1;
|
||||||
|
}
|
||||||
|
|
||||||
public async findUserByIdentifier(identifier: string): Promise<User | null> {
|
public async findUserByIdentifier(identifier: string): Promise<User | null> {
|
||||||
return (await UserEmail.select()
|
return (await UserEmail.select()
|
||||||
.with('user.mainEmail')
|
.with('user.mainEmail')
|
||||||
|
@ -24,6 +24,12 @@ export default class PasswordAuthMethod implements AuthMethod<PasswordAuthProof>
|
|||||||
return 'password';
|
return 'password';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getWeightForRequest(req: Request): number {
|
||||||
|
return !req.body.identifier || !req.body.password || req.body.password.length === 0 ?
|
||||||
|
0 :
|
||||||
|
2;
|
||||||
|
}
|
||||||
|
|
||||||
public async findUserByIdentifier(identifier: string): Promise<User | null> {
|
public async findUserByIdentifier(identifier: string): Promise<User | null> {
|
||||||
const query = UserEmail.select()
|
const query = UserEmail.select()
|
||||||
.with('user')
|
.with('user')
|
||||||
|
Loading…
Reference in New Issue
Block a user