# frozen_string_literal: true require 'psych' require_relative 'util' class InfisicalLicenseServer::Config AUTH_TIME = 1 * 24 * 60 * 60 attr_reader :data def initialize(file = 'config.yml') raise 'Missing configuration file' unless File.exist?(file) @data = Psych.load_file(file) end def auth?(token) Time.now - Time.at(decode_auth(token)['auth']) <= AUTH_TIME rescue StandardError => e puts "Failed to read auth token - #{e.class}: #{e}" puts e.backtrace false end def valid_key?(key) data['plans'].any? { |_, plan| plan['key'] == key } end def plan_for(key) if key.start_with? 'Bearer ' key = decode_auth(key)['key'] end plan_name, plan = data['plans'].find { |_, search| search['key'] == key } return nil unless plan plan['merged'] = default_plan.merge(_id: plan_name, slug: 'enterprise').deep_merge(plan['features']) plan['plan'] = plan_name plan end def decode_auth(token) raise 'Missing auth' unless token token = token[7..] if token.start_with? 'Bearer ' JSON.parse(Base64.decode64(token)) end # https://github.com/Infisical/infisical/blob/main/backend/src/ee/services/license/license-fns.ts#L55 def self.default_plan { _id: nil, slug: nil, tier: -1, workspaceLimit: nil, workspacesUsed: 0, memberLimit: nil, membersUsed: 0, environmentLimit: nil, environmentsUsed: 0, identityLimit: nil, identitiesUsed: 0, dynamicSecret: false, secretVersioning: true, pitRecovery: false, ipAllowlisting: false, rbac: false, githubOrgSync: false, customRateLimits: false, subOrganization: false, customAlerts: false, secretAccessInsights: false, auditLogs: false, auditLogsRetentionDays: 0, auditLogStreams: false, auditLogStreamLimit: 3, samlSSO: false, enforceGoogleSSO: false, hsm: false, oidcSSO: false, scim: false, ldap: false, groups: false, status: nil, trial_end: nil, has_used_trial: true, secretApproval: false, secretRotation: false, caCrl: false, instanceUserManagement: false, externalKms: false, rateLimits: { readLimit: 60, writeLimit: 200, secretsLimit: 40 }, pkiEst: false, pkiAcme: false, enforceMfa: false, projectTemplates: false, kmip: false, gateway: false, sshHostGroups: false, secretScanning: false, enterpriseSecretSyncs: false, enterpriseCertificateSyncs: false, enterpriseAppConnections: false, fips: false, eventSubscriptions: false, machineIdentityAuthTemplates: false, pkiLegacyTemplates: false, secretShareExternalBranding: false } end def default_plan self.class.default_plan end end