// Copyright Abridged, Inc. 2021,2024. All Rights Reserved. // Node module: @collabland/api-security // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT import {getEnvVarAsObject} from '@collabland/common'; import {authenticate} from '@loopback/authentication'; import {securityId, UserProfile} from '@loopback/security'; export interface AuthConfig {} export interface ClientApplicationRegistration { id: string; name: string; } /** * A special profile for anonymous users (unauthenticated) */ export const ANONYMOUS_USER: UserProfile = { platform: 'collabland', [securityId]: '$anonymous', id: '$anonymous', }; /** * Check if the given user profile is anonymous * @param user - User profile * @returns */ export function isAnonymous(user: UserProfile) { return ( user.platform === 'collabland' && user[securityId] === ANONYMOUS_USER[securityId] && user.id === ANONYMOUS_USER.id ); } /** * Create a special user profile for a client application * @param clientApp - OAuth2 client application * @returns */ export function createServiceAccount( clientApp: ClientApplicationRegistration, ): UserProfile { const id = `$app/${clientApp.id}`; const name = `$app/${clientApp.name}`; return { [securityId]: id, platform: 'collabland', id: id, client_id: clientApp.id, name: name, type: 'SERVICE_ACCOUNT', }; } /** * Check if the given user profile is a service account * @param user - User profile * @returns */ export function isServiceAccount(user: UserProfile) { return user.platform === 'collabland' && user.type === 'SERVICE_ACCOUNT'; } /** * A special service account with admin permissions */ export const ADMIN_ACCOUNT: UserProfile = createServiceAccount({ id: '$admin', name: '$admin', }); /** * Check if the user is an admin account * @param user - User profile * @returns */ export function isAdmin(user: UserProfile) { return ( isServiceAccount(user) && user[securityId] === ADMIN_ACCOUNT[securityId] && user.id === ADMIN_ACCOUNT.id && user.name === ADMIN_ACCOUNT.name ); } export function isCustomerSupport(user: UserProfile) { const supportTeam = getEnvVarAsObject<{platform: string; id: string}[]>( 'COLLABLAND_SUPPORT_TEAM', [], ); const ids = [ ...supportTeam, /* {platform: 'discord', id: '779511607172530196'}, // Raymond {platform: 'telegram', id: '1260421322'}, // Raymond {platform: 'discord', id: '646733536744833054'}, // Alok {platform: 'telegram', id: '897802142'}, // Alok {platform: 'discord', id: '739068497375526923'}, // Abhishek {platform: 'telegram', id: '772545686'}, // Abhishek {platform: 'discord', id: '908565281150992384'}, // Vanilladelphia {platform: 'discord', id: '176043694242136064'}, // Vanilladelphia {platform: 'telegram', id: '1088682093'}, // Vanilladelphia {platform: 'discord', id: '818559214574108725'}, // Anjali */ ]; return ids.some( id => String(user[securityId] ?? user.id) === id.id && user.platform === id.platform, ); } export const API_KEY_AUTHENTICATION = 'api-key-auth'; export const AE_TOKEN_AUTHENTICATION = 'ae-token-auth'; export const ETHEREUM_AUTHENTICATION = 'ethereum-auth'; export const ANONYMOUS_AUTHENTICATION = 'anonymous-auth'; export const CLIENT_APPLICATION_AUTHENTICATION = 'client-application-auth'; export const OAUTH2_AUTHENTICATION = 'oauth2-auth'; export const DISCORD_AUTHENTICATION = 'discord-auth'; // No longer used /** * A short-cut decorator to mark classes/methods to be authenticated */ export function auth() { return authenticate( API_KEY_AUTHENTICATION, OAUTH2_AUTHENTICATION, // oAuth2 access token AE_TOKEN_AUTHENTICATION, // Authenticated encryption token ETHEREUM_AUTHENTICATION, // Wallet signature based authentication CLIENT_APPLICATION_AUTHENTICATION, // Check client application ); } /** * Composition of authentication decorators * @param decorators * @returns */ export function composeAuthDecorators( ...decorators: ReturnType[] ) { return (...args: Parameters>) => { for (const fn of decorators) { fn(...args); } }; } /** * Get the identity provider of the user profile behind an access token. The * identity provider is used to login a user * @param user - User profile * @returns */ export function getIdentityProvider(user: UserProfile) { return user.idp ?? user.user_profile?.idp ?? user.platform; }