Files
b161467904 chore: update Angular to v21 (#9390)
* @rahul-rocket chore(deps): chore(deps): bump @angular/core from ^20.2.4 to 21.1.2

* fix(ui): update missing jest.preset.js

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

* chore(deps): bump jest-preset-angular to 16.0.0

* chore(deps): bump @nebular/* packages to 17.0.0 for Angular 21 compatibility

* chore(deps): upgrade all packages to Angular 21 and compatible dependencies

* chore(deps): upgrade all packages to Angular 21 and compatible dependencies

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

* Update yarn.lock

* Update yarn.lock

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

Replace 'jest-preset-angular/setup-jest' imports with the new 'setupZoneTestEnv' function.

* @nx/jest: replace-removed-matcher-aliases-v22-3

Replace removed matcher aliases in Jest v30 with their corresponding matcher

* chore(deps): @angular/common and @angular/core peerDependencies to ^21.1.0

* Update package.json

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

* chore(deps): bump @nebular/theme from ^16.0.0 to ^17.0.0

* chore(deps): upgrade all packages to Angular 21

* chore(deps): upgrade all packages to Angular 21

* fix(build): update helmet import to support 8.x default export

* fix(build): resolve TypeScript errors and improve code quality

- Fix TemplateRef type conflicts caused by duplicate @angular/core packages (ngx-permissions)
- Change moment imports from namespace to default imports for ESM compatibility
- Convert constructor injection to inject() function in multiple components
- Add OnPush change detection strategy to WindowLayoutComponent
- Make CountdownConfirmationComponent standalone
- Update LayoutWithDraggableObject to use any[] for draggableObject type

* fix(build): fix moment & timezone namespace packages

* fix(build): add jest config for missing packages

* chore(deps): bump swiper from 8.3.1 to 12.1.0

* fix(build): update swiper module and syntax

* Update time-tracking.component.ts

* chore(deps): downgrade `node-polyfill-webpack-plugin` from 4.1.0 to 1.1.4

* fix(deps): resolve browserslist "Unknown version 143 of and_chr" error

Add caniuse-lite and browserslist to yarn resolutions to force all

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

* fix(deps): standardize Angular 21.0.0 versions across all packages and fix compatibility issues

- Fix @angular/* packages to use exact version 21.0.0 (remove caret ^) across all apps, packages, and plugins
- Add @angular/cdk resolution to 21.0.0 to force consistent version

* fix(build): `ui-config` replace env files module issue

* fix(build): `ui-config` replace env files module issue

* fix(build): replace all TemplateRef<HTMLElement> with TemplateRef<any>

* Update package.json

* Update apps\agent\tsconfig.json

* chore(deps): upgrade packages to latest version

* Update yarn.lock

* Update yarn.lock

* fix(build): apply AI suggestion by bot agent reviewers

* fix(build): apply AI suggestion by bot agent reviewers

* fix(nx-migrations): migrate nx from 21.5.1 to 22.4.4

* chore(deps): bump @nestjs/common and @nestjs/core to 11.1.14

* fix(build): replace all TemplateRef<HTMLElement> with TemplateRef<any>

* fix(plugins): apply AI suggestion by bot agent reviewers

* Update yarn.lock

* chore(deps): bump packages

* Update yarn.lock

* chore(deps): bump packages

* chore(deps): bump packages

* fix(plugins): replace 'jest-preset-angular/setup-jest' imports with the new 'setupZoneTestEnv'

* fix(plugins): apply AI suggestion by bot agent reviewers

* fix(cspell): typo spelling :-)

* fix(plugins): apply AI suggestion by bot agent reviewers

* fix: fontawesome icon change version to FA 7

* refactor(ui-core): migrate dashboard directives to standalone

* refactor(ui-core): migrate pipes/directives to standalone

* fix(plugins): apply AI suggestion by bot agent reviewers

* fix(plugins): apply AI suggestion by bot agent reviewers

* chore(deps): bump packages

* refactor(ui-core): migrate directives to standalone

* fix(plugins): apply AI suggestion by bot agent reviewers

---------

Co-authored-by: Ruslan Konviser <evereq@gmail.com>
Co-authored-by: syns2191 <sutralian@gmail.com>
2026-02-20 09:52:34 +01:00

125 lines
3.4 KiB
JavaScript

const { notarize } = require('@electron/notarize');
const fs = require('node:fs');
const path = require('node:path');
const os = require('os');
require('dotenv').config();
/**
* Check if a string looks like a file path and the file exists
*/
function isFilePath(str) {
if (!str || typeof str !== 'string') return false;
// Check if it looks like a path (starts with / or contains path separators)
const looksLikePath =
str.startsWith('/') ||
str.startsWith('./') ||
str.startsWith('../') ||
str.includes(path.sep) ||
str.endsWith('.p8');
if (!looksLikePath) return false;
// Check if the file actually exists
try {
return fs.existsSync(str);
} catch {
return false;
}
}
/**
* Validate that a string is valid base64
*/
function isValidBase64(str) {
if (!str || typeof str !== 'string') return false;
try {
// Decode and re-encode - they should match
const decoded = Buffer.from(str, 'base64');
const reEncoded = decoded.toString('base64');
// Compare (ignoring whitespace in original)
return reEncoded === str.replace(/\s/g, '');
} catch {
return false;
}
}
exports.default = async (context) => {
const {
electronPlatformName,
appOutDir,
packager: {
appInfo: { productFilename: appName, id: appBundleId }
}
} = context;
const { APPLE_API_KEY, APPLE_API_KEY_ID, APPLE_API_ISSUER } = process.env;
// Skip if not building for macOS
if (electronPlatformName !== 'darwin') {
console.log('Skipping notarization: Platform is not darwin.');
return;
}
// Check if credentials are present
if (!APPLE_API_KEY || !APPLE_API_KEY_ID || !APPLE_API_ISSUER) {
console.warn(
'WARN: `APPLE_API_KEY`, `APPLE_API_KEY_ID` & `APPLE_API_ISSUER` are missing. Skipping notarization.'
);
return;
}
// Case 1: APPLE_API_KEY is a file path - electron-builder handles notarization automatically
if (isFilePath(APPLE_API_KEY)) {
console.log(
`Skipping custom notarization: APPLE_API_KEY is a file path (${APPLE_API_KEY}). ` +
'Electron-builder will handle notarization automatically.'
);
return;
}
// Case 2: APPLE_API_KEY is base64 encoded - decode and notarize manually
if (isValidBase64(APPLE_API_KEY)) {
const appPath = path.join(appOutDir, `${appName}.app`);
const privateKeyPath = path.join(os.tmpdir(), `AuthKey_${APPLE_API_KEY_ID}.p8`);
try {
// Write the base64 decoded key to a temporary file
fs.writeFileSync(privateKeyPath, Buffer.from(APPLE_API_KEY, 'base64'), { mode: 0o600 });
console.log(`Notarizing ${appBundleId} found at ${appPath}...`);
await notarize({
tool: 'notarytool',
appBundleId,
appPath,
appleApiKey: privateKeyPath,
appleApiKeyId: APPLE_API_KEY_ID,
appleApiIssuer: APPLE_API_ISSUER
});
console.log(`Notarization successful for ${appBundleId}.`);
} catch (error) {
console.error(`ERROR: Failed to notarize: ${error}`);
} finally {
// Clean up the secret key file
try {
fs.unlinkSync(privateKeyPath);
} catch (cleanupError) {
// Don't throw - just warn
console.warn(`Warning: Failed to cleanup temporary file: ${cleanupError.message}`);
}
}
return;
}
// Case 3: APPLE_API_KEY is neither a file path nor valid base64
console.warn(
'WARN: APPLE_API_KEY is not a valid file path or base64-encoded string. ' +
'Skipping notarization. Please set APPLE_API_KEY to either:\n' +
' - A file path to the .p8 private key (e.g., /path/to/AuthKey_XXXXX.p8)\n' +
' - A base64-encoded string of the private key contents'
);
};