Skip to content

Commit

Permalink
feat: improve auth flow when user email is not verified
Browse files Browse the repository at this point in the history
If the user has their email not verified, instead of failing with a generic error message of "invalid JWT", print an error message asking user to verify their email and try again.

In Auth0 mode, if the JWT validation has failed on the backend at the moment of clicking "Login", get a new ID token from Auth0 on the next click. This way, the user will not have to reload the page after validating their email - they can simply click "Login" again to get in.

Part of #114.

Signed-off-by: Utku Ozdemir <[email protected]>
  • Loading branch information
utkuozdemir committed May 8, 2024
1 parent 5b8c130 commit 987f8cd
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
23 changes: 22 additions & 1 deletion frontend/src/views/omni/Auth/Authenticate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ import TIcon from "@/components/common/Icon/TIcon.vue";
import UserInfo from "@/components/common/UserInfo/UserInfo.vue";
import { withMetadata } from "@/api/options";
import { fetchOption } from "@/api/fetch.pb";
import { Code } from "@/api/google/rpc/code.pb";
import { Auth0VueClient } from "@auth0/auth0-vue/src/global";

const user = ref<User | undefined>(undefined);
let idToken = "";
Expand All @@ -88,9 +90,11 @@ const redirectToURL = (url: string) => {
}
}

let auth0: Auth0VueClient | undefined;

onMounted(() => {
if (authType.value === AuthType.Auth0) {
const auth0 = useAuth0();
auth0 = useAuth0();

user.value = auth0.user.value;
idToken = auth0.idTokenClaims.value.__raw;
Expand Down Expand Up @@ -194,8 +198,21 @@ const generatePublicKey = async () => {
await router.replace({ path: redirect });
}

let renewIdToken = false;

const confirmPublicKey = async () => {
try {
if (renewIdToken && auth0) {
renewIdToken = false;

await auth0.checkSession({
ignoreCache: true,
})

user.value = auth0.user.value;
idToken = auth0.idTokenClaims.value.__raw;
}

const options: fetchOption[] = [];

if (authType.value === AuthType.Auth0) {
Expand All @@ -216,6 +233,10 @@ const confirmPublicKey = async () => {
} catch (e) {
showError("Failed to confirm public key", e.message);

if (e?.code == Code.UNAUTHENTICATED && auth0) {
renewIdToken = true;
}

throw e;
}
}
Expand Down
12 changes: 11 additions & 1 deletion internal/pkg/auth/auth0/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,18 @@ func (a *CustomIDClaims) Validate(_ context.Context) error {
}

if !a.EmailVerified {
return errors.New("email is not verified")
return &EmailNotVerifiedError{Email: a.Email}
}

return nil
}

// EmailNotVerifiedError is an error that occurs when the email address is not verified.
type EmailNotVerifiedError struct {
Email string
}

// Error implements the error interface.
func (e EmailNotVerifiedError) Error() string {
return "email not verified: " + e.Email
}
8 changes: 8 additions & 0 deletions internal/pkg/auth/interceptor/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package interceptor
import (
"context"
"errors"
"fmt"

grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/siderolabs/go-api-signature/pkg/jwt"
Expand All @@ -18,6 +19,7 @@ import (
"google.golang.org/grpc/status"

"github.com/siderolabs/omni/internal/pkg/auth"
"github.com/siderolabs/omni/internal/pkg/auth/auth0"
)

var errGRPCInvalidJWT = status.Error(codes.Unauthenticated, "invalid jwt")
Expand Down Expand Up @@ -77,6 +79,12 @@ func (i *JWT) intercept(ctx context.Context) (context.Context, error) {
if err != nil {
i.logger.Info("invalid jwt", zap.Error(err))

var errEmailNotVerified *auth0.EmailNotVerifiedError

if errors.As(err, &errEmailNotVerified) {
return nil, status.Error(codes.Unauthenticated, fmt.Sprintf("Email address %q is not verified, please verify it and try again.", errEmailNotVerified.Email))
}

return nil, errGRPCInvalidJWT
}

Expand Down

0 comments on commit 987f8cd

Please sign in to comment.