import { Header } from '@devvit/shared-types/Header.js';
import { Hostname } from '@devvit/shared-types/HostnameUtil.js';
/** Returns true for any header starting with "devvit-". */
export function isSystemHeader(header) {
    return header.startsWith('devvit-');
}
// These headers are always allowed to all destinations including untrusted
// destinations. System headers are not sent to non-system destinations by
// default. See headers.md. Sync to metadata_envelope_filter.go.
export const allowlistedReadHeaders = Object.freeze([
    Header.App,
    Header.AppUser,
    Header.Caller,
    Header.Canary,
    Header.Debug,
    Header.Installation,
    Header.Language,
    Header.ModPermissions,
    Header.StreamID,
    Header.Subreddit,
    Header.SubredditName,
    Header.Timezone,
    Header.TraceID,
    Header.User,
    Header.UserAgent,
]);
/**
 * Return a new shallow copy of metadata with restricted headers filtered out.
 *
 * Don't care about the origin of the request. System destinations have access
 * to all headers regardless of the sender.
 */
export function filterHeadersForDestination(namespace, metadata, destination) {
    if (isTrustedLocation(namespace, destination))
        return { ...metadata }; // No filtering.
    const allowedEntries = Object.entries(metadata).filter(([header]) => allowlistedReadHeaders.includes(header) || !isSystemHeader(header));
    return Object.fromEntries(allowedEntries);
}
export function isTrustedLocation(namespace, location) {
    return (
    // Allow runtime plugin clients, Studio, and test clients to send whatever
    // headers they wish. An actor trusts all Envelopes manufactured in its
    // own thread.
    location === namespace.hostname ||
        Hostname.isPlugin(location, namespace) ||
        Hostname.isSystem(location, namespace));
}
