react-native-msal2 1.0.10 → 1.0.13

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 (72) hide show
  1. package/android/src/main/java/com/reactnativemsal/RNMSALModule.kt +11 -0
  2. package/package.json +1 -1
  3. package/react-native-msal2.podspec +1 -1
  4. package/src/publicClientApplication.ts +9 -0
  5. package/src/types.ts +9 -0
  6. package/app/.bundle/config +0 -2
  7. package/app/.eslintrc.js +0 -4
  8. package/app/.prettierrc.js +0 -7
  9. package/app/.watchman-cookie-Sandeeps-Mac-541-3381 +0 -0
  10. package/app/.watchmanconfig +0 -1
  11. package/app/Gemfile +0 -9
  12. package/app/README.md +0 -79
  13. package/app/android/app/build.gradle +0 -119
  14. package/app/android/app/debug.keystore +0 -0
  15. package/app/android/app/proguard-rules.pro +0 -10
  16. package/app/android/app/src/debug/AndroidManifest.xml +0 -9
  17. package/app/android/app/src/main/AndroidManifest.xml +0 -25
  18. package/app/android/app/src/main/java/com/msal2app/MainActivity.kt +0 -22
  19. package/app/android/app/src/main/java/com/msal2app/MainApplication.kt +0 -45
  20. package/app/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -36
  21. package/app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  22. package/app/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  23. package/app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  24. package/app/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  25. package/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  26. package/app/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  27. package/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  28. package/app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  29. package/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  30. package/app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  31. package/app/android/app/src/main/res/values/strings.xml +0 -3
  32. package/app/android/app/src/main/res/values/styles.xml +0 -9
  33. package/app/android/build.gradle +0 -21
  34. package/app/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  35. package/app/android/gradle/wrapper/gradle-wrapper.properties +0 -7
  36. package/app/android/gradle.properties +0 -41
  37. package/app/android/gradlew +0 -249
  38. package/app/android/gradlew.bat +0 -92
  39. package/app/android/settings.gradle +0 -4
  40. package/app/app.json +0 -4
  41. package/app/babel.config.js +0 -3
  42. package/app/index.js +0 -9
  43. package/app/ios/.xcode.env +0 -11
  44. package/app/ios/Msal2App/AppDelegate.h +0 -6
  45. package/app/ios/Msal2App/AppDelegate.mm +0 -31
  46. package/app/ios/Msal2App/Images.xcassets/AppIcon.appiconset/Contents.json +0 -53
  47. package/app/ios/Msal2App/Images.xcassets/Contents.json +0 -6
  48. package/app/ios/Msal2App/Info.plist +0 -52
  49. package/app/ios/Msal2App/LaunchScreen.storyboard +0 -47
  50. package/app/ios/Msal2App/main.m +0 -10
  51. package/app/ios/Msal2App.xcodeproj/project.pbxproj +0 -698
  52. package/app/ios/Msal2App.xcodeproj/xcshareddata/xcschemes/Msal2App.xcscheme +0 -88
  53. package/app/ios/Msal2App.xcworkspace/contents.xcworkspacedata +0 -10
  54. package/app/ios/Msal2AppTests/Info.plist +0 -24
  55. package/app/ios/Msal2AppTests/Msal2AppTests.m +0 -66
  56. package/app/ios/Podfile +0 -56
  57. package/app/ios/Podfile.lock +0 -1384
  58. package/app/jest.config.js +0 -3
  59. package/app/metro.config.js +0 -11
  60. package/app/package-lock.json +0 -20038
  61. package/app/package.json +0 -37
  62. package/app/react-native-msal2-1.0.0.tgz +0 -0
  63. package/app/src/App.tsx +0 -150
  64. package/app/src/b2cClient.ts +0 -199
  65. package/app/src/msalConfig.ts +0 -20
  66. package/app/tsconfig.json +0 -3
  67. package/app/yarn.lock +0 -6771
  68. package/dist/index.d.ts +0 -3
  69. package/dist/index.js +0 -92
  70. package/dist/index.js.map +0 -7
  71. package/dist/src/publicClientApplication.d.ts +0 -14
  72. package/dist/src/types.d.ts +0 -297
