https://supertokens.com/ logo
Title
d

doraig

10/22/2022, 7:06 PM
Quick question, with respect to role and permission validation can we create a custom validator in overrideGlobalClaimValidators?
r

rp

10/23/2022, 4:32 AM
Hey @doraig yea you can.
What’s the behaviour you want? And which backend SDK?
I can share some code
d

doraig

10/23/2022, 8:30 AM
For node sdk
r

rp

10/23/2022, 3:22 PM
okay. And what's the behaviour you want for the claim? For example, from where is the claim value fetched and how often should it be refreshed?
d

doraig

10/23/2022, 9:44 PM
Claim details are part of JWT payload, so was think of using OPA check against the user attribute
r

rp

10/24/2022, 5:28 AM
So you can build your own claim validator to use in overrideGlobalClaimValidators:
ts
import { SessionClaimValidator } from "supertokens-node/recipe/session"
import UserRoles from "supertokens-node/recipe/userroles";

let MyCustomClaimValidator: (runOPARule: (roles: string[]) => Promise<boolean>, maxAgeInSeconds?: number) => SessionClaimValidator = (runOPARule, maxAgeInSeconds) => {
    return {
        ...UserRoles.UserRoleClaim.validators.excludes("", maxAgeInSeconds),
        validate: async (payload: any, userContext: any): Promise<ClaimValidationResult> => {
            let roles = UserRoles.UserRoleClaim.getValueFromPayload(payload);
            if (roles === undefined) {
                return {
                    isValid: false,
                    reason: {
                        "message": "No roles in the session claim"
                    }
                }
            }
            let isValid = await runOPARule(roles)
            if (!isValid) {
                return {
                    isValid: false,
                    reason: {
                        "message": "Failed OPA check"
                    }
                }
            }
            return {
                isValid: true
            }
        }
    }
}

verifySession({
    overrideGlobalClaimValidators: (globalClaimValidators) => {
        return [...globalClaimValidators,
        MyCustomClaimValidator(async (roles) => {
            // TODO: define OPA check
            return true;
        })]
    }
})
Here I am essentially copying from an existing claim validator and modifying the validate function to do my own check.