export const scopeMessages = defineMessages({ userReadEmailLabel: { id: "scopes.userReadEmail.label", defaultMessage: "Read user email", }, userReadEmailDescription: { id: "scopes.userReadEmail.description", defaultMessage: "Read your email", }, userReadLabel: { id: "scopes.userRead.label", defaultMessage: "Read user data", }, userReadDescription: { id: "scopes.userRead.description", defaultMessage: "Access your public profile information", }, userWriteLabel: { id: "scopes.userWrite.label", defaultMessage: "Write user data", }, userWriteDescription: { id: "scopes.userWrite.description", defaultMessage: "Write to your profile", }, userDeleteLabel: { id: "scopes.userDelete.label", defaultMessage: "Delete your account", }, userDeleteDescription: { id: "scopes.userDelete.description", defaultMessage: "Delete your account", }, userAuthWriteLabel: { id: "scopes.userAuthWrite.label", defaultMessage: "Write auth data", }, userAuthWriteDescription: { id: "scopes.userAuthWrite.description", defaultMessage: "Modify your authentication data", }, notificationReadLabel: { id: "scopes.notificationRead.label", defaultMessage: "Read notifications", }, notificationReadDescription: { id: "scopes.notificationRead.description", defaultMessage: "Read your notifications", }, notificationWriteLabel: { id: "scopes.notificationWrite.label", defaultMessage: "Write notifications", }, notificationWriteDescription: { id: "scopes.notificationWrite.description", defaultMessage: "Delete/View your notifications", }, payoutsReadLabel: { id: "scopes.payoutsRead.label", defaultMessage: "Read payouts", }, payoutsReadDescription: { id: "scopes.payoutsRead.description", defaultMessage: "Read your payouts data", }, payoutsWriteLabel: { id: "scopes.payoutsWrite.label", defaultMessage: "Write payouts", }, payoutsWriteDescription: { id: "scopes.payoutsWrite.description", defaultMessage: "Withdraw money", }, analyticsLabel: { id: "scopes.analytics.label", defaultMessage: "Read analytics", }, analyticsDescription: { id: "scopes.analytics.description", defaultMessage: "Access your analytics data", }, projectCreateLabel: { id: "scopes.projectCreate.label", defaultMessage: "Create projects", }, projectCreateDescription: { id: "scopes.projectCreate.description", defaultMessage: "Create new projects", }, projectReadLabel: { id: "scopes.projectRead.label", defaultMessage: "Read projects", }, projectReadDescription: { id: "scopes.projectRead.description", defaultMessage: "Read all your projects", }, projectWriteLabel: { id: "scopes.projectWrite.label", defaultMessage: "Write projects", }, projectWriteDescription: { id: "scopes.projectWrite.description", defaultMessage: "Write to project data", }, projectDeleteLabel: { id: "scopes.projectDelete.label", defaultMessage: "Delete projects", }, projectDeleteDescription: { id: "scopes.projectDelete.description", defaultMessage: "Delete your projects", }, versionCreateLabel: { id: "scopes.versionCreate.label", defaultMessage: "Create versions", }, versionCreateDescription: { id: "scopes.versionCreate.description", defaultMessage: "Create new versions", }, versionReadLabel: { id: "scopes.versionRead.label", defaultMessage: "Read versions", }, versionReadDescription: { id: "scopes.versionRead.description", defaultMessage: "Read all versions", }, versionWriteLabel: { id: "scopes.versionWrite.label", defaultMessage: "Write versions", }, versionWriteDescription: { id: "scopes.versionWrite.description", defaultMessage: "Write to version data", }, versionDeleteLabel: { id: "scopes.versionDelete.label", defaultMessage: "Delete versions", }, versionDeleteDescription: { id: "scopes.versionDelete.description", defaultMessage: "Delete a version", }, reportCreateLabel: { id: "scopes.reportCreate.label", defaultMessage: "Create reports", }, reportCreateDescription: { id: "scopes.reportCreate.description", defaultMessage: "Create reports", }, reportReadLabel: { id: "scopes.reportRead.label", defaultMessage: "Read reports", }, reportReadDescription: { id: "scopes.reportRead.description", defaultMessage: "Read reports", }, reportWriteLabel: { id: "scopes.reportWrite.label", defaultMessage: "Write reports", }, reportWriteDescription: { id: "scopes.reportWrite.description", defaultMessage: "Edit reports", }, reportDeleteLabel: { id: "scopes.reportDelete.label", defaultMessage: "Delete reports", }, reportDeleteDescription: { id: "scopes.reportDelete.description", defaultMessage: "Delete reports", }, threadReadLabel: { id: "scopes.threadRead.label", defaultMessage: "Read threads", }, threadReadDescription: { id: "scopes.threadRead.description", defaultMessage: "Read threads", }, threadWriteLabel: { id: "scopes.threadWrite.label", defaultMessage: "Write threads", }, threadWriteDescription: { id: "scopes.threadWrite.description", defaultMessage: "Write to threads", }, patCreateLabel: { id: "scopes.patCreate.label", defaultMessage: "Create PATs", }, patCreateDescription: { id: "scopes.patCreate.description", defaultMessage: "Create personal API tokens", }, patReadLabel: { id: "scopes.patRead.label", defaultMessage: "Read PATs", }, patReadDescription: { id: "scopes.patRead.description", defaultMessage: "View created API tokens", }, patWriteLabel: { id: "scopes.patWrite.label", defaultMessage: "Write PATs", }, patWriteDescription: { id: "scopes.patWrite.description", defaultMessage: "Edit personal API tokens", }, patDeleteLabel: { id: "scopes.patDelete.label", defaultMessage: "Delete PATs", }, patDeleteDescription: { id: "scopes.patDelete.description", defaultMessage: "Delete your personal API tokens", }, sessionReadLabel: { id: "scopes.sessionRead.label", defaultMessage: "Read sessions", }, sessionReadDescription: { id: "scopes.sessionRead.description", defaultMessage: "Read active sessions", }, sessionDeleteLabel: { id: "scopes.sessionDelete.label", defaultMessage: "Delete sessions", }, sessionDeleteDescription: { id: "scopes.sessionDelete.description", defaultMessage: "Delete sessions", }, performAnalyticsLabel: { id: "scopes.performAnalytics.label", defaultMessage: "Perform analytics", }, performAnalyticsDescription: { id: "scopes.performAnalytics.description", defaultMessage: "Perform analytics actions", }, collectionCreateLabel: { id: "scopes.collectionCreate.label", defaultMessage: "Create collections", }, collectionCreateDescription: { id: "scopes.collectionCreate.description", defaultMessage: "Create collections", }, collectionReadLabel: { id: "scopes.collectionRead.label", defaultMessage: "Read collections", }, collectionReadDescription: { id: "scopes.collectionRead.description", defaultMessage: "Read collections", }, collectionWriteLabel: { id: "scopes.collectionWrite.label", defaultMessage: "Write collections", }, collectionWriteDescription: { id: "scopes.collectionWrite.description", defaultMessage: "Write to collections", }, collectionDeleteLabel: { id: "scopes.collectionDelete.label", defaultMessage: "Delete collections", }, collectionDeleteDescription: { id: "scopes.collectionDelete.description", defaultMessage: "Delete collections", }, organizationCreateLabel: { id: "scopes.organizationCreate.label", defaultMessage: "Create organizations", }, organizationCreateDescription: { id: "scopes.organizationCreate.description", defaultMessage: "Create organizations", }, organizationReadLabel: { id: "scopes.organizationRead.label", defaultMessage: "Read organizations", }, organizationReadDescription: { id: "scopes.organizationRead.description", defaultMessage: "Read organizations", }, organizationWriteLabel: { id: "scopes.organizationWrite.label", defaultMessage: "Write organizations", }, organizationWriteDescription: { id: "scopes.organizationWrite.description", defaultMessage: "Write to organizations", }, organizationDeleteLabel: { id: "scopes.organizationDelete.label", defaultMessage: "Delete organizations", }, organizationDeleteDescription: { id: "scopes.organizationDelete.description", defaultMessage: "Delete organizations", }, sessionAccessLabel: { id: "scopes.sessionAccess.label", defaultMessage: "Access sessions", }, sessionAccessDescription: { id: "scopes.sessionAccess.description", defaultMessage: "Access modrinth-issued sessions", }, }); const scopeDefinitions = [ { id: "USER_READ_EMAIL", value: BigInt(1) << BigInt(0), label: scopeMessages.userReadEmailLabel, desc: scopeMessages.userReadEmailDescription, }, { id: "USER_READ", value: BigInt(1) << BigInt(1), label: scopeMessages.userReadLabel, desc: scopeMessages.userReadDescription, }, { id: "USER_WRITE", value: BigInt(1) << BigInt(2), label: scopeMessages.userWriteLabel, desc: scopeMessages.userWriteDescription, }, { id: "USER_DELETE", value: BigInt(1) << BigInt(3), label: scopeMessages.userDeleteLabel, desc: scopeMessages.userDeleteDescription, }, { id: "USER_AUTH_WRITE", value: BigInt(1) << BigInt(4), label: scopeMessages.userAuthWriteLabel, desc: scopeMessages.userAuthWriteDescription, }, { id: "NOTIFICATION_READ", value: BigInt(1) << BigInt(5), label: scopeMessages.notificationReadLabel, desc: scopeMessages.notificationReadDescription, }, { id: "NOTIFICATION_WRITE", value: BigInt(1) << BigInt(6), label: scopeMessages.notificationWriteLabel, desc: scopeMessages.notificationWriteDescription, }, { id: "PAYOUTS_READ", value: BigInt(1) << BigInt(7), label: scopeMessages.payoutsReadLabel, desc: scopeMessages.payoutsReadDescription, }, { id: "PAYOUTS_WRITE", value: BigInt(1) << BigInt(8), label: scopeMessages.payoutsWriteLabel, desc: scopeMessages.payoutsWriteDescription, }, { id: "ANALYTICS", value: BigInt(1) << BigInt(9), label: scopeMessages.analyticsLabel, desc: scopeMessages.analyticsDescription, }, { id: "PROJECT_CREATE", value: BigInt(1) << BigInt(10), label: scopeMessages.projectCreateLabel, desc: scopeMessages.projectCreateDescription, }, { id: "PROJECT_READ", value: BigInt(1) << BigInt(11), label: scopeMessages.projectReadLabel, desc: scopeMessages.projectReadDescription, }, { id: "PROJECT_WRITE", value: BigInt(1) << BigInt(12), label: scopeMessages.projectWriteLabel, desc: scopeMessages.projectWriteDescription, }, { id: "PROJECT_DELETE", value: BigInt(1) << BigInt(13), label: scopeMessages.projectDeleteLabel, desc: scopeMessages.projectDeleteDescription, }, { id: "VERSION_CREATE", value: BigInt(1) << BigInt(14), label: scopeMessages.versionCreateLabel, desc: scopeMessages.versionCreateDescription, }, { id: "VERSION_READ", value: BigInt(1) << BigInt(15), label: scopeMessages.versionReadLabel, desc: scopeMessages.versionReadDescription, }, { id: "VERSION_WRITE", value: BigInt(1) << BigInt(16), label: scopeMessages.versionWriteLabel, desc: scopeMessages.versionWriteDescription, }, { id: "VERSION_DELETE", value: BigInt(1) << BigInt(17), label: scopeMessages.versionDeleteLabel, desc: scopeMessages.versionDeleteDescription, }, { id: "REPORT_CREATE", value: BigInt(1) << BigInt(18), label: scopeMessages.reportCreateLabel, desc: scopeMessages.reportCreateDescription, }, { id: "REPORT_READ", value: BigInt(1) << BigInt(19), label: scopeMessages.reportReadLabel, desc: scopeMessages.reportReadDescription, }, { id: "REPORT_WRITE", value: BigInt(1) << BigInt(20), label: scopeMessages.reportWriteLabel, desc: scopeMessages.reportWriteDescription, }, { id: "REPORT_DELETE", value: BigInt(1) << BigInt(21), label: scopeMessages.reportDeleteLabel, desc: scopeMessages.reportDeleteDescription, }, { id: "THREAD_READ", value: BigInt(1) << BigInt(22), label: scopeMessages.threadReadLabel, desc: scopeMessages.threadReadDescription, }, { id: "THREAD_WRITE", value: BigInt(1) << BigInt(23), label: scopeMessages.threadWriteLabel, desc: scopeMessages.threadWriteDescription, }, { id: "PAT_CREATE", value: BigInt(1) << BigInt(24), label: scopeMessages.patCreateLabel, desc: scopeMessages.patCreateDescription, }, { id: "PAT_READ", value: BigInt(1) << BigInt(25), label: scopeMessages.patReadLabel, desc: scopeMessages.patReadDescription, }, { id: "PAT_WRITE", value: BigInt(1) << BigInt(26), label: scopeMessages.patWriteLabel, desc: scopeMessages.patWriteDescription, }, { id: "PAT_DELETE", value: BigInt(1) << BigInt(27), label: scopeMessages.patDeleteLabel, desc: scopeMessages.patDeleteDescription, }, { id: "SESSION_READ", value: BigInt(1) << BigInt(28), label: scopeMessages.sessionReadLabel, desc: scopeMessages.sessionReadDescription, }, { id: "SESSION_DELETE", value: BigInt(1) << BigInt(29), label: scopeMessages.sessionDeleteLabel, desc: scopeMessages.sessionDeleteDescription, }, { id: "PERFORM_ANALYTICS", value: BigInt(1) << BigInt(30), label: scopeMessages.performAnalyticsLabel, desc: scopeMessages.performAnalyticsDescription, }, { id: "COLLECTION_CREATE", value: BigInt(1) << BigInt(31), label: scopeMessages.collectionCreateLabel, desc: scopeMessages.collectionCreateDescription, }, { id: "COLLECTION_READ", value: BigInt(1) << BigInt(32), label: scopeMessages.collectionReadLabel, desc: scopeMessages.collectionReadDescription, }, { id: "COLLECTION_WRITE", value: BigInt(1) << BigInt(33), label: scopeMessages.collectionWriteLabel, desc: scopeMessages.collectionWriteDescription, }, { id: "COLLECTION_DELETE", value: BigInt(1) << BigInt(34), label: scopeMessages.collectionDeleteLabel, desc: scopeMessages.collectionDeleteDescription, }, { id: "ORGANIZATION_CREATE", value: BigInt(1) << BigInt(35), label: scopeMessages.organizationCreateLabel, desc: scopeMessages.organizationCreateDescription, }, { id: "ORGANIZATION_READ", value: BigInt(1) << BigInt(36), label: scopeMessages.organizationReadLabel, desc: scopeMessages.organizationReadDescription, }, { id: "ORGANIZATION_WRITE", value: BigInt(1) << BigInt(37), label: scopeMessages.organizationWriteLabel, desc: scopeMessages.organizationWriteDescription, }, { id: "ORGANIZATION_DELETE", value: BigInt(1) << BigInt(38), label: scopeMessages.organizationDeleteLabel, desc: scopeMessages.organizationDeleteDescription, }, { id: "SESSION_ACCESS", value: BigInt(1) << BigInt(39), label: scopeMessages.sessionAccessLabel, desc: scopeMessages.sessionAccessDescription, }, ]; const Scopes = scopeDefinitions.reduce( (acc, scope) => { acc[scope.id] = scope.value; return acc; }, {} as Record, ); export const restrictedScopes = [ Scopes.PAT_READ, Scopes.PAT_CREATE, Scopes.PAT_WRITE, Scopes.PAT_DELETE, Scopes.SESSION_READ, Scopes.SESSION_DELETE, Scopes.SESSION_ACCESS, Scopes.USER_AUTH_WRITE, Scopes.USER_DELETE, Scopes.PERFORM_ANALYTICS, ]; export const scopeList = Object.entries(Scopes) .filter(([_, value]) => !restrictedScopes.includes(value)) .map(([key, _]) => key); export const getScopeValue = (scope: string) => { return Scopes[scope]; }; export const encodeScopes = (scopes: string[]) => { let scopeFlag = BigInt(0); // We iterate over the provided scopes for (const scope of scopes) { // We iterate over the entries of the Scopes object for (const [scopeName, scopeFlagValue] of Object.entries(Scopes)) { // If the scope name is the same as the provided scope, add the scope flag to the scopeFlag variable if (scopeName === scope) { scopeFlag = scopeFlag | scopeFlagValue; } } } return scopeFlag; }; export const decodeScopes = (scopes: bigint | number) => { if (typeof scopes === "number") { scopes = BigInt(scopes); } const authorizedScopes = []; // We iterate over the entries of the Scopes object for (const [scopeName, scopeFlag] of Object.entries(Scopes)) { // If the scope flag is present in the provided number, add the scope name to the list if ((scopes & scopeFlag) === scopeFlag) { authorizedScopes.push(scopeName); } } return authorizedScopes; }; export const hasScope = (scopes: bigint, scope: string) => { const authorizedScopes = decodeScopes(scopes); return authorizedScopes.includes(scope); }; export const toggleScope = (scopes: bigint, scope: string) => { const authorizedScopes = decodeScopes(scopes); if (authorizedScopes.includes(scope)) { return encodeScopes(authorizedScopes.filter((authorizedScope) => authorizedScope !== scope)); } else { return encodeScopes([...authorizedScopes, scope]); } }; export const useScopes = () => { const { formatMessage } = useVIntl(); const scopesToDefinitions = (scopes: bigint) => { const authorizedScopes = decodeScopes(scopes); return authorizedScopes.map((scope) => { const scopeDefinition = scopeDefinitions.find( (scopeDefinition) => scopeDefinition.id === scope, ); if (!scopeDefinition) { throw new Error(`Scope ${scope} not found`); } return formatMessage(scopeDefinition.desc); }); }; const scopesToLabels = (scopes: bigint) => { const authorizedScopes = decodeScopes(scopes); return authorizedScopes.map((scope) => { const scopeDefinition = scopeDefinitions.find( (scopeDefinition) => scopeDefinition.id === scope, ); if (!scopeDefinition) { throw new Error(`Scope ${scope} not found`); } return formatMessage(scopeDefinition.label); }); }; return { scopesToDefinitions, scopesToLabels, }; };