Put registration logic in methods
This commit is contained in:
parent
58bc1af969
commit
df9354d91f
2 changed files with 45 additions and 3 deletions
|
@ -4,11 +4,17 @@ const types = @import("../types.zig");
|
|||
|
||||
const Uuid = util.Uuid;
|
||||
const DateTime = util.DateTime;
|
||||
const RegistrationOptions = @import("../lib.zig").RegistrationOptions;
|
||||
const UserResponse = @import("../lib.zig").UserResponse;
|
||||
const Invite = @import("../lib.zig").Invite;
|
||||
pub const Token = types.Token;
|
||||
|
||||
pub const RegistrationOptions = struct {
|
||||
invite_code: ?[]const u8 = null,
|
||||
email: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
pub const AccountCreateOptions = @import("../services/accounts.zig").CreateOptions;
|
||||
|
||||
pub fn methods(comptime models: type) type {
|
||||
return struct {
|
||||
fn isInviteValid(invite: Invite) bool {
|
||||
|
@ -33,7 +39,7 @@ pub fn methods(comptime models: type) type {
|
|||
|
||||
if (self.context.community.kind == .admin) @panic("Unimplmented");
|
||||
|
||||
const user_id = try models.auth.register(
|
||||
const user_id = try createLocalAccount(
|
||||
tx,
|
||||
username,
|
||||
password,
|
||||
|
@ -63,6 +69,28 @@ pub fn methods(comptime models: type) type {
|
|||
return user;
|
||||
}
|
||||
|
||||
fn createLocalAccount(
|
||||
db: anytype,
|
||||
username: []const u8,
|
||||
password: []const u8,
|
||||
community_id: Uuid,
|
||||
opt: AccountCreateOptions,
|
||||
alloc: std.mem.Allocator,
|
||||
) !Uuid {
|
||||
const tx = try db.beginOrSavepoint();
|
||||
errdefer tx.rollback();
|
||||
|
||||
const hash = try hashPassword(password, alloc);
|
||||
defer alloc.free(hash);
|
||||
|
||||
const id = try models.actors.create(tx, username, community_id, false, alloc);
|
||||
try models.accounts.create(tx, id, hash, opt, alloc);
|
||||
|
||||
try tx.commitOrRelease();
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
pub fn login(self: anytype, username: []const u8, password: []const u8) !Token {
|
||||
const community_id = self.context.community.id;
|
||||
const credentials = try models.accounts.getCredentialsByUsername(
|
||||
|
@ -137,6 +165,20 @@ fn verifyPassword(
|
|||
};
|
||||
}
|
||||
|
||||
fn hashPassword(password: []const u8, alloc: std.mem.Allocator) ![]const u8 {
|
||||
const buf = try alloc.alloc(u8, password_hash_len);
|
||||
errdefer alloc.free(buf);
|
||||
return scrypt.strHash(
|
||||
password,
|
||||
.{
|
||||
.allocator = alloc,
|
||||
.params = scrypt.Params.interactive,
|
||||
.encoding = .phc,
|
||||
},
|
||||
buf,
|
||||
) catch error.HashFailure;
|
||||
}
|
||||
|
||||
/// A raw token is a sequence of N random bytes, base64 encoded.
|
||||
/// When the token is generated:
|
||||
/// - The hash of the token is calculated by:
|
||||
|
|
|
@ -169,7 +169,7 @@ const signup = struct {
|
|||
error.UsernameEmpty => "Username cannot be empty",
|
||||
error.UsernameContainsInvalidChar => "Username must be composed of alphanumeric characters and underscore",
|
||||
error.UsernameTooLong => "Username too long",
|
||||
error.PasswordTooShort => "Password too short, must be at least 12 chars",
|
||||
//error.PasswordTooShort => "Password too short, must be at least 12 chars",
|
||||
|
||||
error.UsernameTaken => blk: {
|
||||
status = .unprocessable_entity;
|
||||
|
|
Loading…
Reference in a new issue