Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add policies Types for JavaScript/TypeScript project #1095

Open
qupig opened this issue Apr 25, 2024 · 6 comments
Open

Add policies Types for JavaScript/TypeScript project #1095

qupig opened this issue Apr 25, 2024 · 6 comments

Comments

@qupig
Copy link
Contributor

qupig commented Apr 25, 2024

I would like to do this by writing the policies template with type checking in a JavaScript file and then generating the policies.json or org.mozilla.firefox.plist file directly. (I'm not familiar with Windows Group Policy, but maybe it works as well.)

Type checking helps us write correct template object, or can be used to build front-end GUI interfaces.

The json and plist conversion can be easily done using plutil that comes with macOS:

# json -> plist
plutil -convert xml1 "policies.json" -o "org.mozilla.firefox.plist"
# json -> binary plist
plutil -convert binary1 "policies.json" -o "org.mozilla.firefox.plist"
# plist -> json
plutil -convert json "org.mozilla.firefox.plist" -o "policies.json"

I've tried using this example policies.json to write the Types definition.

But what I'm interested in is, how is this file generated?

It's not a legal JSON file, but more like an interface defined in TypeScript, except it uses some actual strings as examples.

Is there already a hidden project used to generate the example files that already contains those Type definitions?

Or would the project be interested in receiving contributions to add Type definitions and/or conversion tools?

I just hope that we don’t reinvent the wheel, or that creating a wheel can help more developers/users with the same needs.

@mkaply
Copy link
Collaborator

mkaply commented Apr 25, 2024

That file is a sample file that's not intended to be used directly until it's modified.

For booleans, it shows both options.

This would normally be generated by hand based on the info in the template docs.

Someone built an addon to do this as well

https://addons.mozilla.org/en-US/firefox/addon/enterprise-policy-generator/

@qupig
Copy link
Contributor Author

qupig commented Apr 25, 2024

That file is a sample file that's not intended to be used directly until it's modified.
For booleans, it shows both options.

Yes, I know, that takes a lot of conversion, and I've noticed some errors.

This would normally be generated by hand based on the info in the template docs.

Oh, and thanks for the work you put into this, it would be nice to have some automated processes.

https://addons.mozilla.org/en-US/firefox/addon/enterprise-policy-generator/

Good to know, I checked out the project and it produces some meta data policies.js, that's nice, but it seems the project stopped being updated about 4 years ago?


I was just thinking about something simple that would be helpful for this project, maybe just some cli utils.

By the way, I just performed some simple transformations on it (unfinished):

policy-templates.d.ts
/**
 * @see {@link https://mozilla.github.io/policy-templates/#preferences Preferences}
 */
interface Preferences {
	Type?: "number" | "boolean" | "string";
	Value: number | boolean | string;
	Status: "default" | "locked" | "user" | "clear";
}

/**
 * @see {@link https://github.com/mozilla/policy-templates/blob/master/linux/policies.json}
 */
interface PolicyTemplate {
	policies?: {
		/** example: "managedfirefox.com,example.com" */
		AllowedDomainsForApps?: string;
		AppAutoUpdate?: boolean;
		/** example: "106." */
		AppUpdatePin?: string;
		/** example: "https://yoursite.com" */
		AppUpdateURL?: string;
		Authentication?: {
			/** example: ["mydomain.com", "https://myotherdomain.com"] */
			SPNEGO?: string[];
			/** example: ["mydomain.com", "https://myotherdomain.com"] */
			Delegated?: string[];
			/** example: ["mydomain.com", "https://myotherdomain.com"] */
			NTLM?: string[];
			AllowNonFQDN?: {
				SPNEGO?: boolean;
				NTLM?: boolean;
			};
			AllowProxies?: {
				SPNEGO?: boolean;
				NTLM?: boolean;
			};
			Locked?: boolean;
			PrivateBrowsing?: boolean;
		};
		AutoLaunchProtocolsFromOrigins?: [
			{
				/** example: "zoommtg" */
				protocol?: string;
				/** example: ["https://somesite.zoom.us"] */
				allowed_origins?: string[];
			}
		];
		BackgroundAppUpdate?: boolean;
		BlockAboutAddons?: boolean;
		BlockAboutConfig?: boolean;
		BlockAboutProfiles?: boolean;
		BlockAboutSupport?: boolean;
		Bookmarks?: [
			{
				/** example: "Example" */
				Title?: string;
				/** example: "https://example.com" */
				URL?: string;
				/** example: "https://example.com/favicon.ico" */
				Favicon?: string;
				Placement?: "toolbar" | "menu";
				/** example: "FolderName" */
				Folder?: string;
			}
		];
		CaptivePortal?: boolean;
		Certificates?: {
			/** example: ["cert1.der", "/home/username/cert2.pem"] */
			Install?: string[];
		};
		Containers?: {
			Default?: [
				{
					/** example: "My container" */
					name?: string;
					/** example: "pet" */
					icon?: string;
					/** example: "turquoise" */
					color?: string;
				}
			];
		};
		Cookies?: {
			/** example: ["http://example.org/"] */
			Allow?: string[];
			/** example: ["http://example.edu/"] */
			AllowSession?: string[];
			/** example: ["http://example.edu/"] */
			Block?: string[];
			Default?: boolean;
			AcceptThirdParty?: "always" | "never" | "from-visited";
			ExpireAtSessionEnd?: boolean;
			RejectTracker?: boolean;
			Locked?: boolean;
			Behavior?:
				| "accept"
				| "reject-foreign"
				| "reject"
				| "limit-foreign"
				| "reject-tracker"
				| "reject-tracker-and-partition-foreign";
			BehaviorPrivateBrowsing?:
				| "accept"
				| "reject-foreign"
				| "reject"
				| "limit-foreign"
				| "reject-tracker"
				| "reject-tracker-and-partition-foreign";
		};
		/** example: "${home}/Downloads" */
		DefaultDownloadDirectory?: string;
		DisableAppUpdate?: boolean;
		DisableBuiltinPDFViewer?: boolean;
		DisabledCiphers?: {
			CIPHER_NAME?: boolean;
		};
		DisableDeveloperTools?: boolean;
		DisableFeedbackCommands?: boolean;
		DisableFirefoxAccounts?: boolean;
		DisableFirefoxScreenshots?: boolean;
		DisableFirefoxStudies?: boolean;
		DisableForgetButton?: boolean;
		DisableFormHistory?: boolean;
		DisableMasterPasswordCreation?: boolean;
		DisablePasswordReveal?: boolean;
		DisablePocket?: boolean;
		DisablePrivateBrowsing?: boolean;
		DisableProfileImport?: boolean;
		DisableProfileRefresh?: boolean;
		DisableSafeMode?: boolean;
		DisableSecurityBypass?: {
			InvalidCertificate?: boolean;
			SafeBrowsing?: boolean;
		};
		DisableSetDesktopBackground?: boolean;
		DisableSystemAddonUpdate?: boolean;
		DisableTelemetry?: boolean;
		DisplayBookmarksToolbar?: "always" | "never" | "newtab";
		DisplayMenuBar?: "always" | "never" | "default-on" | "default-off";
		DNSOverHTTPS?: {
			Enabled?: boolean;
			/** example: "URL_TO_ALTERNATE_PROVIDER" */
			ProviderURL?: string;
			Locked?: boolean;
			/** example: ["example.com"] */
			ExcludedDomains?: string[];
		};
		DontCheckDefaultBrowser?: boolean;
		/** example: "${home}/Downloads" */
		DownloadDirectory?: string;
		EnableTrackingProtection?: {
			Value?: boolean;
			Locked?: boolean;
			Cryptomining?: boolean;
			Fingerprinting?: boolean;
			EmailTracking?: boolean;
			/** example: ["https://example.com"] */
			Exceptions?: string[];
		};
		EncryptedMediaExtensions?: {
			Enabled?: boolean;
			Locked?: boolean;
		};
		ExemptDomainFileTypePairsFromFileTypeDownloadWarnings?: [
			{
				/** example: "jnlp" */
				file_extension?: string;
				/** example: ["example.com"] */
				domains?: string[];
			}
		];
		Extensions?: {
			Install?: [
				"https://addons.mozilla.org/firefox/downloads/somefile.xpi",
				"//path/to/xpi"
			];
			/** example: ["[email protected]"] */
			Uninstall?: string[];
			/** example: ["[email protected]"] */
			Locked?: string[];
		};
		ExtensionSettings?: {
			"*": {
				/** example: "Custom error message." */
				blocked_install_message?: string;
				/** example: ["https://yourwebsite.com/*"] */
				install_sources?: string[];
				/** example: "blocked" */
				installation_mode?: string;
				/** example: ["extension"] */
				allowed_types?: string[];
			};
			"[email protected]": {
				/** example: "force_installed" */
				installation_mode?: string;
				/** example: "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi" */
				install_url?: string;
			};
			"[email protected]": {
				/** example: "allowed" */
				installation_mode?: string;
			};
		};
		ExtensionUpdate?: boolean;
		FirefoxHome?: {
			Search?: boolean;
			TopSites?: boolean;
			SponsoredTopSites?: boolean;
			Highlights?: boolean;
			Pocket?: boolean;
			SponsoredPocket?: boolean;
			Snippets?: boolean;
			Locked?: boolean;
		};
		FirefoxSuggest?: {
			WebSuggestions?: boolean;
			SponsoredSuggestions?: boolean;
			ImproveSuggest?: boolean;
			Locked?: boolean;
		};
		GoToIntranetSiteForSingleWordEntryInAddressBar?: boolean;
		Handlers?: {
			mimeTypes?: {
				"application/msword": {
					/** example: "useSystemDefault" */
					action?: string;
					ask?: false;
				};
			};
			schemes?: {
				mailto?: {
					/** example: "useHelperApp" */
					action?: string;
					ask?: boolean;
					handlers?: [
						{
							/** example: "Gmail" */
							name?: string;
							/** example: "https://mail.google.com/mail/?extsrc=mailto&url=%s" */
							uriTemplate?: string;
						}
					];
				};
			};
			extensions?: {
				pdf?: {
					/** example: "useHelperApp" */
					action?: string;
					ask?: boolean;
					handlers?: [
						{
							/** example: "Adobe Acrobat" */
							name?: string;
							/** example: "/usr/bin/acroread" */
							path?: string;
						}
					];
				};
			};
		};
		HardwareAcceleration?: boolean;
		Homepage?: {
			/** example: "http://example.com/" */
			URL?: string;
			Locked?: boolean;
			/** example: ["http://example.org/", "http://example.edu/"] */
			Additional?: string[];
			StartPage?: "none" | "homepage" | "previous-session" | "homepage-locked";
		};
		InstallAddonsPermission?: {
			/** example: ["http://example.org/", "http://example.edu/"] */
			Allow?: string[];
			Default?: boolean;
		};
		LegacySameSiteCookieBehaviorEnabled?: boolean;
		/** example: ["example.org", "example.edu"] */
		LegacySameSiteCookieBehaviorEnabledForDomainList?: string[];
		/** example: ["http://example.org/", "http://example.edu/"] */
		LocalFileLinks?: string[];
		ManagedBookmarks?: [
			{
				/** example: "My managed bookmarks folder" */
				toplevel_name?: string;
			},
			{
				/** example: "example.com" */
				url?: string;
				/** example: "Example" */
				name?: string;
			},
			{
				/** example: "Mozilla links" */
				name?: string;
				children?: [
					{
						/** example: "https://mozilla.org" */
						url?: string;
						/** example: "Mozilla.org" */
						name?: string;
					},
					{
						/** example: "https://support.mozilla.org/" */
						url?: string;
						/** example: "SUMO" */
						name?: string;
					}
				];
			}
		];
		NetworkPrediction?: boolean;
		NewTabPage?: boolean;
		NoDefaultBookmarks?: boolean;
		OfferToSaveLogins?: boolean;
		OfferToSaveLoginsDefault?: boolean;
		/** example: "http://example.org" */
		OverrideFirstRunPage?: string;
		/** example: "http://example.org" */
		OverridePostUpdatePage?: string;
		PasswordManagerEnabled?: boolean;
		/** example: ["https://example.org", "https://example.edu"] */
		PasswordManagerExceptions?: string[];
		PDFjs?: {
			Enabled?: boolean;
			EnablePermissions?: boolean;
		};
		Permissions?: {
			Camera?: {
				/** example: ["https://example.org", "https://example.org:1234"] */
				Allow?: string[];
				/** example: ["https://example.edu"] */
				Block?: string[];
				BlockNewRequests?: boolean;
				Locked?: boolean;
			};
			Microphone?: {
				/** example: ["https://example.org"] */
				Allow?: string[];
				/** example: ["https://example.edu"] */
				Block?: string[];
				BlockNewRequests?: boolean;
				Locked?: boolean;
			};
			Location?: {
				/** example: ["https://example.org"] */
				Allow?: string[];
				/** example: ["https://example.edu"] */
				Block?: string[];
				BlockNewRequests?: boolean;
				Locked?: boolean;
			};
			Notifications?: {
				/** example: ["https://example.org"] */
				Allow?: string[];
				/** example: ["https://example.edu"] */
				Block?: string[];
				BlockNewRequests?: boolean;
				Locked?: boolean;
			};
			Autoplay?: {
				/** example: ["https://example.org"] */
				Allow?: string[];
				/** example: ["https://example.edu"] */
				Block?: string[];
				Default?: "allow-audio-video" | "block-audio" | "block-audio-video";
				Locked?: boolean;
			};
		};
		PictureInPicture?: {
			Enabled?: boolean;
			Locked?: boolean;
		};
		PopupBlocking?: {
			/** example: ["http://example.org/", "http://example.edu/"] */
			Allow?: string[];
			Default?: boolean;
			Locked?: boolean;
		};
		Preferences?: { [x: string]: Preferences };
		PrimaryPassword?: boolean;
		PrintingEnabled?: boolean;
		PromptForDownloadLocation?: boolean;
		Proxy?: {
			Mode?: "none" | "system" | "manual" | "autoDetect" | "autoConfig";
			Locked?: boolean;
			/** example: "hostname" */
			HTTPProxy?: string;
			UseHTTPProxyForAllProtocols?: boolean;
			/** example: "hostname" */
			SSLProxy?: string;
			/** example: "hostname" */
			FTPProxy?: string;
			/** example: "hostname" */
			SOCKSProxy?: string;
			SOCKSVersion?: 4 | 5;
			/** example: "<local>" */
			Passthrough?: string;
			/** example: "URL_TO_AUTOCONFIG" */
			AutoConfigURL?: string;
			AutoLogin?: boolean;
			UseProxyForDNS?: boolean;
		};
		/** example: "de,en-US" */
		RequestedLocales?: string;
		SanitizeOnShutdown?: {
			Cache?: boolean;
			Cookies?: boolean;
			Downloads?: boolean;
			FormData?: boolean;
			History?: boolean;
			Sessions?: boolean;
			SiteSettings?: boolean;
			OfflineApps?: boolean;
			Locked?: boolean;
		};
		SearchEngines?: {
			Add?: [
				{
					/** example: "Example1" */
					Name?: string;
					/** example: "https://www.example.org/q={searchTerms}" */
					URLTemplate?: string;
					Method?: "GET" | "POST";
					/** example: "https://www.example.org/favicon.ico" */
					IconURL?: string;
					/** example: "example" */
					Alias?: string;
					/** example: "Description" */
					Description?: string;
					/** example: "name=value&q={searchTerms}" */
					PostData?: string;
					/** example: "https://www.example.org/suggestions/q={searchTerms}" */
					SuggestURLTemplate?: string;
				}
			];
			/** example: "NAME_OF_SEARCH_ENGINE" */
			Default?: string;
			PreventInstalls?: boolean;
			/** example: ["NAME_OF_SEARCH_ENGINE"] */
			Remove?: string[];
		};
		SearchSuggestEnabled?: boolean;
		SecurityDevices?: {
			/** example: "PATH_TO_LIBRARY_FOR_DEVICE" */
			NAME_OF_DEVICE?: string;
		};
		ShowHomeButton?: boolean;
		SSLVersionMax?: "tls1" | "tls1.1" | "tls1.2" | "tls1.3";
		SSLVersionMin?: "tls1" | "tls1.1" | "tls1.2" | "tls1.3";
		SupportMenu?: {
			/** example: "Support Menu" */
			Title?: string;
			/** example: "http://example.com/support" */
			URL?: string;
			/** example: "S" */
			AccessKey?: string;
		};
		StartDownloadsInTempDirectory?: boolean;
		UserMessaging?: {
			WhatsNew?: boolean;
			ExtensionRecommendations?: boolean;
			FeatureRecommendations?: boolean;
			UrlbarInterventions?: boolean;
			SkipOnboarding?: boolean;
			MoreFromMozilla?: boolean;
			Locked?: boolean;
		};
		UseSystemPrintDialog?: boolean;
		WebsiteFilter?: {
			/** example: ["<all_urls>"] */
			Block?: string[];
			/** example: ["http://example.org/*"] */
			Exceptions?: string[];
		};
	};
}

@mkaply
Copy link
Collaborator

mkaply commented Apr 26, 2024

So you're thinking this would be a separate file in github?

@qupig
Copy link
Contributor Author

qupig commented Apr 26, 2024

So you're thinking this would be a separate file in github?

I don't know. What do you think? If that helps people use the repo and get continued updates, why not?

But more importantly, I don't want anyone to increase their workload by maintaining this file individually.

So I'd like to have a set of source data there for generating these types, demo templates, or even the documentation.

Essentially I hope to reduce the workload of this repo and make it more usable by people.

It's not that easy to create anything useful from a document, and it's easy to make mistakes by repeating templates by hand.

Specifically, I might want create a generator similar to the project below that generates the required file types from upstream source data and is sustainably maintained.

https://github.com/Lusito/webextension-polyfill-ts#news-this-has-changed-to-be-a-pure-generator-project

Making an external project or extension may be easy, but keeping it up to date with upstream is not easy unless we embed it into a CI/CD workflow.

@qupig
Copy link
Contributor Author

qupig commented Apr 27, 2024

So it looks like the required upstream source data is at: policies-schema.json

@mkaply
Copy link
Collaborator

mkaply commented May 2, 2024

I love this idea. Policies-schema.json definitely has all the information we need in it.

I'll support you however I can.

Right now my release work is very manual and anything I could automate would be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants