projectId; } public function getType(): string { return $this->type; } public function getRole(): string { return $this->role; } public function getScopes(): array { return $this->scopes; } public function getName(): string { return $this->name; } public function isUsageEnabled(): bool { return $this->usage; } /** * Decode the given secret key into a Key object, containing the project ID, type, role, scopes, and name. * Can be a stored API key or a dynamic key (JWT). * * @param Document $project * @param string $key * @return Key * @throws Exception */ public static function decode( Document $project, string $key ): Key { if (\str_contains($key, '_')) { [$type, $secret] = \explode('_', $key, 2); } else { $type = API_KEY_STANDARD; $secret = $key; } $role = Auth::USER_ROLE_APPS; $roles = Config::getParam('roles', []); $scopes = $roles[Auth::USER_ROLE_APPS]['scopes'] ?? []; $guestKey = new Key( $project->getId(), $type, Auth::USER_ROLE_GUESTS, $roles[Auth::USER_ROLE_GUESTS]['scopes'] ?? [], 'UNKNOWN' ); switch ($type) { case API_KEY_DYNAMIC: $jwtObj = new JWT( key: System::getEnv('_APP_OPENSSL_KEY_V1'), algo: 'HS256', maxAge: 86400, leeway: 0 ); try { $payload = $jwtObj->decode($secret); } catch (JWTException) { throw new Exception(Exception::API_KEY_EXPIRED); } $name = $payload['name'] ?? 'Dynamic Key'; $projectId = $payload['projectId'] ?? ''; $usage = $payload['usage'] ?? true; $scopes = \array_merge($payload['scopes'] ?? [], $scopes); if ($projectId !== $project->getId()) { return $guestKey; } return new Key( $projectId, $type, $role, $scopes, $name, $usage ); case API_KEY_STANDARD: $key = $project->find( key: 'secret', find: $key, subject: 'keys' ); if (!$key) { return $guestKey; } $expire = $key->getAttribute('expire'); if (!empty($expire) && $expire < DateTime::formatTz(DateTime::now())) { throw new Exception(Exception::PROJECT_KEY_EXPIRED); } $name = $key->getAttribute('name', 'UNKNOWN'); $scopes = \array_merge($key->getAttribute('scopes', []), $scopes); return new Key( $project->getId(), $type, $role, $scopes, $name ); default: return $guestKey; } } }