hapijs / hapi

The Simple, Secure Framework Developers Trust
https://hapi.dev
Other
14.58k stars 1.34k forks source link

Set additional route options from auth plugin added in route options auth #4520

Open szmyt151 opened 1 month ago

szmyt151 commented 1 month ago

Runtime

nodejs

Runtime version

20

Module version

21.3.10

Used with

hapi

Any other relevant information

No response

How can we help?

I need to change route options from auth plugin:

example route

hapiServer.route({
            method: 'GET',
            path: '/users',
            handler: this.handler.getUsersForLoggedInUserCompany.bind(this.handler),
            options: {
                auth: auth.setAuth(hapiServer, {
                    scopes: ['Internal', 'User'],
                    roles: ['userRole'],
                }),
                response: {
                    failAction: 'error',
                    status: {
                        200: AccountSchemas.responseUsers,
                    },
                },
            },
        });

In auth.setAuth I have options based on it and some manipulations to hide sensitive values I have to put in

 auth: auth.setAuth(hapiServer, { scopes: ['Internal', 'User'], roles: ['Rsa.Default'] }),
                plugins: {
                    'hapi-swagger': {
                        'x-vi-visibility': 'external',
                        'x-vi-permission': {
                            scopes: ['Internal', 'User'],
                            roles: ['Rsa.Default'],
                        },
                    },
                },

Is it possible? I tried in auth plugin

  // server.ext('onPostStart', () => {
            //     server.table().forEach((route) => {
            //         // @ts-ignore
            //         route.settings.plugins['hapi-swagger'] = {
            //             // @ts-ignore
            //             ...route.settings.plugins['hapi-swagger'],
            //             'x-vi-visibility': isViVisibility(route.settings.auth || {}),
            //             'x-vi-permission': viPermisions(route.settings.auth || {}),
            //         };
            //     });
            // });

but i can not get information about route in normal way and these values are not passing when I call for /openapi.json route

export const setAuth = function (server: Hapi.Server, options: AuthOptions) {
    const name = uuid.v4();
    server.auth.strategy(name, SCHEME_NAME, options);

    return name;
};

How to modify route options.plugins via auth plugin?

damusix commented 1 month ago

@szmyt151 I think you want to play around with serve.rules()

This is from my own code-base, so it will be missing context. The point is: you can use rules to configure universal route options. The processor parses your route.rules object and you can decide what to do with it there.


declare module '@hapi/hapi' {

    interface RouteRules {
        consumes?: SwaggerRouteRules['consumes'];
        deprecated?: SwaggerRouteRules['deprecated'];
        order?: SwaggerRouteRules['order'];
        payloadType?: SwaggerRouteRules['payloadType'];
        produces?: SwaggerRouteRules['produces'];
        responses?: SwaggerRouteRules['responses'];
    }
}

export const swaggerRulesProcess = {

    processor(rules: RouteRules) {

        const isSwaggerConfig = Boolean(
            rules.consumes ||
            rules.deprecated ||
            rules.order ||
            rules.payloadType ||
            rules.produces ||
            rules.responses
        )

        const config: SwaggerRouteRules = {};

        if (isSwaggerConfig) {

            config.consumes = rules.consumes;
            config.deprecated = rules.deprecated;
            config.order = rules.order;
            config.payloadType = rules.payloadType;
            config.produces = rules.produces;
            config.responses = rules.responses;

            return {
                tags: ['api'],
                plugins: {
                    'hapi-swagger': config
                }
            };
        }

        return null;
    },
    schema: {
        consumes: Joi.array().items(Joi.string()),
        deprecated: Joi.boolean(),
        order: Joi.number(),
        payloadType: Joi.string(),
        produces: Joi.array().items(Joi.string()),
        responses: Joi.object().pattern(
            Joi.string().allow(Joi.number().required()),
            Joi.object({
                description: Joi.string().required(),
                schema: Joi.object().required().allow(null)
            })
        )
    }
};