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.
Files changed (110) hide show
  1. package/LICENSE +27 -0
  2. package/NOTICE +49 -0
  3. package/README.md +164 -0
  4. package/RNIntune.podspec +69 -0
  5. package/android/build.gradle +152 -0
  6. package/android/consumer-rules.pro +28 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/java/com/reactnativeintune/RNIntuneAuth.kt +330 -0
  9. package/android/src/main/java/com/reactnativeintune/RNIntuneAuthCallback.kt +195 -0
  10. package/android/src/main/java/com/reactnativeintune/RNIntuneConfig.kt +63 -0
  11. package/android/src/main/java/com/reactnativeintune/RNIntuneEventQueue.kt +50 -0
  12. package/android/src/main/java/com/reactnativeintune/RNIntuneModule.kt +752 -0
  13. package/android/src/main/java/com/reactnativeintune/RNIntuneMsalConfig.kt +78 -0
  14. package/android/src/main/java/com/reactnativeintune/RNIntuneNotifications.kt +187 -0
  15. package/android/src/main/java/com/reactnativeintune/RNIntunePackage.kt +33 -0
  16. package/android/src/main/java/com/reactnativeintune/RNIntunePolicy.kt +108 -0
  17. package/android/src/main/java/com/reactnativeintune/RNIntuneReset.kt +85 -0
  18. package/android/src/main/java/com/reactnativeintune/RNIntuneResetJournal.kt +140 -0
  19. package/app.plugin.js +10 -0
  20. package/ios/RNIntune.h +20 -0
  21. package/ios/RNIntune.mm +467 -0
  22. package/ios/RNIntuneAuth.h +121 -0
  23. package/ios/RNIntuneAuth.m +390 -0
  24. package/ios/RNIntuneCore.h +150 -0
  25. package/ios/RNIntuneCore.m +535 -0
  26. package/ios/RNIntuneDelegates.h +70 -0
  27. package/ios/RNIntuneDelegates.m +268 -0
  28. package/ios/RNIntunePendingRequests.h +57 -0
  29. package/ios/RNIntunePendingRequests.m +230 -0
  30. package/ios/RNIntunePlistGuard.h +37 -0
  31. package/ios/RNIntunePlistGuard.m +147 -0
  32. package/ios/RNIntunePolicy.h +25 -0
  33. package/ios/RNIntunePolicy.m +112 -0
  34. package/ios/RNIntuneReset.h +34 -0
  35. package/ios/RNIntuneReset.m +93 -0
  36. package/ios/RNIntuneResetJournal.h +69 -0
  37. package/ios/RNIntuneResetJournal.m +106 -0
  38. package/lib/module/NativeIntune.js +20 -0
  39. package/lib/module/NativeIntune.js.map +1 -0
  40. package/lib/module/api/auth.js +66 -0
  41. package/lib/module/api/auth.js.map +1 -0
  42. package/lib/module/api/enrollment.js +104 -0
  43. package/lib/module/api/enrollment.js.map +1 -0
  44. package/lib/module/api/events.js +50 -0
  45. package/lib/module/api/events.js.map +1 -0
  46. package/lib/module/api/lifecycle.js +73 -0
  47. package/lib/module/api/lifecycle.js.map +1 -0
  48. package/lib/module/api/policy.js +23 -0
  49. package/lib/module/api/policy.js.map +1 -0
  50. package/lib/module/api/tokenProvider.js +80 -0
  51. package/lib/module/api/tokenProvider.js.map +1 -0
  52. package/lib/module/index.js +82 -0
  53. package/lib/module/index.js.map +1 -0
  54. package/lib/module/internal/decode.js +153 -0
  55. package/lib/module/internal/decode.js.map +1 -0
  56. package/lib/module/internal/emitter.js +15 -0
  57. package/lib/module/internal/emitter.js.map +1 -0
  58. package/lib/module/internal/errors.js +32 -0
  59. package/lib/module/internal/errors.js.map +1 -0
  60. package/lib/module/package.json +1 -0
  61. package/lib/module/types.js +143 -0
  62. package/lib/module/types.js.map +1 -0
  63. package/lib/typescript/package.json +1 -0
  64. package/lib/typescript/src/NativeIntune.d.ts +120 -0
  65. package/lib/typescript/src/NativeIntune.d.ts.map +1 -0
  66. package/lib/typescript/src/api/auth.d.ts +37 -0
  67. package/lib/typescript/src/api/auth.d.ts.map +1 -0
  68. package/lib/typescript/src/api/enrollment.d.ts +54 -0
  69. package/lib/typescript/src/api/enrollment.d.ts.map +1 -0
  70. package/lib/typescript/src/api/events.d.ts +24 -0
  71. package/lib/typescript/src/api/events.d.ts.map +1 -0
  72. package/lib/typescript/src/api/lifecycle.d.ts +33 -0
  73. package/lib/typescript/src/api/lifecycle.d.ts.map +1 -0
  74. package/lib/typescript/src/api/policy.d.ts +14 -0
  75. package/lib/typescript/src/api/policy.d.ts.map +1 -0
  76. package/lib/typescript/src/api/tokenProvider.d.ts +18 -0
  77. package/lib/typescript/src/api/tokenProvider.d.ts.map +1 -0
  78. package/lib/typescript/src/index.d.ts +67 -0
  79. package/lib/typescript/src/index.d.ts.map +1 -0
  80. package/lib/typescript/src/internal/decode.d.ts +48 -0
  81. package/lib/typescript/src/internal/decode.d.ts.map +1 -0
  82. package/lib/typescript/src/internal/emitter.d.ts +11 -0
  83. package/lib/typescript/src/internal/emitter.d.ts.map +1 -0
  84. package/lib/typescript/src/internal/errors.d.ts +22 -0
  85. package/lib/typescript/src/internal/errors.d.ts.map +1 -0
  86. package/lib/typescript/src/types.d.ts +317 -0
  87. package/lib/typescript/src/types.d.ts.map +1 -0
  88. package/package.json +204 -0
  89. package/plugin/transforms.js +153 -0
  90. package/plugin/withIntune.js +320 -0
  91. package/scripts/cli.mjs +72 -0
  92. package/scripts/doctor.mjs +232 -0
  93. package/scripts/fetch-sdks.mjs +456 -0
  94. package/scripts/lib/checks.mjs +720 -0
  95. package/scripts/lib/project.mjs +196 -0
  96. package/scripts/setup.mjs +233 -0
  97. package/sdk-lock.json +27 -0
  98. package/sdk-versions.json +70 -0
  99. package/src/NativeIntune.ts +130 -0
  100. package/src/api/auth.ts +73 -0
  101. package/src/api/enrollment.ts +112 -0
  102. package/src/api/events.ts +87 -0
  103. package/src/api/lifecycle.ts +75 -0
  104. package/src/api/policy.ts +22 -0
  105. package/src/api/tokenProvider.ts +80 -0
  106. package/src/index.ts +127 -0
  107. package/src/internal/decode.ts +191 -0
  108. package/src/internal/emitter.ts +14 -0
  109. package/src/internal/errors.ts +43 -0
  110. package/src/types.ts +381 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Sign-in, for `authMode: 'builtin'` — the module owns MSAL (SPEC §3).
