Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ jobs:
run: |
yarn build:android

- name: 🔑 License backend hint
if: failure()
run: |
echo "::warning::The example app applies app.talsec.plugin, which requests a license token from portal-backend.talsec.app during the build."
echo "::warning::If the log shows 'Cannot resolve license', check that the backend is up and reachable from the runner before investigating this PR."

build-ios:
runs-on: macos-latest
needs: build-library
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [6.0.0] - 2026-09-30

- Android SDK version: 19.3.1
- iOS SDK version: 7.1.4

### React Native

#### Breaking

- Android builds now require the `app.talsec.plugin` Gradle plugin

### Android

#### Breaking

- Changed Talsec integration from Maven dependency to the `app.talsec.plugin` Gradle plugin with `talsec { }` configuration block

#### Fixed

- Root detection related bugs causing false positives

## [5.2.2] - 2026-09-29

- Android SDK version: 19.2.3
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ dependencies {
implementation "com.facebook.react:react-native:$react_native_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:19.2.3"
implementation "com.aheaditec.talsec.security:TalsecSecurity-Community-ReactNative:19.3.1"
}

if (isNewArchitectureEnabled()) {
Expand Down
1 change: 1 addition & 0 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply plugin: "app.talsec.plugin"

/**
* This is the configuration block to customize your React Native Android app.
Expand Down
3 changes: 3 additions & 0 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ buildscript {
repositories {
google()
mavenCentral()
maven { url "https://europe-west3-maven.pkg.dev/talsec-artifact-repository/plugin" }
}
dependencies {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
// TODO: set the real version once app.talsec.plugin with wrapper support is released
classpath("app.talsec.plugin:talsec-security-plugin:1.1.0")
}
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "freerasp-react-native",
"version": "5.2.2",
"version": "6.0.0",
"description": "React Native plugin for improving app security and threat monitoring on Android and iOS mobile devices.",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
50 changes: 50 additions & 0 deletions plugin/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const iosSpmProperties_1 = __importDefault(require("./iosSpmProperties"));
const { createBuildGradlePropsConfigPlugin } = config_plugins_1.AndroidConfig.BuildProperties;
const urlFreerasp = 'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp';
const urlJitpack = 'https://www.jitpack.io';
const urlTalsecPlugin = 'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/plugin';
const talsecPluginId = 'app.talsec.plugin';
// TODO: set the real version once app.talsec.plugin with wrapper support is released
const talsecPluginArtifact = 'app.talsec.plugin:talsec-security-plugin:1.1.0';
const setBuildscriptDependency = (buildGradle) => {
// This enables users in bare workflow to comment out the line to prevent freerasp from adding it back.
const mavenFreerasp = buildGradle.includes(urlFreerasp)
Expand Down Expand Up @@ -78,6 +82,50 @@ const withAndroidR8Version = (expoConfig, props) => {
return config;
});
};
const setTalsecGradlePlugin = (buildGradle) => {
if (buildGradle.includes(talsecPluginArtifact)) {
return buildGradle;
}
const talsecBuildscript = `
buildscript {
repositories {
maven { url "${urlTalsecPlugin}" }
}
dependencies {
classpath("${talsecPluginArtifact}")
}
}
`;
return buildGradle + `\n${talsecBuildscript}\n`;
};
const setTalsecAppPlugin = (appBuildGradle) => {
if (appBuildGradle.includes(talsecPluginId)) {
return appBuildGradle;
}
return appBuildGradle + `\napply plugin: "${talsecPluginId}"\n`;
};
const withTalsecGradlePlugin = (expoConfig) => {
return (0, config_plugins_1.withProjectBuildGradle)(expoConfig, (config) => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setTalsecGradlePlugin(config.modResults.contents);
}
else {
config_plugins_1.WarningAggregator.addWarningAndroid('freerasp-react-native', `Cannot automatically configure project build.gradle, because it's not groovy`);
}
return config;
});
};
const withTalsecAppPlugin = (expoConfig) => {
return (0, config_plugins_1.withAppBuildGradle)(expoConfig, (config) => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setTalsecAppPlugin(config.modResults.contents);
}
else {
config_plugins_1.WarningAggregator.addWarningAndroid('freerasp-react-native', `Cannot automatically configure app build.gradle, because it's not groovy`);
}
return config;
});
};
const withFreeraspIosFrameworks = (config, spmEnabled) => {
return (0, config_plugins_1.withPodfileProperties)(config, (cfg) => {
(0, iosSpmProperties_1.default)(cfg.modResults, spmEnabled);
Expand Down Expand Up @@ -110,6 +158,8 @@ const withRnTalsecIos = (config, props) => {
};
const withRnTalsecApp = (config, props) => {
config = withBuildscriptDependency(config);
config = withTalsecGradlePlugin(config);
config = withTalsecAppPlugin(config);
config = withAndroidMinSdkVersion(config, props);
config = withAndroidR8Version(config, props);
config = withRnTalsecIos(config, props);
Expand Down
67 changes: 67 additions & 0 deletions plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
createRunOncePlugin,
withDangerousMod,
withPodfileProperties,
withAppBuildGradle,
withProjectBuildGradle,
type ConfigPlugin,
} from '@expo/config-plugins';
Expand All @@ -19,6 +20,11 @@ const { createBuildGradlePropsConfigPlugin } = AndroidConfig.BuildProperties;
const urlFreerasp =
'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/freerasp';
const urlJitpack = 'https://www.jitpack.io';
const urlTalsecPlugin =
'https://europe-west3-maven.pkg.dev/talsec-artifact-repository/plugin';
const talsecPluginId = 'app.talsec.plugin';
// TODO: set the real version once app.talsec.plugin with wrapper support is released
const talsecPluginArtifact = 'app.talsec.plugin:talsec-security-plugin:1.1.0';

const setBuildscriptDependency = (buildGradle: string) => {
// This enables users in bare workflow to comment out the line to prevent freerasp from adding it back.
Expand Down Expand Up @@ -112,6 +118,65 @@ const withAndroidR8Version: ConfigPlugin<PluginConfigType> = (
});
};

const setTalsecGradlePlugin = (buildGradle: string) => {
if (buildGradle.includes(talsecPluginArtifact)) {
return buildGradle;
}

const talsecBuildscript = `
buildscript {
repositories {
maven { url "${urlTalsecPlugin}" }
}
dependencies {
classpath("${talsecPluginArtifact}")
}
}
`;

return buildGradle + `\n${talsecBuildscript}\n`;
};

const setTalsecAppPlugin = (appBuildGradle: string) => {
if (appBuildGradle.includes(talsecPluginId)) {
return appBuildGradle;
}

return appBuildGradle + `\napply plugin: "${talsecPluginId}"\n`;
};

const withTalsecGradlePlugin: ConfigPlugin = (expoConfig) => {
return withProjectBuildGradle(expoConfig, (config) => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setTalsecGradlePlugin(
config.modResults.contents
);
} else {
WarningAggregator.addWarningAndroid(
'freerasp-react-native',
`Cannot automatically configure project build.gradle, because it's not groovy`
);
}
return config;
});
};

const withTalsecAppPlugin: ConfigPlugin = (expoConfig) => {
return withAppBuildGradle(expoConfig, (config) => {
if (config.modResults.language === 'groovy') {
config.modResults.contents = setTalsecAppPlugin(
config.modResults.contents
);
} else {
WarningAggregator.addWarningAndroid(
'freerasp-react-native',
`Cannot automatically configure app build.gradle, because it's not groovy`
);
}
return config;
});
};

const withFreeraspIosFrameworks = (
config: ExpoConfig,
spmEnabled: boolean
Expand Down Expand Up @@ -159,6 +224,8 @@ const withRnTalsecIos: ConfigPlugin<PluginConfigType> = (config, props) => {

const withRnTalsecApp: ConfigPlugin<PluginConfigType> = (config, props) => {
config = withBuildscriptDependency(config);
config = withTalsecGradlePlugin(config);
config = withTalsecAppPlugin(config);
config = withAndroidMinSdkVersion(config, props);
config = withAndroidR8Version(config, props);
config = withRnTalsecIos(config, props);
Expand Down
Loading