react-native-intune 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +27 -0
- package/NOTICE +49 -0
- package/README.md +164 -0
- package/RNIntune.podspec +69 -0
- package/android/build.gradle +152 -0
- package/android/consumer-rules.pro +28 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneAuth.kt +330 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneAuthCallback.kt +195 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneConfig.kt +63 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneEventQueue.kt +50 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneModule.kt +752 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneMsalConfig.kt +78 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneNotifications.kt +187 -0
- package/android/src/main/java/com/reactnativeintune/RNIntunePackage.kt +33 -0
- package/android/src/main/java/com/reactnativeintune/RNIntunePolicy.kt +108 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneReset.kt +85 -0
- package/android/src/main/java/com/reactnativeintune/RNIntuneResetJournal.kt +140 -0
- package/app.plugin.js +10 -0
- package/ios/RNIntune.h +20 -0
- package/ios/RNIntune.mm +467 -0
- package/ios/RNIntuneAuth.h +121 -0
- package/ios/RNIntuneAuth.m +390 -0
- package/ios/RNIntuneCore.h +150 -0
- package/ios/RNIntuneCore.m +535 -0
- package/ios/RNIntuneDelegates.h +70 -0
- package/ios/RNIntuneDelegates.m +268 -0
- package/ios/RNIntunePendingRequests.h +57 -0
- package/ios/RNIntunePendingRequests.m +230 -0
- package/ios/RNIntunePlistGuard.h +37 -0
- package/ios/RNIntunePlistGuard.m +147 -0
- package/ios/RNIntunePolicy.h +25 -0
- package/ios/RNIntunePolicy.m +112 -0
- package/ios/RNIntuneReset.h +34 -0
- package/ios/RNIntuneReset.m +93 -0
- package/ios/RNIntuneResetJournal.h +69 -0
- package/ios/RNIntuneResetJournal.m +106 -0
- package/lib/module/NativeIntune.js +20 -0
- package/lib/module/NativeIntune.js.map +1 -0
- package/lib/module/api/auth.js +66 -0
- package/lib/module/api/auth.js.map +1 -0
- package/lib/module/api/enrollment.js +104 -0
- package/lib/module/api/enrollment.js.map +1 -0
- package/lib/module/api/events.js +50 -0
- package/lib/module/api/events.js.map +1 -0
- package/lib/module/api/lifecycle.js +73 -0
- package/lib/module/api/lifecycle.js.map +1 -0
- package/lib/module/api/policy.js +23 -0
- package/lib/module/api/policy.js.map +1 -0
- package/lib/module/api/tokenProvider.js +80 -0
- package/lib/module/api/tokenProvider.js.map +1 -0
- package/lib/module/index.js +82 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/internal/decode.js +153 -0
- package/lib/module/internal/decode.js.map +1 -0
- package/lib/module/internal/emitter.js +15 -0
- package/lib/module/internal/emitter.js.map +1 -0
- package/lib/module/internal/errors.js +32 -0
- package/lib/module/internal/errors.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +143 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeIntune.d.ts +120 -0
- package/lib/typescript/src/NativeIntune.d.ts.map +1 -0
- package/lib/typescript/src/api/auth.d.ts +37 -0
- package/lib/typescript/src/api/auth.d.ts.map +1 -0
- package/lib/typescript/src/api/enrollment.d.ts +54 -0
- package/lib/typescript/src/api/enrollment.d.ts.map +1 -0
- package/lib/typescript/src/api/events.d.ts +24 -0
- package/lib/typescript/src/api/events.d.ts.map +1 -0
- package/lib/typescript/src/api/lifecycle.d.ts +33 -0
- package/lib/typescript/src/api/lifecycle.d.ts.map +1 -0
- package/lib/typescript/src/api/policy.d.ts +14 -0
- package/lib/typescript/src/api/policy.d.ts.map +1 -0
- package/lib/typescript/src/api/tokenProvider.d.ts +18 -0
- package/lib/typescript/src/api/tokenProvider.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +67 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/internal/decode.d.ts +48 -0
- package/lib/typescript/src/internal/decode.d.ts.map +1 -0
- package/lib/typescript/src/internal/emitter.d.ts +11 -0
- package/lib/typescript/src/internal/emitter.d.ts.map +1 -0
- package/lib/typescript/src/internal/errors.d.ts +22 -0
- package/lib/typescript/src/internal/errors.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +317 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +204 -0
- package/plugin/transforms.js +153 -0
- package/plugin/withIntune.js +320 -0
- package/scripts/cli.mjs +72 -0
- package/scripts/doctor.mjs +232 -0
- package/scripts/fetch-sdks.mjs +456 -0
- package/scripts/lib/checks.mjs +720 -0
- package/scripts/lib/project.mjs +196 -0
- package/scripts/setup.mjs +233 -0
- package/sdk-lock.json +27 -0
- package/sdk-versions.json +70 -0
- package/src/NativeIntune.ts +130 -0
- package/src/api/auth.ts +73 -0
- package/src/api/enrollment.ts +112 -0
- package/src/api/events.ts +87 -0
- package/src/api/lifecycle.ts +75 -0
- package/src/api/policy.ts +22 -0
- package/src/api/tokenProvider.ts +80 -0
- package/src/index.ts +127 -0
- package/src/internal/decode.ts +191 -0
- package/src/internal/emitter.ts +14 -0
- package/src/internal/errors.ts +43 -0
- package/src/types.ts +381 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Artashes Bayazetyan and react-native-intune contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This licence covers the code in this repository only. It does not cover the
|
|
26
|
+
Microsoft Intune App SDK, which this project wraps and does not include. See
|
|
27
|
+
NOTICE for what belongs to Microsoft and under which terms.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# NOTICE
|
|
2
|
+
|
|
3
|
+
`react-native-intune` is MIT licensed (see LICENSE) and covers **only the code in this
|
|
4
|
+
repository**. It wraps Microsoft software that it neither includes nor relicenses.
|
|
5
|
+
|
|
6
|
+
## The Microsoft Intune App SDK is not part of this package
|
|
7
|
+
|
|
8
|
+
The SDK is Microsoft's, distributed under Microsoft's own licence terms, and is **not
|
|
9
|
+
included in this repository or in the published npm tarball**.
|
|
10
|
+
|
|
11
|
+
`vendor/` is gitignored and excluded from `package.json`'s `files`. `scripts/fetch-sdks.mjs`
|
|
12
|
+
downloads the pinned version at install time, from Microsoft's own releases, verifying a
|
|
13
|
+
recorded sha256 per artifact. Nothing about that arrangement grants anyone rights they did
|
|
14
|
+
not already have from Microsoft.
|
|
15
|
+
|
|
16
|
+
Using this package therefore means accepting Microsoft's terms for the SDK. They arrive
|
|
17
|
+
alongside the download:
|
|
18
|
+
|
|
19
|
+
| File | What it covers |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `vendor/ios/Microsoft License Terms Intune App SDK for iOS.pdf` | the iOS SDK |
|
|
22
|
+
| `vendor/android/Microsoft License Terms Intune App SDK for Android.pdf` | the Android SDK |
|
|
23
|
+
| `vendor/ios/REDIST.txt` | which iOS binaries may be redistributed in *your* app |
|
|
24
|
+
| `vendor/ios/ThirdPartyNotices.txt` | the SDK's own third-party attributions |
|
|
25
|
+
|
|
26
|
+
Read `REDIST.txt` before shipping: it names the frameworks you are permitted to
|
|
27
|
+
redistribute inside an application, which is a narrower permission than redistributing the
|
|
28
|
+
SDK itself. This project relies on that permission and does not extend it.
|
|
29
|
+
|
|
30
|
+
## Microsoft Authentication Library (MSAL)
|
|
31
|
+
|
|
32
|
+
MSAL is a declared dependency rather than a vendored one — the pod on iOS, the Gradle
|
|
33
|
+
artifact on Android — and is fetched from public registries in the normal way. It is
|
|
34
|
+
Microsoft's, under the MIT licence, Copyright (c) Microsoft Corporation.
|
|
35
|
+
|
|
36
|
+
The version is pinned in `sdk-versions.json`. The reason is in SPEC §3.1: the Intune SDK
|
|
37
|
+
does not carry its own MSAL, it drives the application's, so two MSAL versions in one
|
|
38
|
+
binary is a failure nobody debugs quickly.
|
|
39
|
+
|
|
40
|
+
## Trademarks
|
|
41
|
+
|
|
42
|
+
Microsoft, Intune, Microsoft Entra, Microsoft 365 and Azure are trademarks of the
|
|
43
|
+
Microsoft group of companies. They appear here only to describe what this package
|
|
44
|
+
integrates with.
|
|
45
|
+
|
|
46
|
+
**This project is not affiliated with, endorsed by, or supported by Microsoft.** Microsoft
|
|
47
|
+
publishes no React Native support for the Intune App SDK, which is why this package exists
|
|
48
|
+
and why a meaningful part of its behaviour was established by reading the SDK's own headers
|
|
49
|
+
and running it on real devices rather than from documentation.
|
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# react-native-intune
|
|
2
|
+
|
|
3
|
+
Microsoft Intune app protection for React Native — **app-level data protection, not device
|
|
4
|
+
management.** MSAL with broker support is included, so sign-in and enrollment work without
|
|
5
|
+
a second SDK.
|
|
6
|
+
|
|
7
|
+
**[Documentation](https://bayazetyan.github.io/react-native-intune/)** ·
|
|
8
|
+
[Getting started](https://bayazetyan.github.io/react-native-intune/docs/getting-started) ·
|
|
9
|
+
[Traps](https://bayazetyan.github.io/react-native-intune/docs/notes/traps) ·
|
|
10
|
+
[API reference](https://bayazetyan.github.io/react-native-intune/docs/reference)
|
|
11
|
+
|
|
12
|
+
> **Status: pre-alpha.** Implemented and verified on real devices against a real tenant,
|
|
13
|
+
> but not released. Expect breaking changes until 1.0.
|
|
14
|
+
|
|
15
|
+
*Not affiliated with, endorsed by, or sponsored by Microsoft. Microsoft, Intune and Entra
|
|
16
|
+
are trademarks of the Microsoft group of companies.*
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
An IT administrator in any customer tenant can target your app from their Intune console
|
|
21
|
+
and enforce an App Protection Policy on it: a PIN or biometric unlock, copy-paste
|
|
22
|
+
restrictions between managed and unmanaged apps, screenshot blocking, save-as and open-from
|
|
23
|
+
restrictions, encryption at rest, conditional launch rules, and a selective wipe that
|
|
24
|
+
removes corporate data and leaves personal data alone.
|
|
25
|
+
|
|
26
|
+
**The device does not need to be enrolled in Intune.** That is the point of MAM — the
|
|
27
|
+
boundary is drawn around one app, and the employee's phone stays theirs.
|
|
28
|
+
|
|
29
|
+
## What it is not
|
|
30
|
+
|
|
31
|
+
It cannot do device management, and no configuration changes that: the SDK runs inside your
|
|
32
|
+
app's sandbox.
|
|
33
|
+
|
|
34
|
+
| | |
|
|
35
|
+
|---|---|
|
|
36
|
+
| App-level PIN, copy-paste, screenshots, selective wipe | ✅ This library |
|
|
37
|
+
| Full device wipe, device passcode, disk encryption | ❌ The customer's MDM |
|
|
38
|
+
| Per-app VPN, network inspection, kiosk mode, inventory | ❌ The customer's MDM |
|
|
39
|
+
|
|
40
|
+
If someone asks whether this gives them "Intune device control", the answer is no. It makes
|
|
41
|
+
your app a first-class Intune-managed app; their MDM handles the device.
|
|
42
|
+
|
|
43
|
+
## Licensing — read before installing
|
|
44
|
+
|
|
45
|
+
**This library is MIT. The Microsoft Intune App SDK is not, and is not included here.**
|
|
46
|
+
|
|
47
|
+
The SDK is downloaded from Microsoft's own repositories by `fetch-sdks`. It is never
|
|
48
|
+
committed to this repository and never published in the npm package. Microsoft's terms
|
|
49
|
+
apply to it, they are separate from ours, and **reviewing and accepting them is your
|
|
50
|
+
responsibility**:
|
|
51
|
+
|
|
52
|
+
- [Intune App SDK for iOS](https://github.com/msintuneappsdk/ms-intune-app-sdk-ios)
|
|
53
|
+
- [Intune App SDK for Android](https://github.com/microsoftconnect/ms-intune-app-sdk-android)
|
|
54
|
+
|
|
55
|
+
[`NOTICE`](./NOTICE) is the full statement.
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
| | |
|
|
60
|
+
|---|---|
|
|
61
|
+
| React Native | 0.74+, **New Architecture required** |
|
|
62
|
+
| iOS | **17.0+, Xcode 26+** — MAM SDK 21.x is built against them |
|
|
63
|
+
| Android | minSdk 24, Java 17, Gradle 8.11.1 / AGP 8.9.1 / Kotlin 2.1.21 |
|
|
64
|
+
| On the device | Company Portal on Android; Authenticator or Company Portal on iOS |
|
|
65
|
+
| In the tenant | An Entra app registration with the Intune MAM API permission granted |
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm install react-native-intune
|
|
71
|
+
npx react-native-intune fetch-sdks # accepts Microsoft's terms, downloads the SDKs
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Installing the package is the short part. **Most of this integration is changes to your own
|
|
75
|
+
app project** — `Info.plist`, entitlements, `AndroidManifest.xml`, your app module's
|
|
76
|
+
`build.gradle`, your `Application` class — and autolinking does not touch any of them.
|
|
77
|
+
|
|
78
|
+
**Expo:** add the config plugin and run `expo prebuild`. Nearly everything is applied for
|
|
79
|
+
you, including the `MAMApplication` change.
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{ "expo": { "plugins": [["react-native-intune", { "androidSignatureHash": "…" }]] } }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Bare React Native:** two commands, then a short manual remainder.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx react-native-intune doctor # reports what is missing, changes nothing
|
|
89
|
+
npx react-native-intune setup # applies what it can, shows a diff first
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Then follow [iOS setup](https://bayazetyan.github.io/react-native-intune/docs/setup/ios) or
|
|
93
|
+
[Android setup](https://bayazetyan.github.io/react-native-intune/docs/setup/android).
|
|
94
|
+
|
|
95
|
+
> **Three of those steps fail silently when missed** — the app builds, runs, and protects
|
|
96
|
+
> nothing while everyone believes protection is in place. The setup guides mark which, and
|
|
97
|
+
> `doctor` finds them.
|
|
98
|
+
|
|
99
|
+
## Quick start
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import Intune, { EnrollmentStatus } from 'react-native-intune';
|
|
103
|
+
|
|
104
|
+
// Per-tenant, from your own backend — one build serves many customers.
|
|
105
|
+
await Intune.configure({
|
|
106
|
+
clientId: cfg.aadClientId,
|
|
107
|
+
tenantId: cfg.aadTenantId,
|
|
108
|
+
authority: cfg.aadAuthority,
|
|
109
|
+
redirectUri: cfg.aadRedirectUri,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const { enrollment } = await Intune.signInAndEnroll();
|
|
113
|
+
|
|
114
|
+
// Only 'failed' means block.
|
|
115
|
+
if (enrollment.status === EnrollmentStatus.Failed) {
|
|
116
|
+
blockCorporateData();
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Enrollment outcomes
|
|
121
|
+
|
|
122
|
+
`enroll()` **resolves** for every outcome — a failure is data, not an exception. It rejects
|
|
123
|
+
only for programming errors.
|
|
124
|
+
|
|
125
|
+
| Status | What your app must do |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `succeeded` | Continue. Policy is in force |
|
|
128
|
+
| `notTargeted` | **Continue.** Nobody has aimed a policy at this app yet |
|
|
129
|
+
| `notLicensed` | **Continue.** The employee has no Intune licence and is still a legitimate employee |
|
|
130
|
+
| `failed` | Block access to corporate data until it succeeds |
|
|
131
|
+
| `pending` · `authorizationNeeded` · `wrongUser` · `companyPortalRequired` | Handle it — see the reference |
|
|
132
|
+
| `unenrolled` · `unenrollmentFailed` · `unknown` | Reset states, and one to treat conservatively |
|
|
133
|
+
|
|
134
|
+
> **The most common integration bug in libraries like this one** is treating anything that
|
|
135
|
+
> is not `succeeded` as "block the user". That breaks every customer with staff who have no
|
|
136
|
+
> Intune licence, and every pilot where the policy has not been targeted yet — while the app
|
|
137
|
+
> reports itself as secure. `notLicensed` and `notTargeted` mean the opposite of `failed`,
|
|
138
|
+
> and that distinction is prescribed by Microsoft rather than invented here.
|
|
139
|
+
|
|
140
|
+
[All eleven outcomes, and what to do with each](https://bayazetyan.github.io/react-native-intune/docs/guides/enrollment-outcomes)
|
|
141
|
+
|
|
142
|
+
## Where the rest is
|
|
143
|
+
|
|
144
|
+
| | |
|
|
145
|
+
|---|---|
|
|
146
|
+
| [Traps and field notes](https://bayazetyan.github.io/react-native-intune/docs/notes/traps) | 23 things that each cost somebody a day and are in no Microsoft documentation |
|
|
147
|
+
| [Authentication](https://bayazetyan.github.io/react-native-intune/docs/guides/authentication) | The broker, MSAL, and using your own instead |
|
|
148
|
+
| [Reconcile at launch](https://bayazetyan.github.io/react-native-intune/docs/guides/reconcile-at-launch) | The pattern to drive enrollment from, and why not from lifecycle hooks |
|
|
149
|
+
| [Reset and wipe](https://bayazetyan.github.io/react-native-intune/docs/guides/reset-and-wipe) | One code path, several callers, and a process that may not survive it |
|
|
150
|
+
| [Troubleshooting](https://bayazetyan.github.io/react-native-intune/docs/troubleshooting) | The seven checks worth doing before opening an issue |
|
|
151
|
+
| [API reference](https://bayazetyan.github.io/react-native-intune/docs/reference) | Generated from the source |
|
|
152
|
+
|
|
153
|
+
## Contributing
|
|
154
|
+
|
|
155
|
+
[How to contribute](https://bayazetyan.github.io/react-native-intune/docs/contributing/).
|
|
156
|
+
In short: nothing builds until you accept Microsoft's terms and run `fetch-sdks`, `vendor/`
|
|
157
|
+
is never committed, and a pull request touching native code states which platform was
|
|
158
|
+
actually run, on which device, against which tenant. Enrollment paths cannot be verified by
|
|
159
|
+
unit tests and CI does not pretend otherwise.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT — see [`LICENSE`](./LICENSE). It covers this library's code and not the Microsoft Intune
|
|
164
|
+
App SDK; [`NOTICE`](./NOTICE) says what belongs to whom.
|
package/RNIntune.podspec
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
# The Microsoft SDKs are fetched, never committed (SPEC §2.1). Fail here with an
|
|
6
|
+
# instruction rather than letting the linker fail 200 lines deep.
|
|
7
|
+
vendor_ios = File.join(__dir__, "vendor", "ios")
|
|
8
|
+
unless File.directory?(vendor_ios) && !Dir.glob(File.join(vendor_ios, "*.xcframework")).empty?
|
|
9
|
+
raise "[react-native-intune] The Microsoft Intune App SDK is missing from vendor/ios. " \
|
|
10
|
+
"Run `yarn fetch-sdks` (or `node node_modules/react-native-intune/scripts/fetch-sdks.mjs`) " \
|
|
11
|
+
"and then `pod install` again."
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Pod::Spec.new do |s|
|
|
15
|
+
s.name = "RNIntune"
|
|
16
|
+
s.version = package["version"]
|
|
17
|
+
s.summary = package["description"]
|
|
18
|
+
s.homepage = package["homepage"]
|
|
19
|
+
s.license = package["license"]
|
|
20
|
+
s.authors = package["author"]
|
|
21
|
+
|
|
22
|
+
# Deliberately NOT min_ios_version_supported. Intune App SDK 21.8.0 is built with
|
|
23
|
+
# `minos 17.0` (verified with otool on IntuneMAMSwift.framework), so a host app on
|
|
24
|
+
# React Native's floor of 15.1 cannot link it. Supporting iOS 16 means pinning SDK
|
|
25
|
+
# 20.x, which Microsoft maintains for high-priority security fixes only.
|
|
26
|
+
s.platforms = { :ios => "17.0" }
|
|
27
|
+
s.source = { :git => "https://github.com/bayazetyan/react-native-intune.git", :tag => "#{s.version}" }
|
|
28
|
+
|
|
29
|
+
# No .swift and no .cpp on purpose — see SPEC §5.1.1 for the language split.
|
|
30
|
+
s.source_files = "ios/**/*.{h,m,mm}"
|
|
31
|
+
s.private_header_files = "ios/**/*.h"
|
|
32
|
+
|
|
33
|
+
# IntuneMAMTelemetry is a separate product in 21.x and must be linked explicitly.
|
|
34
|
+
s.vendored_frameworks = [
|
|
35
|
+
"vendor/ios/IntuneMAMSwift.xcframework",
|
|
36
|
+
"vendor/ios/IntuneMAMSwiftStub.xcframework",
|
|
37
|
+
"vendor/ios/IntuneMAMTelemetry.xcframework"
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
# Not optional. Carries PinViewController, the blur/policy/diagnostics/MTD-compliance
|
|
41
|
+
# screens and 28 localizations. Without it the SDK's UI cannot render — and that
|
|
42
|
+
# failure shows up at runtime, not at build time.
|
|
43
|
+
s.resources = ["vendor/ios/IntuneMAMResources.bundle"]
|
|
44
|
+
|
|
45
|
+
# Keeps IntuneMAMConfigurator (and Microsoft's licence files) in the installed pod so
|
|
46
|
+
# the consumer can call the configurator from an Xcode build phase.
|
|
47
|
+
s.preserve_paths = "vendor/**/*"
|
|
48
|
+
|
|
49
|
+
s.frameworks = "MessageUI", "Security", "CoreServices", "SystemConfiguration",
|
|
50
|
+
"ImageIO", "LocalAuthentication", "AudioToolbox", "QuartzCore",
|
|
51
|
+
"WebKit", "MetricKit"
|
|
52
|
+
s.libraries = "sqlite3", "c++"
|
|
53
|
+
|
|
54
|
+
# Required, and not only by our own auth layer. The Intune SDK does not carry its own
|
|
55
|
+
# MSAL — it drives the app's. Without this pod even loginAndEnrollAccount:, where the
|
|
56
|
+
# SDK runs the whole sign-in itself, fails with "Failed to instantiate MSALAuthority /
|
|
57
|
+
# Ensure the appropriate version of ADAL is included in the application" (observed on
|
|
58
|
+
# device, 2026-09-04). Version pinned in sdk-versions.json -> toolchain.msal_ios.
|
|
59
|
+
s.dependency "MSAL", "2.15.0"
|
|
60
|
+
|
|
61
|
+
s.pod_target_xcconfig = {
|
|
62
|
+
"STRIP_SWIFT_SYMBOLS" => "NO",
|
|
63
|
+
"ENABLE_BITCODE" => "NO"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# RN 0.74+ helper: wires Codegen and the New Architecture dependencies. Do not
|
|
67
|
+
# hand-roll React-Core / folly deps or RCT_NEW_ARCH_ENABLED flags.
|
|
68
|
+
install_modules_dependencies(s)
|
|
69
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
// The MAM SDK compatibility matrix (SPEC §6.1) is tested as whole rows, not as a
|
|
3
|
+
// mix. The pinned Android tag in sdk-lock.json is 12.4.0, so this is the 12.0.0
|
|
4
|
+
// row: Android 16 (compileSdk 36), Gradle 8.11.1, AGP 8.9.1, Kotlin 2.1.21, Java 17.
|
|
5
|
+
// Mirrored in sdk-versions.json -> toolchain.requires; change both together.
|
|
6
|
+
ext.Intune = [
|
|
7
|
+
kotlinVersion: "2.1.21",
|
|
8
|
+
minSdkVersion: 24,
|
|
9
|
+
compileSdkVersion: 36
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
ext.getExtOrDefault = { prop ->
|
|
13
|
+
if (rootProject.ext.has(prop)) {
|
|
14
|
+
return rootProject.ext.get(prop)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return Intune[prop]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
repositories {
|
|
21
|
+
google()
|
|
22
|
+
// Not jcenter(), which Microsoft's docs still reference — it is read-only/retired.
|
|
23
|
+
mavenCentral()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
dependencies {
|
|
27
|
+
classpath "com.android.tools.build:gradle:8.9.1"
|
|
28
|
+
// noinspection DifferentKotlinGradleVersion
|
|
29
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
apply plugin: "com.android.library"
|
|
35
|
+
apply plugin: "kotlin-android"
|
|
36
|
+
|
|
37
|
+
apply plugin: "com.facebook.react"
|
|
38
|
+
|
|
39
|
+
// The MAM Gradle plugin ("com.microsoft.intune.mam") is deliberately NOT applied here.
|
|
40
|
+
// It rewrites bytecode across the whole application and every one of its dependencies,
|
|
41
|
+
// so it belongs in the consumer's app module. Applying it in this library would rewrite
|
|
42
|
+
// only the library, build successfully, and protect nothing — the worst kind of failure.
|
|
43
|
+
|
|
44
|
+
android {
|
|
45
|
+
namespace "com.reactnativeintune"
|
|
46
|
+
|
|
47
|
+
compileSdkVersion getExtOrDefault("compileSdkVersion")
|
|
48
|
+
|
|
49
|
+
defaultConfig {
|
|
50
|
+
minSdkVersion getExtOrDefault("minSdkVersion")
|
|
51
|
+
|
|
52
|
+
// Shipped to consumers, because a release build with R8 fails without them and only
|
|
53
|
+
// a release build does — debug and unminified release both succeed, so an app finds
|
|
54
|
+
// out when it ships. See the file for what each rule is for.
|
|
55
|
+
consumerProguardFiles "consumer-rules.pro"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
compileOptions {
|
|
59
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
60
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
kotlinOptions {
|
|
64
|
+
jvmTarget = "17"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Fetched by scripts/fetch-sdks.mjs into a gitignored vendor/ (SPEC §2.1).
|
|
69
|
+
//
|
|
70
|
+
// Resolved from projectDir, NOT rootDir. SPEC §12.3 and TODO.md both write
|
|
71
|
+
// "$rootDir/../vendor/...", but when this library is autolinked, rootDir is the
|
|
72
|
+
// *consumer app's* android/ directory — that path would point at <app>/vendor and
|
|
73
|
+
// never resolve. projectDir is this library's own android/ folder, so ../vendor is
|
|
74
|
+
// the package root where fetch-sdks writes.
|
|
75
|
+
def mamAar = file("$projectDir/../vendor/android/Microsoft.Intune.MAM.SDK.aar")
|
|
76
|
+
|
|
77
|
+
// Parallel to the raise in RNIntune.podspec: fail with an instruction rather than an
|
|
78
|
+
// unresolved-symbol error deep in the Kotlin compile. Scoped to graphs that actually
|
|
79
|
+
// compile this library, so `clean` and unrelated tasks are not blocked by a missing
|
|
80
|
+
// download.
|
|
81
|
+
gradle.taskGraph.whenReady { graph ->
|
|
82
|
+
if (mamAar.exists()) return
|
|
83
|
+
def compiling = graph.allTasks.any {
|
|
84
|
+
it.project == project && it.name.startsWith("compile")
|
|
85
|
+
}
|
|
86
|
+
if (compiling) {
|
|
87
|
+
throw new GradleException(
|
|
88
|
+
"[react-native-intune] The Microsoft Intune App SDK is missing from vendor/android.\n" +
|
|
89
|
+
" Expected: ${mamAar}\n" +
|
|
90
|
+
" Run: node node_modules/react-native-intune/scripts/fetch-sdks.mjs"
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Disable AAR packaging for this library, with a message that says why.
|
|
97
|
+
*
|
|
98
|
+
* `./gradlew assembleDebug` from a consumer's android/ directory assembles every module,
|
|
99
|
+
* including this one, and `:react-native-intune:bundleDebugAar` then fails with "Direct
|
|
100
|
+
* local .aar file dependencies are not supported when building an AAR". People run that
|
|
101
|
+
* command, and the error names our library, so it reads as our bug.
|
|
102
|
+
*
|
|
103
|
+
* It is not a workaround for a problem we could otherwise solve. AGP's own message says
|
|
104
|
+
* the AAR "would be broken because the classes and Android resources from any local .aar
|
|
105
|
+
* file dependencies would not be packaged" — so the output being skipped is an output
|
|
106
|
+
* that could never have been correct. The MAM SDK is distributed as a file from
|
|
107
|
+
* Microsoft's GitHub, not from Maven Central, so there is no coordinate to depend on
|
|
108
|
+
* instead.
|
|
109
|
+
*
|
|
110
|
+
* Nothing is lost: autolinking consumes this library as a Gradle *project*, so its AAR is
|
|
111
|
+
* never built for a consumer. `:app:assembleDebug` was always the working form; now the
|
|
112
|
+
* root form works too.
|
|
113
|
+
*/
|
|
114
|
+
tasks.configureEach { task ->
|
|
115
|
+
if (task.name ==~ /bundle.*Aar/) {
|
|
116
|
+
task.enabled = false
|
|
117
|
+
task.doFirst {
|
|
118
|
+
logger.lifecycle(
|
|
119
|
+
"[react-native-intune] Skipping ${task.name}: this library depends on the MAM " +
|
|
120
|
+
"SDK as a local .aar, so AGP cannot package a valid AAR for it. Consumers " +
|
|
121
|
+
"autolink it as a Gradle project and never need one."
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
dependencies {
|
|
128
|
+
implementation "com.facebook.react:react-android"
|
|
129
|
+
|
|
130
|
+
implementation files(mamAar)
|
|
131
|
+
|
|
132
|
+
// MSAL. Mirrored in sdk-versions.json -> toolchain.msal_android; change both together.
|
|
133
|
+
//
|
|
134
|
+
// Unlike iOS, Microsoft states no required version for Android — the SDK guide says
|
|
135
|
+
// only "integrate MSAL". So this pin is ours, for reproducibility rather than
|
|
136
|
+
// compatibility, and it is exact for the same reason the iOS one is: two MSAL versions
|
|
137
|
+
// in one binary is a failure mode nobody debugs quickly.
|
|
138
|
+
//
|
|
139
|
+
// mavenCentral, never jcenter — Microsoft's own docs still say jcenter in places and it
|
|
140
|
+
// has been read-only for years (CLAUDE.md, Android gotchas).
|
|
141
|
+
// `display-mask` is excluded deliberately. MSAL depends on it for dual-screen Surface
|
|
142
|
+
// Duo layout, and it is published only to Microsoft's own Azure DevOps feed, not Maven
|
|
143
|
+
// Central. MSAL's README tells apps to add that feed — but repositories are declared by
|
|
144
|
+
// the *consumer's* settings.gradle, so a library cannot add one, and requiring every
|
|
145
|
+
// consumer to trust an extra feed is a poor trade for dual-screen support.
|
|
146
|
+
//
|
|
147
|
+
// [verify] whether MSAL degrades cleanly without it, or throws at sign-in on a real
|
|
148
|
+
// device. If it throws, the fallback is documenting the feed for consumers.
|
|
149
|
+
implementation("com.microsoft.identity.client:msal:8.4.2") {
|
|
150
|
+
exclude group: "com.microsoft.device.display"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ProGuard/R8 rules shipped to consumers of this library.
|
|
2
|
+
#
|
|
3
|
+
# Wired through `consumerProguardFiles`, so an app that enables minification gets them
|
|
4
|
+
# without having to discover any of this. It shipped broken otherwise: a release build
|
|
5
|
+
# with R8 fails outright, and only a release build — every debug build and the unminified
|
|
6
|
+
# release both succeed, so this is invisible until someone ships.
|
|
7
|
+
#
|
|
8
|
+
# All three entries are `-dontwarn`, not `-keep`. Nothing here is called at runtime on the
|
|
9
|
+
# paths this module uses; the classes are referenced from code branches that never execute,
|
|
10
|
+
# and R8 refuses to finish while it cannot resolve a reference it can see.
|
|
11
|
+
|
|
12
|
+
# `nimbus-jose-jwt`, MSAL's JWT library, has optional support for BouncyCastle and Google
|
|
13
|
+
# Tink and references both unconditionally. Neither is a declared dependency of MSAL, and
|
|
14
|
+
# MSAL's own AAR ships no ProGuard rules at all — verified by unpacking it — so the gap
|
|
15
|
+
# lands on whoever brings MSAL in. That is us.
|
|
16
|
+
-dontwarn org.bouncycastle.**
|
|
17
|
+
-dontwarn com.google.crypto.tink.**
|
|
18
|
+
|
|
19
|
+
# `com.microsoft.device.display:display-mask` is excluded from the MSAL dependency on
|
|
20
|
+
# purpose (SPEC §6.1.2): it is published only to Microsoft's own Azure DevOps feed and a
|
|
21
|
+
# library cannot add a repository on its consumers' behalf. MSAL references it from
|
|
22
|
+
# `DualScreenActivity.getHinge`, for Surface Duo dual-screen layout, which is a path this
|
|
23
|
+
# module never takes.
|
|
24
|
+
#
|
|
25
|
+
# This is the cost of that exclusion, and it only appeared here — sign-in and enrollment
|
|
26
|
+
# both work without the artifact, so the `[verify]` note in §6.1.2 was answered by a
|
|
27
|
+
# release build rather than by a device.
|
|
28
|
+
-dontwarn com.microsoft.device.display.**
|