UNPKG

@nestjs-mod/supabase

Version:

NestJS JavaScript Client for Supabase (Wrapper for https://www.npmjs.com/package/@supabase/supabase-js)

161 lines 7.95 kB
"use strict"; var SupabaseService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.SupabaseService = void 0; const tslib_1 = require("tslib"); const common_1 = require("@nestjs-mod/common"); const common_2 = require("@nestjs/common"); const core_1 = require("@nestjs/core"); const supabase_js_1 = require("@supabase/supabase-js"); const supabase_configuration_1 = require("./supabase.configuration"); const supabase_decorators_1 = require("./supabase.decorators"); const supabase_environments_1 = require("./supabase.environments"); const supabase_errors_1 = require("./supabase.errors"); let SupabaseService = SupabaseService_1 = class SupabaseService { constructor(reflector, supabaseConfiguration, supabaseStaticEnvironments) { this.reflector = reflector; this.supabaseConfiguration = supabaseConfiguration; this.supabaseStaticEnvironments = supabaseStaticEnvironments; this.logger = new common_2.Logger(SupabaseService_1.name); } onModuleInit() { this.supabaseClient = new supabase_js_1.SupabaseClient(this.supabaseStaticEnvironments.url, this.supabaseStaticEnvironments.key, { ...this.supabaseConfiguration.clientOptions, global: { ...this.supabaseConfiguration.clientOptions, headers: { ...this.supabaseConfiguration.extraHeaders, ...this.supabaseConfiguration.clientOptions?.global?.headers } } }); } getSupabaseClient() { return this.supabaseClient; } // eslint-disable-next-line @typescript-eslint/no-explicit-any async getUserFromRequest(ctx, checkAccess = true) { await this.tryGetOrCreateCurrentUserWithExternalUserId(ctx); await this.checkAccessValidator(checkAccess, ctx); const req = this.getRequestFromExecutionContext(ctx); this.setInfoOfExternalUserIdToRequest(req); this.setSkippedBySupabaseIfUserIsEmpty(req); return req.supabaseUser; } setSkippedBySupabaseIfUserIsEmpty(req) { req.skippedBySupabase = req.supabaseUser === undefined || req.supabaseUser?.id === undefined; } setInfoOfExternalUserIdToRequest(req) { if (req.supabaseUser?.id && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion !req?.headers?.[this.supabaseConfiguration.externalUserIdHeaderName]) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion req.headers[this.supabaseConfiguration.externalUserIdHeaderName] = req.supabaseUser?.id; req.externalUserId = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion req?.headers?.[this.supabaseConfiguration.externalUserIdHeaderName]; } } async checkAccessValidator(checkAccess, ctx) { const { checkAccessMetadata, allowEmptyUserMetadata } = this.getHandlersReflectMetadata(ctx); const req = this.getRequestFromExecutionContext(ctx); if (allowEmptyUserMetadata) { req.skipEmptySupabaseUser = true; } if (checkAccess) { // check access by custom logic const checkAccessValidatorResult = this.supabaseConfiguration .checkAccessValidator ? await this.supabaseConfiguration.checkAccessValidator(req.supabaseUser, checkAccessMetadata, ctx) : false; // check access by roles if (!req.skipEmptySupabaseUser && !checkAccessValidatorResult && !req.supabaseUser?.id) { throw new supabase_errors_1.SupabaseError(supabase_errors_1.SupabaseErrorEnum.UNAUTHORIZED); } } } async tryGetOrCreateCurrentUserWithExternalUserId(ctx) { const req = this.getRequestFromExecutionContext(ctx); if (!req.supabaseUser?.id) { const token = req.headers?.authorization?.split(' ')[1]; if (token && token !== 'undefined') { // check user in supabase try { const getProfileResult = await this.supabaseClient.auth.getUser(token); if (!getProfileResult.error) { req.supabaseUser = { email: getProfileResult.data.user.email, id: getProfileResult.data.user.id, created_at: (+new Date(getProfileResult.data.user.created_at)).toString(), updated_at: getProfileResult.data.user.updated_at ? (+new Date(getProfileResult.data.user.updated_at)).toString() : '0', role: 'user', picture: getProfileResult.data.user.user_metadata['picture'], }; } else { this.logger.debug({ token }); this.logger.error(getProfileResult.error.message, getProfileResult.error.stack); throw new supabase_errors_1.SupabaseError(getProfileResult.error.message); } } catch (err) { req.supabaseUser = { id: undefined }; } } // check external user id if (!req.supabaseUser) { req.externalUserId = req?.headers?.[ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.supabaseConfiguration.externalUserIdHeaderName]; req.externalAppId = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion req?.headers?.[this.supabaseConfiguration.externalAppIdHeaderName]; if (req.externalAppId && !this.supabaseStaticEnvironments.allowedExternalAppIds?.includes(req.externalAppId)) { req.supabaseUser = { id: req.externalUserId ? (await this.supabaseConfiguration.getSupabaseUserFromExternalUserId?.(req.externalUserId, req.externalAppId, ctx))?.id : undefined, }; } } } req.supabaseUser = req.supabaseUser || { id: undefined }; } getRequestFromExecutionContext(ctx) { const req = (0, common_1.getRequestFromExecutionContext)(ctx); req.headers = req.headers || {}; return req; } getHandlersReflectMetadata(ctx) { const allowEmptyUserMetadata = Boolean((typeof ctx.getHandler === 'function' && this.reflector.get(supabase_decorators_1.AllowEmptySupabaseUser, ctx.getHandler())) || (typeof ctx.getClass === 'function' && this.reflector.get(supabase_decorators_1.AllowEmptySupabaseUser, ctx.getClass())) || undefined); const checkAccessMetadata = (typeof ctx.getHandler === 'function' && this.reflector.get(supabase_decorators_1.CheckSupabaseAccess, ctx.getHandler())) || (typeof ctx.getClass === 'function' && this.reflector.get(supabase_decorators_1.CheckSupabaseAccess, ctx.getClass())) || undefined; return { checkAccessMetadata, allowEmptyUserMetadata, }; } }; exports.SupabaseService = SupabaseService; exports.SupabaseService = SupabaseService = SupabaseService_1 = tslib_1.__decorate([ (0, common_2.Injectable)(), tslib_1.__metadata("design:paramtypes", [core_1.Reflector, supabase_configuration_1.SupabaseConfiguration, supabase_environments_1.SupabaseStaticEnvironments]) ], SupabaseService); //# sourceMappingURL=supabase.service.js.map