3
+ *
4
+ * Two tokens exist and only one of them appears here: the MAM service token is acquired
5
+ * internally and never crosses the bridge. Everything returned by these calls is for
6
+ * *your* API's scopes (SPEC §3.5).
7
+ */
8
+
9
+ import NativeIntune from '../NativeIntune';
10
+ import { assertAccountId } from '../internal/errors';
11
+ import { toAuthAccount, toAuthResult } from '../internal/decode';
12
+ import { enroll } from './enrollment';
13
+ import type {
14
+ AcquireTokenParams,
15
+ AuthAccount,
16
+ AuthResult,
17
+ EnrollmentResult,
18
+ SignInParams,
19
+ SignOutParams,
20
+ } from '../types';
21
+
22
+ /**
23
+ * Uses the broker when one is present, which also gives device-wide SSO: a user already
24
+ * signed into Outlook usually gets a token with no prompt at all.
25
+ */
26
+ export async function signIn(params: SignInParams = {}): Promise<AuthResult> {
27
+ return toAuthResult(await NativeIntune.signIn(params));
28
+ }
29
+
30
+ /**
31
+ * Cache-first. Rejects with `E_INTERACTION_REQUIRED` when a prompt is needed — the normal
32
+ * pattern is `signInSilent` first, `signIn` on that rejection.
33
+ */
34
+ export async function signInSilent(
35
+ params: SignInParams = {}
36
+ ): Promise<AuthResult> {
37
+ return toAuthResult(await NativeIntune.signInSilent(params));
38
+ }
39
+
40
+ /** For your own API's scopes, after sign-in. */
41
+ export async function acquireToken(
42
+ params: AcquireTokenParams
43
+ ): Promise<AuthResult> {
44
+ return toAuthResult(await NativeIntune.acquireToken(params));
45
+ }
46
+
47
+ /**
48
+ * Accounts with cached refresh tokens. Under single identity (SPEC §9) this holds at
49
+ * most one; more than one means state a reset should have cleared.
50
+ */
51
+ export async function getAccounts(): Promise<AuthAccount[]> {
52
+ const accounts = await NativeIntune.getAccounts();
53
+ return accounts.map(toAuthAccount);
54
+ }
55
+
56
+ /**
57
+ * Removes the account from the MSAL cache. With `wipeIntune: true` it also runs the full
58
+ * reset sequence, which is what you want on logout — and which means **the process may
59
+ * terminate during this call on Android.**
60
+ */
61
+ export function signOut(params: SignOutParams): Promise<void> {
62
+ assertAccountId(params.accountId);
63
+ return NativeIntune.signOut(params);
64
+ }
65
+
66
+ /** The common path in one call. Use the primitives when you need a step in between. */
67
+ export async function signInAndEnroll(
68
+ params: SignInParams = {}
69
+ ): Promise<{ auth: AuthResult; enrollment: EnrollmentResult }> {
70
+ const auth = await signIn(params);
71
+ const enrollment = await enroll({ accountId: auth.accountId });
72
+ return { auth, enrollment };
73
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Enrollment, state, and the reset sequence.
3
+ *
4
+ * The theme running through all three: **the SDK reports asynchronously and the process
5
+ * may not survive**. Nothing here resolves from a call returning, and nothing assumes
6
+ * the next line will run.
7
+ */
8
+
9
+ import NativeIntune from '../NativeIntune';
10
+ import { assertAccountId } from '../internal/errors';
11
+ import { toEnrollmentResult, toIntuneState } from '../internal/decode';
12
+ import type {
13
+ EnrollInteractiveParams,
14
+ EnrollmentResult,
15
+ EnrollParams,
16
+ IntuneState,
17
+ ResetHandler,
18
+ ResetParams,
19
+ } from '../types';
20
+
21
+ let resetHandler: ResetHandler | null = null;
22
+
23
+ /**
24
+ * Clears the app's own local data during a reset. The module cannot do this for you — it
25
+ * does not know what you store or where.
26
+ *
27
+ * Registered rather than passed to `reset` because a reset can be *resumed* at launch
28
+ * from the journal, with no `reset` call in flight (SPEC §7).
29
+ */
30
+ export function setResetHandler(handler: ResetHandler | null): void {
31
+ resetHandler = handler;
32
+ }
33
+
34
+ /**
35
+ * Resolves with a result for every outcome including failures — a non-success status is
36
+ * data, not an exception. It only rejects for programming errors.
37
+ *
38
+ * Expect seconds, and a spinner: the promise settles when the SDK reports through its
39
+ * delegate or notification, not when the underlying call returns.
40
+ *
41
+ * Read SPEC §8 before branching on `status`. `NotLicensed` and `NotTargeted` must not
42
+ * block the user; `Failed` must.
43
+ */
44
+ export async function enroll(params: EnrollParams): Promise<EnrollmentResult> {
45
+ assertAccountId(params.accountId);
46
+ return toEnrollmentResult(
47
+ // '' rather than undefined: the Codegen spec has no optionals, so "not known" has to
48
+ // be a value the native side can recognise.
49
+ await NativeIntune.enroll({
50
+ accountId: params.accountId,
51
+ upn: params.upn ?? '',
52
+ })
53
+ );
54
+ }
55
+
56
+ /**
57
+ * **iOS only.** Hands the whole sign-in to the SDK: it shows its own credential screen,
58
+ * signs the user in, and enrolls them. No MSAL on our side, which is why this works
59
+ * before the built-in auth layer exists.
60
+ *
61
+ * Rejects with `E_SDK_UNAVAILABLE` on Android — `registerAccountForMAM` there always
62
+ * needs a token supplied by the app, so there is nothing equivalent to call.
63
+ *
64
+ * Like `enroll`, it resolves with a result for every outcome including failures.
65
+ */
66
+ export async function enrollInteractive(
67
+ params: EnrollInteractiveParams = {}
68
+ ): Promise<EnrollmentResult> {
69
+ return toEnrollmentResult(
70
+ await NativeIntune.enrollInteractive({ upn: params.upn ?? '' })
71
+ );
72
+ }
73
+
74
+ /**
75
+ * The reconciliation primitive, and the intended way to drive this module. Call it at
76
+ * launch, compare against what your backend says the state should be, act on the
77
+ * difference. It never rejects.
78
+ */
79
+ export async function getState(): Promise<IntuneState> {
80
+ return toIntuneState(await NativeIntune.getState());
81
+ }
82
+
83
+ /**
84
+ * Unregisters, unenrolls, optionally wipes corporate data, and clears the runtime
85
+ * configuration.
86
+ *
87
+ * **The process is expected to terminate during this call on Android** (SPEC §7). Do not
88
+ * write code after `await reset(...)` that must run — put the continuation in the
89
+ * launch-time reconciliation and let the journal resume it.
90
+ */
91
+ export async function reset(params: ResetParams): Promise<void> {
92
+ // The order below is SPEC §7's, and it is not the intuitive one. The unregister has to
93
+ // happen before anything purges the account's tokens, and on Android the process is
94
+ // expected to die during it — so local cleanup cannot come first, and cannot be
95
+ // assumed to run at all. The journal carries the sequence across that death: if the
96
+ // native call never returns, the next launch sees `pendingReset` and calls reset()
97
+ // again with reason 'resume', landing back here.
98
+ const state = await getState().catch(() => null);
99
+ const accountId = state?.enrolledAccountId ?? null;
100
+
101
+ await NativeIntune.reset(params);
102
+
103
+ // Reached only if the process survived.
104
+ const handler = resetHandler;
105
+ if (handler !== null) {
106
+ // Deliberately not caught: if the app cannot clear its own data, the journal stays
107
+ // open and the reset is retried next launch rather than being marked done.
108
+ await handler({ reason: params.reason, accountId });
109
+ }
110
+
111
+ await NativeIntune.completeReset();
112
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Typed subscriptions.
3
+ *
4
+ * Every one of these can fire without the app having called anything: the SDK enrolls on
5
+ * its own retry schedule, an administrator can change policy, and a wipe is
6
+ * service-initiated. Subscribe at startup, not when you happen to be waiting (SPEC §4.4).
7
+ */
8
+
9
+ import type { EmitterSubscription } from 'react-native';
10
+
11
+ import { emitter } from '../internal/emitter';
12
+ import {
13
+ nullableStr,
14
+ toBrokerStatus,
15
+ toEnrollmentResult,
16
+ toPolicySnapshot,
17
+ toRestartReason,
18
+ } from '../internal/decode';
19
+ import type {
20
+ BrokerStatus,
21
+ EnrollmentResult,
22
+ IntuneEvents,
23
+ PolicySnapshot,
24
+ RestartRequest,
25
+ } from '../types';
26
+
27
+ function subscribe<K extends keyof IntuneEvents>(
28
+ event: K,
29
+ decode: (raw: object) => IntuneEvents[K],
30
+ listener: (payload: IntuneEvents[K]) => void
31
+ ): EmitterSubscription {
32
+ return emitter.addListener(event, (raw: object) => listener(decode(raw)));
33
+ }
34
+
35
+ /** Also fires for the SDK's own background enrollment retries, which have no caller. */
36
+ export function onEnrollmentResult(
37
+ listener: (result: EnrollmentResult) => void
38
+ ): EmitterSubscription {
39
+ return subscribe('enrollmentResult', toEnrollmentResult, listener);
40
+ }
41
+
42
+ /** The terminal state of a reset. */
43
+ export function onUnenrollmentResult(
44
+ listener: (result: EnrollmentResult) => void
45
+ ): EmitterSubscription {
46
+ return subscribe('unenrollmentResult', toEnrollmentResult, listener);
47
+ }
48
+
49
+ /** An administrator changed policy — re-read whatever UI you gate on it. */
50
+ export function onPolicyChanged(
51
+ listener: (policy: PolicySnapshot) => void
52
+ ): EmitterSubscription {
53
+ return subscribe('policyChanged', toPolicySnapshot, listener);
54
+ }
55
+
56
+ /** The user installed or removed Company Portal. */
57
+ export function onBrokerStatusChanged(
58
+ listener: (status: BrokerStatus) => void
59
+ ): EmitterSubscription {
60
+ return subscribe('brokerStatusChanged', toBrokerStatus, listener);
61
+ }
62
+
63
+ /** **Service-initiated.** Can arrive with no prior app call at all. */
64
+ export function onWipeRequested(
65
+ listener: (request: { accountId: string | null }) => void
66
+ ): EmitterSubscription {
67
+ return subscribe(
68
+ 'wipeRequested',
69
+ (raw) => ({
70
+ accountId: nullableStr((raw as Record<string, unknown>).accountId),
71
+ }),
72
+ listener
73
+ );
74
+ }
75
+
76
+ /** iOS, on first policy application. See `configure({ restartHandledByApp })`. */
77
+ export function onRestartRequired(
78
+ listener: (request: RestartRequest) => void
79
+ ): EmitterSubscription {
80
+ return subscribe(
81
+ 'restartRequired',
82
+ (raw) => ({
83
+ reason: toRestartReason((raw as Record<string, unknown>).reason),
84
+ }),
85
+ listener
86
+ );
87
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Setup, and the two questions worth asking before it: is the SDK usable at all, and is
3
+ * a broker present.
4
+ */
5
+
6
+ import NativeIntune from '../NativeIntune';
7
+ import { toBrokerStatus } from '../internal/decode';
8
+ import {
9
+ FileProtectionLevel,
10
+ type BrokerStatus,
11
+ type IntuneConfig,
12
+ } from '../types';
13
+
14
+ /**
15
+ * Configures the SDK for one customer tenant. Every other method rejects with
16
+ * `E_NOT_CONFIGURED` until this resolves.
17
+ *
18
+ * Two things it will refuse rather than paper over:
19
+ *
20
+ * - a different `tenantId` than the active one — `E_RESET_REQUIRED`, because silently
21
+ * reconfiguring would leave the old tenant enrolled, and the iOS runtime overrides
22
+ * persist across restarts so the mismatch would survive a relaunch;
23
+ * - an `Info.plist` that disagrees with it — `E_PLIST_CONFLICT`, see SPEC §5.1.2.
24
+ */
25
+ export function configure(config: IntuneConfig): Promise<void> {
26
+ // Every optional becomes a concrete value here, so the native side never has to guess
27
+ // a default and the two platforms cannot drift apart on what the default was.
28
+ return NativeIntune.configure({
29
+ clientId: config.clientId,
30
+ tenantId: config.tenantId,
31
+ authority: config.authority,
32
+ redirectUri: config.redirectUri,
33
+ authMode: config.authMode ?? 'builtin',
34
+ verboseLogging: config.verboseLogging ?? false,
35
+ restartHandledByApp: config.restartHandledByApp ?? false,
36
+ maxFileProtectionLevel:
37
+ config.maxFileProtectionLevel ?? FileProtectionLevel.Complete,
38
+ // Throws on integration bugs that would otherwise leave data unprotected, so it is
39
+ // on in development and must never ship enabled.
40
+ strictMode: config.strictMode ?? __DEV__,
41
+ keychainGroupOverride: config.keychainGroupOverride ?? '',
42
+ telemetryEnabled: config.telemetryEnabled ?? true,
43
+ // Flattened because Codegen takes no nested optionals. '' means "leave the SDK's
44
+ // own default alone", which is not the same as a colour.
45
+ brandingBackground: config.branding?.background ?? '',
46
+ brandingForeground: config.branding?.foreground ?? '',
47
+ brandingAccent: config.branding?.accent ?? '',
48
+ brandingSecondaryBackground: config.branding?.secondaryBackground ?? '',
49
+ brandingSecondaryForeground: config.branding?.secondaryForeground ?? '',
50
+ });
51
+ }
52
+
53
+ /**
54
+ * SDK linked and platform prerequisites met. Gate the whole Intune path on this so a
55
+ * misbuilt binary degrades instead of crashing.
56
+ */
57
+ export function isSupported(): Promise<boolean> {
58
+ return NativeIntune.isSupported();
59
+ }
60
+
61
+ /**
62
+ * Answerable before `configure`, on purpose — the app needs it to decide whether to
63
+ * prompt for a broker install.
64
+ *
65
+ * A false negative here usually means a missing manifest entry rather than a missing
66
+ * app: `LSApplicationQueriesSchemes` on iOS, `<queries>` on Android 11+.
67
+ */
68
+ export async function getBrokerStatus(): Promise<BrokerStatus> {
69
+ return toBrokerStatus(await NativeIntune.getBrokerStatus());
70
+ }
71
+
72
+ /** Rejects with `E_NOT_NEEDED` when a broker is already present. */
73
+ export function openBrokerInstall(): Promise<void> {
74
+ return NativeIntune.openBrokerInstall();
75
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Reading policy, and reading the module's own state for a support bundle.
3
+ */
4
+
5
+ import NativeIntune from '../NativeIntune';
6
+ import { strRecord, toPolicySnapshot } from '../internal/decode';
7
+ import type { Diagnostics, PolicySnapshot } from '../types';
8
+
9
+ /**
10
+ * For adapting your own UI — hiding an export button, disabling a share sheet.
11
+ *
12
+ * **PIN prompts, screenshot blocking and encryption are enforced inside the SDK and
13
+ * never surface here.** Do not attempt to implement enforcement from these booleans.
14
+ */
15
+ export async function getPolicy(): Promise<PolicySnapshot> {
16
+ return toPolicySnapshot(await NativeIntune.getPolicy());
17
+ }
18
+
19
+ /** Safe to attach to a support ticket: no tokens, no UPNs. */
20
+ export async function getDiagnostics(): Promise<Diagnostics> {
21
+ return strRecord(await NativeIntune.getDiagnostics());
22
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The MAM service token bridge (SPEC §13.4).
3
+ *
4
+ * The SDK asks for this token on a background thread, including on its own retry
5
+ * schedule when no JS call is in flight — which is why it is a registration rather than
6
+ * a callback parameter on `enroll`.
7
+ *
8
+ * The token never leaves the module: the provider's answer goes to native, native hands
9
+ * it to the SDK, and it is never logged or returned to JS (CLAUDE.md rule 9).
10
+ */
11
+
12
+ import NativeIntune from '../NativeIntune';
13
+ import { emitter } from '../internal/emitter';
14
+ import { str } from '../internal/decode';
15
+ import type { TokenProvider, TokenRequest } from '../types';
16
+
17
+ let tokenProvider: TokenProvider | null = null;
18
+
19
+ /**
20
+ * Registers the provider for `authMode: 'external'`. Return `null` from it to say
21
+ * "cannot get a token right now" — the SDK treats that as needing authorization rather
22
+ * than as a hard failure.
23
+ */
24
+ export function setTokenProvider(provider: TokenProvider | null): void {
25
+ tokenProvider = provider;
26
+ }
27
+
28
+ /**
29
+ * Subscribed at import time, not from `setTokenProvider`.
30
+ *
31
+ * If nothing answers, the SDK waits until the native timeout — 45s on iOS, and on
32
+ * Android that is a *held background thread*. Replying "no provider" immediately turns a
33
+ * stall into a fast, named failure.
34
+ */
35
+ emitter.addListener('tokenRequest', (raw: object) => {
36
+ const r = raw as Record<string, unknown>;
37
+ const requestId = str(r.requestId);
38
+ const request: TokenRequest = {
39
+ resourceId: str(r.resourceId),
40
+ tenantId: str(r.tenantId),
41
+ authority: str(r.authority),
42
+ accountId: str(r.accountId),
43
+ };
44
+
45
+ const active = tokenProvider;
46
+ if (active === null) {
47
+ NativeIntune.rejectToken({
48
+ requestId,
49
+ reason:
50
+ "No token provider is registered. In authMode 'external' the app must call " +
51
+ 'setTokenProvider() before enrolling.',
52
+ });
53
+ return;
54
+ }
55
+
56
+ const respond = async () => {
57
+ try {
58
+ const token = await active(request);
59
+ if (typeof token === 'string' && token.length > 0) {
60
+ NativeIntune.resolveToken({ requestId, token });
61
+ } else {
62
+ NativeIntune.rejectToken({
63
+ requestId,
64
+ reason: 'token provider returned no token',
65
+ });
66
+ }
67
+ } catch (e) {
68
+ // The message reaches getDiagnostics and support logs, so pass the message and not
69
+ // the error object — a nested response body can carry a token.
70
+ NativeIntune.rejectToken({
71
+ requestId,
72
+ reason: e instanceof Error ? e.message : 'token provider threw',
73
+ });
74
+ }
75
+ };
76
+
77
+ // Nothing upstream can observe this promise: the SDK is waiting on the native side,
78
+ // and every path above already answers it.
79
+ respond().catch(() => {});
80
+ });
package/src/index.ts ADDED
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Public API for react-native-intune. See SPEC §13 for the reference — a method that
3
+ * exists here but not there does not exist, and the two change in the same commit.
4
+ *
5
+ * This file is deliberately only a surface. The work is one directory down:
6
+ *
7
+ * ```
8
+ * src/
9
+ * NativeIntune.ts Codegen spec — the only file Codegen reads, deliberately loose
10
+ * types.ts every public type and enum
11
+ * api/
12
+ * lifecycle.ts configure, isSupported, broker presence
13
+ * auth.ts sign-in, tokens for your own API (authMode 'builtin')
14
+ * enrollment.ts enroll, getState, reset
15
+ * policy.ts getPolicy, getDiagnostics
16
+ * events.ts subscriptions
17
+ * tokenProvider.ts the MAM service token bridge (authMode 'external')
18
+ * internal/
19
+ * decode.ts bridge Object -> typed, with deliberate fallbacks
20
+ * errors.ts IntuneError and the accountId guard
21
+ * emitter.ts the single NativeEventEmitter
22
+ * ```
23
+ *
24
+ * Both import styles work and neither is preferred:
25
+ *
26
+ * ```ts
27
+ * import Intune from 'react-native-intune'; Intune.configure(...)
28
+ * import { configure } from 'react-native-intune'; configure(...)
29
+ * ```
30
+ */
31
+
32
+ export * from './types';
33
+ export { IntuneError } from './internal/errors';
34
+
35
+ import {
36
+ configure,
37
+ getBrokerStatus,
38
+ isSupported,
39
+ openBrokerInstall,
40
+ } from './api/lifecycle';
41
+ import {
42
+ acquireToken,
43
+ getAccounts,
44
+ signIn,
45
+ signInAndEnroll,
46
+ signInSilent,
47
+ signOut,
48
+ } from './api/auth';
49
+ import {
50
+ enroll,
51
+ enrollInteractive,
52
+ getState,
53
+ reset,
54
+ setResetHandler,
55
+ } from './api/enrollment';
56
+ import { getDiagnostics, getPolicy } from './api/policy';
57
+ import {
58
+ onBrokerStatusChanged,
59
+ onEnrollmentResult,
60
+ onPolicyChanged,
61
+ onRestartRequired,
62
+ onUnenrollmentResult,
63
+ onWipeRequested,
64
+ } from './api/events';
65
+ import { setTokenProvider } from './api/tokenProvider';
66
+
67
+ export {
68
+ // setup
69
+ configure,
70
+ isSupported,
71
+ getBrokerStatus,
72
+ openBrokerInstall,
73
+ // auth — authMode 'builtin'
74
+ signIn,
75
+ signInSilent,
76
+ signInAndEnroll,
77
+ acquireToken,
78
+ getAccounts,
79
+ signOut,
80
+ // enrollment and reset
81
+ enroll,
82
+ enrollInteractive,
83
+ getState,
84
+ reset,
85
+ setResetHandler,
86
+ // policy
87
+ getPolicy,
88
+ getDiagnostics,
89
+ // token bridge — authMode 'external'
90
+ setTokenProvider,
91
+ // events
92
+ onEnrollmentResult,
93
+ onUnenrollmentResult,
94
+ onPolicyChanged,
95
+ onWipeRequested,
96
+ onRestartRequired,
97
+ onBrokerStatusChanged,
98
+ };
99
+
100
+ const Intune = {
101
+ configure,
102
+ isSupported,
103
+ getBrokerStatus,
104
+ openBrokerInstall,
105
+ signIn,
106
+ signInSilent,
107
+ signInAndEnroll,
108
+ acquireToken,
109
+ getAccounts,
110
+ signOut,
111
+ enroll,
112
+ enrollInteractive,
113
+ getState,
114
+ reset,
115
+ setResetHandler,
116
+ getPolicy,
117
+ getDiagnostics,
118
+ setTokenProvider,
119
+ onEnrollmentResult,
120
+ onUnenrollmentResult,
121
+ onPolicyChanged,
122
+ onWipeRequested,
123
+ onRestartRequired,
124
+ onBrokerStatusChanged,
125
+ } as const;
126
+
127
+ export default Intune;