/home/bdqbpbxa/dev-subdomains/admin.pixory.goodface.com.ua/src/policies/auth0-optional.ts
import utils from"@strapi/utils";
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import { Context } from 'koa';
import { env } from 'src/config/env';
const { PolicyError } = utils.errors;
const client = jwksClient({
jwksUri: `${env.auth0.issuerBaseUrl}.well-known/jwks.json`,
});
function verifyTokenAsync(token: string, audience: string, issuer: string): Promise<any> {
return new Promise((resolve, reject) => {
jwt.verify(
token,
(header, callback) => {
if (!header.kid) {
return callback(new Error('Missing kid in token header'));
}
client.getSigningKey(header.kid, function (err, key) {
if (err) return callback(err);
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
},
{
audience,
issuer,
algorithms: ['RS256'],
},
(err, decoded) => {
if (err) return reject(err);
resolve(decoded);
}
);
});
}
const auth0OptionalPolicy = async (ctx: Context, config, { strapi }) => {
try {
const authHeader = ctx.request.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return true;
}
const token = authHeader.split(' ')[1];
const decoded = await verifyTokenAsync(
token,
env.auth0.audience,
env.auth0.issuerBaseUrl
);
const user = await strapi.db.query('plugin::users-permissions.user').findOne({
where: { sub: decoded.sub }
});
ctx.state.user = {
id: user?.id || null,
sub: decoded.sub,
...decoded,
};
return true;
} catch (error) {
if (error instanceof PolicyError) {
throw error;
}
if (error.name === 'JsonWebTokenError') {
throw new PolicyError('Invalid token format', { status: 401 });
}
if (error.name === 'TokenExpiredError') {
throw new PolicyError('Token has expired', { status: 401 });
}
if (error.name === 'NotBeforeError') {
throw new PolicyError('Token not active yet', { status: 401 });
}
// Handle JWKS errors
if (error.message && error.message.includes('kid')) {
throw new PolicyError('Invalid token key identifier', { status: 401 });
}
// Generic error fallback
strapi.log.error('Auth0 policy error:', error);
throw new PolicyError('Authentication failed', { status: 401 });
}
};
export default auth0OptionalPolicy;