Skip to content

Commit 0305a71

Browse files
authored
feat: add support for magic link login (#65)
* feat: add support for magic link login * update readme
1 parent 4269e22 commit 0305a71

File tree

12 files changed

+316
-4
lines changed

12 files changed

+316
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
- ✅ Forgot password flow using email
3131
- ✅ Social logins (Google, Github, Facebook, more coming soon)
3232
- ✅ Role-based access management
33+
- ✅ Password-less login with email and magic link
3334

3435
## Project Status
3536

3637
⚠️ **Authorizer is still an early beta! missing features and bugs are to be expected!** If you can stomach it, then bring authentication and authorization to your site today!
3738

3839
## Roadmap
3940

40-
- Password-less login with email and magic link
4141
- Support more JWT encryption algorithms (Currently supporting HS256)
4242
- 2 Factor authentication
4343
- Back office (Admin dashboard to manage user)

server/constants/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var (
2121
RESET_PASSWORD_URL = ""
2222
DISABLE_EMAIL_VERIFICATION = "false"
2323
DISABLE_BASIC_AUTHENTICATION = "false"
24+
DISABLE_MAGIC_LOGIN = "false"
2425

2526
// ROLES
2627
ROLES = []string{}

server/env.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ func InitEnv() {
6464
constants.RESET_PASSWORD_URL = strings.TrimPrefix(os.Getenv("RESET_PASSWORD_URL"), "/")
6565
constants.DISABLE_BASIC_AUTHENTICATION = os.Getenv("DISABLE_BASIC_AUTHENTICATION")
6666
constants.DISABLE_EMAIL_VERIFICATION = os.Getenv("DISABLE_EMAIL_VERIFICATION")
67+
constants.DISABLE_MAGIC_LOGIN = os.Getenv("DISABLE_MAGIC_LOGIN")
6768
constants.JWT_ROLE_CLAIM = os.Getenv("JWT_ROLE_CLAIM")
6869

6970
if constants.ADMIN_SECRET == "" {
@@ -126,6 +127,10 @@ func InitEnv() {
126127
constants.DISABLE_BASIC_AUTHENTICATION = "false"
127128
}
128129

130+
if constants.DISABLE_MAGIC_LOGIN == "" {
131+
constants.DISABLE_MAGIC_LOGIN = "false"
132+
}
133+
129134
if constants.DISABLE_EMAIL_VERIFICATION == "" && constants.DISABLE_BASIC_AUTHENTICATION == "false" {
130135
if constants.SMTP_HOST == "" || constants.SENDER_EMAIL == "" || constants.SENDER_PASSWORD == "" {
131136
constants.DISABLE_EMAIL_VERIFICATION = "true"

server/graph/generated/generated.go

Lines changed: 164 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/graph/model/models_gen.go

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/graph/schema.graphqls

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type Meta {
1313
isGithubLoginEnabled: Boolean!
1414
isEmailVerificationEnabled: Boolean!
1515
isBasicAuthenticationEnabled: Boolean!
16+
isMagicLoginEnabled: Boolean!
1617
}
1718

1819
type User {
@@ -112,9 +113,15 @@ input DeleteUserInput {
112113
email: String!
113114
}
114115

116+
input MagicLoginInput {
117+
email: String!
118+
roles: [String!]
119+
}
120+
115121
type Mutation {
116122
signup(params: SignUpInput!): AuthResponse!
117123
login(params: LoginInput!): AuthResponse!
124+
magicLogin(params: MagicLoginInput!): Response!
118125
logout: Response!
119126
updateProfile(params: UpdateProfileInput!): Response!
120127
adminUpdateUser(params: AdminUpdateUserInput!): User!

server/graph/schema.resolvers.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ func (r *mutationResolver) Login(ctx context.Context, params model.LoginInput) (
1919
return resolvers.Login(ctx, params)
2020
}
2121

22+
func (r *mutationResolver) MagicLogin(ctx context.Context, params model.MagicLoginInput) (*model.Response, error) {
23+
return resolvers.MagicLogin(ctx, params)
24+
}
25+
2226
func (r *mutationResolver) Logout(ctx context.Context) (*model.Response, error) {
2327
return resolvers.Logout(ctx)
2428
}

server/handlers/oauthCallback.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ func OAuthCallbackHandler() gin.HandlerFunc {
208208

209209
signupMethod := existingUser.SignupMethod
210210
if !strings.Contains(signupMethod, provider) {
211-
signupMethod = signupMethod + "," + enum.Github.String()
211+
signupMethod = signupMethod + "," + provider
212212
}
213213
user.SignupMethod = signupMethod
214214
user.Password = existingUser.Password

server/handlers/verifyEmail.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ func VerifyEmailHandler() gin.HandlerFunc {
4646
}
4747

4848
// update email_verified_at in users table
49-
db.Mgr.UpdateVerificationTime(time.Now().Unix(), user.ID)
49+
if user.EmailVerifiedAt <= 0 {
50+
db.Mgr.UpdateVerificationTime(time.Now().Unix(), user.ID)
51+
}
5052
// delete from verification table
5153
db.Mgr.DeleteToken(claim.Email)
5254

0 commit comments

Comments
 (0)