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 UserNameComponent from "./models/UserNameComponent";
|
||||
import {UnknownRelationValidationError} from "../db/Validator";
|
||||
import AuthMethod from "./AuthMethod";
|
||||
import AuthProof from "./AuthProof";
|
||||
|
||||
export default class AuthController extends Controller {
|
||||
public getRoutesPrefix(): string {
|
||||
@ -83,8 +85,23 @@ export default class AuthController extends Controller {
|
||||
// Redirect to registration if user not found
|
||||
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
|
||||
const {user, method} = methods[0];
|
||||
return await method.attemptLogin(req, res, user);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,14 @@ export default interface AuthMethod<P extends AuthProof<User>> {
|
||||
*/
|
||||
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>;
|
||||
|
||||
getProofsForSession?(session: Express.Session): Promise<P[]>;
|
||||
|
@ -11,7 +11,7 @@ import RedirectBackComponent from "../../components/RedirectBackComponent";
|
||||
import Application from "../../Application";
|
||||
import {MailTemplate} from "../../mail/Mail";
|
||||
import AuthMagicLinkActionType from "./AuthMagicLinkActionType";
|
||||
import Validator from "../../db/Validator";
|
||||
import Validator, {EMAIL_REGEX} from "../../db/Validator";
|
||||
import ModelFactory from "../../db/ModelFactory";
|
||||
import UserNameComponent from "../models/UserNameComponent";
|
||||
|
||||
@ -26,6 +26,12 @@ export default class MagicLinkAuthMethod implements AuthMethod<MagicLink> {
|
||||
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> {
|
||||
return (await UserEmail.select()
|
||||
.with('user.mainEmail')
|
||||
|
@ -24,6 +24,12 @@ export default class PasswordAuthMethod implements AuthMethod<PasswordAuthProof>
|
||||
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> {
|
||||
const query = UserEmail.select()
|
||||
.with('user')
|
||||
|
Loading…
Reference in New Issue
Block a user