package/app/package.json DELETED
@@ -1,37 +0,0 @@
1
- {
2
- "name": "Msal2App",
3
- "version": "0.0.1",
4
- "private": true,
5
- "scripts": {
6
- "android": "react-native run-android",
7
- "ios": "react-native run-ios",
8
- "lint": "eslint .",
9
- "start": "react-native start",
10
- "test": "jest"
11
- },
12
- "dependencies": {
13
- "react": "18.2.0",
14
- "react-native": "0.73.6",
15
- "react-native-msal2": "file:react-native-msal2-1.0.0.tgz"
16
- },
17
- "devDependencies": {
18
- "@babel/core": "^7.20.0",
19
- "@babel/preset-env": "^7.20.0",
20
- "@babel/runtime": "^7.20.0",
21
- "@react-native/babel-preset": "0.73.21",
22
- "@react-native/eslint-config": "0.73.2",
23
- "@react-native/metro-config": "0.73.5",
24
- "@react-native/typescript-config": "0.73.1",
25
- "@types/react": "^18.2.6",
26
- "@types/react-test-renderer": "^18.0.0",
27
- "babel-jest": "^29.6.3",
28
- "eslint": "^8.19.0",
29
- "jest": "^29.6.3",
30
- "prettier": "2.8.8",
31
- "react-test-renderer": "18.2.0",
32
- "typescript": "5.0.4"
33
- },
34
- "engines": {
35
- "node": ">=18"
36
- }
37
- }
Binary file
package/app/src/App.tsx DELETED
@@ -1,150 +0,0 @@
1
- /**
2
- * Example for a Azure B2C application using a B2CClient helper class
3
- */
4
-
5
- import React from 'react';
6
- import {
7
- Platform,
8
- SafeAreaView,
9
- ScrollView,
10
- StyleSheet,
11
- Switch,
12
- Text,
13
- View,
14
- TouchableOpacity,
15
- } from 'react-native';
16
- import type {MSALResult, MSALWebviewParams} from 'react-native-msal2';
17
-
18
- import {B2CClient} from './b2cClient';
19
- import {b2cConfig, b2cScopes as scopes} from './msalConfig';
20
-
21
- const b2cClient = new B2CClient(b2cConfig);
22
-
23
- export default function App() {
24
- const [authResult, setAuthResult] = React.useState<MSALResult | null>(null);
25
- const [iosEphemeralSession, setIosEphemeralSession] = React.useState(false);
26
- const webviewParameters: MSALWebviewParams = {
27
- ios_prefersEphemeralWebBrowserSession: iosEphemeralSession,
28
- };
29
-
30
- React.useEffect(() => {
31
- async function init() {
32
- try {
33
- await b2cClient.init();
34
- const isSignedIn = await b2cClient.isSignedIn();
35
- if (isSignedIn) {
36
- setAuthResult(await b2cClient.acquireTokenSilent({scopes}));
37
- }
38
- } catch (error) {
39
- console.error(error);
40
- }
41
- }
42
- init();
43
- }, []);
44
-
45
- const handleSignInPress = async () => {
46
- try {
47
- const res = await b2cClient.signIn({scopes, webviewParameters});
48
- setAuthResult(res);
49
- } catch (error) {
50
- console.warn(error);
51
- }
52
- };
53
-
54
- const handleAcquireTokenPress = async () => {
55
- try {
56
- const res = await b2cClient.acquireTokenSilent({
57
- scopes,
58
- forceRefresh: true,
59
- });
60
- setAuthResult(res);
61
- } catch (error) {
62
- console.warn(error);
63
- }
64
- };
65
-
66
- const handleSignoutPress = async () => {
67
- try {
68
- await b2cClient.signOut();
69
- setAuthResult(null);
70
- } catch (error) {
71
- console.warn(error);
72
- }
73
- };
74
-
75
- return (
76
- <SafeAreaView style={styles.container}>
77
- <View style={styles.buttonContainer}>
78
- {authResult ? (
79
- <>
80
- <TouchableOpacity
81
- style={styles.button}
82
- onPress={handleAcquireTokenPress}>
83
- <Text>Acquire Token (Silent)</Text>
84
- </TouchableOpacity>
85
- <TouchableOpacity
86
- style={styles.button}
87
- onPress={handleSignoutPress}>
88
- <Text>Sign Out</Text>
89
- </TouchableOpacity>
90
- </>
91
- ) : (
92
- <TouchableOpacity style={styles.button} onPress={handleSignInPress}>
93
- <Text>Sign In</Text>
94
- </TouchableOpacity>
95
- )}
96
-
97
- {Platform.OS === 'ios' && (
98
- <TouchableOpacity
99
- style={[styles.button, styles.switchButton]}
100
- onPress={() => setIosEphemeralSession(!iosEphemeralSession)}>
101
- <Text>Prefer ephemeral browser session (iOS only)</Text>
102
- <Switch
103
- value={iosEphemeralSession}
104
- onValueChange={setIosEphemeralSession}
105
- />
106
- </TouchableOpacity>
107
- )}
108
- </View>
109
- <ScrollView style={styles.scrollView}>
110
- <Text>{JSON.stringify(authResult, null, 2)}</Text>
111
- </ScrollView>
112
- </SafeAreaView>
113
- );
114
- }
115
-
116
- const styles = StyleSheet.create({
117
- container: {
118
- flex: 1,
119
- padding: '1%',
120
- backgroundColor: 'white',
121
- },
122
- buttonContainer: {
123
- flexDirection: 'row',
124
- flexWrap: 'wrap',
125
- paddingBottom: '1%',
126
- margin: '-0.5%',
127
- },
128
- button: {
129
- backgroundColor: 'aliceblue',
130
- borderWidth: 1,
131
- margin: '0.5%',
132
- padding: 8,
133
- width: '49%',
134
- alignItems: 'center',
135
- },
136
- disabledButton: {
137
- backgroundColor: '#ddd',
138
- },
139
- switchButton: {
140
- flexDirection: 'row',
141
- justifyContent: 'space-around',
142
- padding: 4,
143
- margin: '0.5%',
144
- width: '99%',
145
- },
146
- scrollView: {
147
- borderWidth: 1,
148
- padding: 1,
149
- },
150
- });
@@ -1,199 +0,0 @@
1
- import {Platform} from 'react-native';
2
- import PublicClientApplication from 'react-native-msal2';
3
- import type {
4
- MSALAccount,
5
- MSALConfiguration,
6
- MSALInteractiveParams,
7
- MSALResult,
8
- MSALSignoutParams,
9
- MSALSilentParams,
10
- MSALWebviewParams,
11
- } from 'react-native-msal2';
12
-
13
- export interface B2CPolicies {
14
- signInSignUp: string;
15
- passwordReset?: string;
16
- }
17
-
18
- export type B2CConfiguration = Omit<MSALConfiguration, 'auth'> & {
19
- auth: {
20
- clientId: string;
21
- authorityBase: string;
22
- policies: B2CPolicies;
23
- redirectUri?: string;
24
- };
25
- };
26
- export type B2CSignInParams = Omit<MSALInteractiveParams, 'authority'>;
27
- export type B2CSilentParams = Pick<MSALSilentParams, 'scopes' | 'forceRefresh'>;
28
- export type B2CSignOutParams = Pick<
29
- MSALSignoutParams,
30
- 'signoutFromBrowser' | 'webviewParameters'
31
- >;
32
-
33
- export class B2CClient {
34
- private static readonly B2C_PASSWORD_CHANGE = 'AADB2C90118';
35
- private static readonly B2C_EXPIRED_GRANT = 'AADB2C90080';
36
- private readonly policyUrls: B2CPolicies;
37
- private pca: PublicClientApplication;
38
-
39
- /** Construct a B2CClient object
40
- * @param b2cConfig The configuration object for the B2CClient
41
- */
42
- constructor(b2cConfig: B2CConfiguration) {
43
- const {authorityBase, policies, ...restOfAuthConfig} = b2cConfig.auth;
44
- this.policyUrls = makePolicyUrls(authorityBase, policies);
45
-
46
- // Set the sign in sign up policy as the default authority for the PublicClientApplication (PCA).
47
- const authority = this.policyUrls.signInSignUp;
48
-
49
- // We need to provide all authorities we'll be using up front.
50
- // The default authority should be included in this list.
51
- const knownAuthorities = Object.values(this.policyUrls);
52
-
53
- this.pca = new PublicClientApplication({
54
- ...b2cConfig,
55
- auth: {authority, knownAuthorities, ...restOfAuthConfig},
56
- });
57
- }
58
-
59
- public async init() {
60
- await this.pca.init();
61
- return this;
62
- }
63
-
64
- /** Initiates an interactive sign-in. If the user clicks "Forgot Password", and a reset password policy
65
- * was provided to the client, it will initiate the password reset flow
66
- */
67
- public async signIn(params: B2CSignInParams): Promise<MSALResult> {
68
- const isSignedIn = await this.isSignedIn();
69
- if (isSignedIn) {
70
- throw Error('A user is already signed in');
71
- }
72
-
73
- try {
74
- // If we don't provide an authority, the PCA will use the one we passed to it when we created it
75
- // (the sign in sign up policy)
76
- const result = await this.pca.acquireToken(params);
77
- if (!result) {
78
- throw new Error('Could not sign in: Result was undefined.');
79
- }
80
- return result;
81
- } catch (error: unknown) {
82
- if (
83
- error instanceof Error &&
84
- error.message.includes(B2CClient.B2C_PASSWORD_CHANGE) &&
85
- this.policyUrls.passwordReset
86
- ) {
87
- return await this.resetPassword(params);
88
- } else {
89
- throw error;
90
- }
91
- }
92
- }
93
-
94
- /** Gets a token silently. Will only work if the user is already signed in */
95
- public async acquireTokenSilent(params: B2CSilentParams) {
96
- const account = await this.getAccountForPolicy(
97
- this.policyUrls.signInSignUp,
98
- );
99
- if (account) {
100
- // We provide the account that we got when we signed in, with the matching sign in sign up authority
101
- // Which again, we set as the default authority so we don't need to provide it explicitly.
102
- try {
103
- const result = await this.pca.acquireTokenSilent({...params, account});
104
- if (!result) {
105
- throw new Error(
106
- 'Could not acquire token silently: Result was undefined.',
107
- );
108
- }
109
- return result;
110
- } catch (error: unknown) {
111
- if (
112
- error instanceof Error &&
113
- error.message.includes(B2CClient.B2C_EXPIRED_GRANT)
114
- ) {
115
- await this.pca.signOut({...params, account});
116
- return await this.signIn(params);
117
- } else {
118
- throw error;
119
- }
120
- }
121
- } else {
122
- throw Error('Could not find existing account for sign in sign up policy');
123
- }
124
- }
125
-
126
- /** Returns true if a user is signed in, false if not */
127
- public async isSignedIn() {
128
- const signInAccount = await this.getAccountForPolicy(
129
- this.policyUrls.signInSignUp,
130
- );
131
- return signInAccount !== undefined;
132
- }
133
-
134
- /** Removes all accounts from the device for this app. User will have to sign in again to get a token */
135
- public async signOut(params?: B2CSignOutParams) {
136
- const accounts = await this.pca.getAccounts();
137
- const signOutPromises = accounts.map(account =>
138
- this.pca.signOut({...params, account}),
139
- );
140
- await Promise.all(signOutPromises);
141
- return true;
142
- }
143
-
144
- private async resetPassword(params: B2CSignInParams) {
145
- const {webviewParameters: wvp, ...rest} = params;
146
- const webviewParameters: MSALWebviewParams = {
147
- ...wvp,
148
- // We use an ephemeral session because if we're resetting a password it means the user
149
- // is not using an identity provider, so we don't need a logged-in browser session
150
- ios_prefersEphemeralWebBrowserSession: true,
151
- };
152
- if (this.policyUrls.passwordReset) {
153
- // Because there is no prompt before starting an iOS ephemeral session, it will be quick to
154
- // open and begin before the other one has ended, causing an error saying that only one
155
- // interactive session is allowed at a time. So we have to slow it down a little
156
- if (Platform.OS === 'ios') {
157
- await delay(1000);
158
- }
159
- // Use the password reset policy in the interactive `acquireToken` call
160
- const authority = this.policyUrls.passwordReset;
161
- await this.pca.acquireToken({...rest, webviewParameters, authority});
162
- // Sign in again after resetting the password
163
- return await this.signIn(params);
164
- } else {
165
- throw Error('B2CClient missing password reset policy');
166
- }
167
- }
168
-
169
- private async getAccountForPolicy(
170
- policyUrl: string,
171
- ): Promise<MSALAccount | undefined> {
172
- const policy = policyUrl.split('/').pop();
173
- const accounts = await this.pca.getAccounts();
174
- return accounts.find(account =>
175
- account.identifier.includes(policy!.toLowerCase()),
176
- );
177
- }
178
- }
179
-
180
- function makeAuthority(authorityBase: string, policyName: string) {
181
- return `${authorityBase}/${policyName}`;
182
- }
183
-
184
- function makePolicyUrls(
185
- authorityBase: string,
186
- policyNames: B2CPolicies,
187
- ): B2CPolicies {
188
- return Object.entries(policyNames).reduce(
189
- (prev, [key, policyName]) => ({
190
- ...prev,
191
- [key]: makeAuthority(authorityBase, policyName),
192
- }),
193
- {} as B2CPolicies,
194
- );
195
- }
196
-
197
- async function delay(ms: number) {
198
- return await new Promise<void>(resolve => setTimeout(resolve, ms));
199
- }
@@ -1,20 +0,0 @@
1
- import type {B2CConfiguration} from './b2cClient';
2
-
3
- export const b2cConfig: B2CConfiguration = {
4
- auth: {
5
- clientId: 'fc8ecae3-0883-45f4-ac1c-013dfa11cb9c',
6
- authorityBase:
7
- 'https://stashcafe.b2clogin.com/tfp/stashcafe.onmicrosoft.com',
8
- policies: {
9
- signInSignUp: 'B2C_1_SignInUp',
10
- passwordReset: 'B2C_1_PasswordReset',
11
- },
12
- // redirectUri: Platform.select({ default: undefined }),
13
- },
14
- // web only:
15
- cache: {cacheLocation: 'localStorage'},
16
- };
17
-
18
- export const b2cScopes = [
19
- 'https://stashcafe.onmicrosoft.com/api/user_impersonation',
20
- ];
package/app/tsconfig.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "@react-native/typescript-config/tsconfig.json"
3
- }