Skip to content

Commit

Permalink
feat(authentication): support OpenID Connect (#625)
Browse files Browse the repository at this point in the history
* feat(authentication): support OpenID Connect

* docs [skip ci]

* fixes

* fix(android): add missing `@PluginMethod`
  • Loading branch information
robingenz committed May 14, 2024
1 parent 792c4d1 commit e2d6914
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/fifty-planes-reply.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@capacitor-firebase/authentication': minor
---

feat: support OpenID Connect
98 changes: 93 additions & 5 deletions packages/authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ The further installation steps depend on the selected authentication method:
- [GitHub Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-github.md)
- [Google Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-google.md)
- [Microsoft Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-microsoft.md)
- [OpenID Connect Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-oidc.md)
- [Play Games Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-play-games.md)
- [Twitter Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-twitter.md)
- [Yahoo Sign-In](https://github.com/capawesome-team/capacitor-firebase/blob/main/packages/authentication/docs/setup-yahoo.md)
Expand Down Expand Up @@ -172,6 +173,11 @@ const getCurrentUser = async () => {
return result.user;
};

const getPendingAuthResult = async () => {
const result = await FirebaseAuthentication.getPendingAuthResult();
return result.user;
};

const getIdToken = async () => {
const currentUser = await getCurrentUser();
if (!currentUser) {
Expand All @@ -181,6 +187,11 @@ const getIdToken = async () => {
return result.token;
};

const getPendingAuthResult = async () => {
const result = await FirebaseAuthentication.getPendingAuthResult();
return result.user;
};

const sendEmailVerification = async () => {
const currentUser = await getCurrentUser();
if (!currentUser) {
Expand Down Expand Up @@ -236,11 +247,6 @@ const signInWithApple = async () => {
return result.user;
};

const signInWithGameCenter = async () => {
const result = await FirebaseAuthentication.signInWithGameCenter();
return result.user;
};

const signInWithCustomToken = async () => {
const result = await FirebaseAuthentication.signInWithCustomToken({
token: '1234',
Expand Down Expand Up @@ -289,6 +295,11 @@ const signInWithFacebook = async () => {
return result.user;
};

const signInWithGameCenter = async () => {
const result = await FirebaseAuthentication.signInWithGameCenter();
return result.user;
};

const signInWithGithub = async () => {
const result = await FirebaseAuthentication.signInWithGithub();
return result.user;
Expand All @@ -304,6 +315,13 @@ const signInWithMicrosoft = async () => {
return result.user;
};

const signInWithOpenIdConnect = async () => {
const result = await FirebaseAuthentication.signInWithOpenIdConnect({
providerId: 'oidc.example.com',
});
return result.user;
};

const signInWithPlayGames = async () => {
const result = await FirebaseAuthentication.signInWithPlayGames();
return result.user;
Expand Down Expand Up @@ -395,6 +413,7 @@ const useEmulator = async () => {
* [`deleteUser()`](#deleteuser)
* [`fetchSignInMethodsForEmail(...)`](#fetchsigninmethodsforemail)
* [`getCurrentUser()`](#getcurrentuser)
* [`getPendingAuthResult()`](#getpendingauthresult)
* [`getIdToken(...)`](#getidtoken)
* [`getRedirectResult()`](#getredirectresult)
* [`getTenantId()`](#gettenantid)
Expand All @@ -407,6 +426,7 @@ const useEmulator = async () => {
* [`linkWithGithub(...)`](#linkwithgithub)
* [`linkWithGoogle(...)`](#linkwithgoogle)
* [`linkWithMicrosoft(...)`](#linkwithmicrosoft)
* [`linkWithOpenIdConnect(...)`](#linkwithopenidconnect)
* [`linkWithPhoneNumber(...)`](#linkwithphonenumber)
* [`linkWithPlayGames(...)`](#linkwithplaygames)
* [`linkWithTwitter(...)`](#linkwithtwitter)
Expand All @@ -428,6 +448,7 @@ const useEmulator = async () => {
* [`signInWithGithub(...)`](#signinwithgithub)
* [`signInWithGoogle(...)`](#signinwithgoogle)
* [`signInWithMicrosoft(...)`](#signinwithmicrosoft)
* [`signInWithOpenIdConnect(...)`](#signinwithopenidconnect)
* [`signInWithPhoneNumber(...)`](#signinwithphonenumber)
* [`signInWithPlayGames(...)`](#signinwithplaygames)
* [`signInWithTwitter(...)`](#signinwithtwitter)
Expand Down Expand Up @@ -573,6 +594,23 @@ Fetches the currently signed-in user.
--------------------


### getPendingAuthResult()

```typescript
getPendingAuthResult() => Promise<SignInResult>
```

Returns the <a href="#signinresult">`SignInResult`</a> if your app launched a web sign-in flow and the OS cleans up the app while in the background.

Only available for Android.

**Returns:** <code>Promise&lt;<a href="#signinresult">SignInResult</a>&gt;</code>

**Since:** 6.0.0

--------------------


### getIdToken(...)

```typescript
Expand Down Expand Up @@ -824,6 +862,25 @@ The `skipNativeAuth` configuration option has no effect here.
--------------------


### linkWithOpenIdConnect(...)

```typescript
linkWithOpenIdConnect(options: LinkWithOpenIdConnectOptions) => Promise<LinkResult>
```

Links the user account with an OpenID Connect provider.

| Param | Type |
| ------------- | ----------------------------------------------------------------------------------------- |
| **`options`** | <code><a href="#signinwithopenidconnectoptions">SignInWithOpenIdConnectOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#signinresult">SignInResult</a>&gt;</code>

**Since:** 6.1.0

--------------------


### linkWithPhoneNumber(...)

```typescript
Expand Down Expand Up @@ -1222,6 +1279,25 @@ Starts the Microsoft sign-in flow.
--------------------


### signInWithOpenIdConnect(...)

```typescript
signInWithOpenIdConnect(options: SignInWithOpenIdConnectOptions) => Promise<SignInResult>
```

Starts the OpenID Connect sign-in flow.

| Param | Type |
| ------------- | ----------------------------------------------------------------------------------------- |
| **`options`** | <code><a href="#signinwithopenidconnectoptions">SignInWithOpenIdConnectOptions</a></code> |

**Returns:** <code>Promise&lt;<a href="#signinresult">SignInResult</a>&gt;</code>

**Since:** 6.1.0

--------------------


### signInWithPhoneNumber(...)

```typescript
Expand Down Expand Up @@ -1713,6 +1789,13 @@ Remove all listeners for this plugin.
| **`emailLink`** | <code>string</code> | The link sent to the user's email address. | 1.1.0 |


#### SignInWithOpenIdConnectOptions

| Prop | Type | Description | Since |
| ---------------- | ------------------- | ------------------------------- | ----- |
| **`providerId`** | <code>string</code> | The OpenID Connect provider ID. | 6.1.0 |


#### SignInWithPhoneNumberOptions

| Prop | Type | Description | Default | Since |
Expand Down Expand Up @@ -1905,6 +1988,11 @@ An interface covering the possible persistence mechanism types.
<code><a href="#signinresult">SignInResult</a></code>


#### LinkWithOpenIdConnectOptions

<code><a href="#signinwithopenidconnectoptions">SignInWithOpenIdConnectOptions</a></code>


#### LinkWithPhoneNumberOptions

<code><a href="#signinwithphonenumberoptions">SignInWithPhoneNumberOptions</a></code>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ public void getIdToken(Boolean forceRefresh, @NonNull final ResultCallback resul
);
}

public void getPendingAuthResult(PluginCall call) {
oAuthProviderHandler.getPendingAuthResult(call);
}

@Nullable
public String getTenantId() {
return getFirebaseAuthInstance().getTenantId();
Expand Down Expand Up @@ -281,6 +285,10 @@ public void linkWithMicrosoft(final PluginCall call) {
oAuthProviderHandler.link(call, ProviderId.MICROSOFT);
}

public void linkWithOpenIdConnect(final PluginCall call, final String providerId) {
oAuthProviderHandler.link(call, providerId);
}

public void linkWithPhoneNumber(@NonNull final LinkWithPhoneNumberOptions options) throws Exception {
phoneAuthProviderHandler.link(options);
}
Expand Down Expand Up @@ -462,6 +470,10 @@ public void signInWithMicrosoft(final PluginCall call) {
oAuthProviderHandler.signIn(call, ProviderId.MICROSOFT);
}

public void signInWithOpenIdConnect(final PluginCall call, final String providerId) {
oAuthProviderHandler.signIn(call, providerId);
}

public void signInWithPhoneNumber(final SignInWithPhoneNumberOptions options) throws Exception {
phoneAuthProviderHandler.signIn(options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,17 @@ public void error(Exception exception) {
}
}

@PluginMethod
public void getPendingAuthResult(PluginCall call) {
try {
implementation.getPendingAuthResult(call);
} catch (Exception exception) {
Logger.error(TAG, exception.getMessage(), exception);
String code = FirebaseAuthenticationHelper.createErrorCode(exception);
call.reject(exception.getMessage(), code);
}
}

@PluginMethod
public void getRedirectResult(PluginCall call) {
call.reject("Not available on Android.");
Expand Down Expand Up @@ -359,6 +370,23 @@ public void linkWithMicrosoft(PluginCall call) {
}
}

@PluginMethod
public void linkWithOpenIdConnect(PluginCall call) {
try {
String providerId = call.getString("providerId");
if (providerId == null) {
call.reject(ERROR_PROVIDER_ID_MISSING);
return;
}

implementation.linkWithOpenIdConnect(call, providerId);
} catch (Exception exception) {
Logger.error(TAG, exception.getMessage(), exception);
String code = FirebaseAuthenticationHelper.createErrorCode(exception);
call.reject(exception.getMessage(), code);
}
}

@PluginMethod
public void linkWithPhoneNumber(PluginCall call) {
try {
Expand Down Expand Up @@ -642,6 +670,23 @@ public void signInWithMicrosoft(PluginCall call) {
}
}

@PluginMethod
public void signInWithOpenIdConnect(PluginCall call) {
try {
String providerId = call.getString("providerId");
if (providerId == null) {
call.reject(ERROR_PROVIDER_ID_MISSING);
return;
}

implementation.signInWithOpenIdConnect(call, providerId);
} catch (Exception exception) {
Logger.error(TAG, exception.getMessage(), exception);
String code = FirebaseAuthenticationHelper.createErrorCode(exception);
call.reject(exception.getMessage(), code);
}
}

@PluginMethod
public void signInWithPhoneNumber(PluginCall call) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ public OAuthProviderHandler(FirebaseAuthentication pluginImplementation) {
this.pluginImplementation = pluginImplementation;
}

public void getPendingAuthResult(PluginCall call) {
Task<AuthResult> pendingResultTask = pluginImplementation.getFirebaseAuthInstance().getPendingAuthResult();
if (pendingResultTask == null) {
pluginImplementation.handleSuccessfulSignIn(call, null, null, null, null);
return;
}

pendingResultTask
.addOnSuccessListener(authResult -> pluginImplementation.handleSuccessfulSignIn(call, authResult, null, null, null))
.addOnFailureListener(exception -> pluginImplementation.handleFailedSignIn(call, null, exception));
}

public void signIn(PluginCall call, String providerId) {
OAuthProvider.Builder provider = OAuthProvider.newBuilder(providerId);
applySignInOptions(call, provider);
Expand Down
21 changes: 21 additions & 0 deletions packages/authentication/docs/setup-oidc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Set up authentication using OpenID Connect

## Android

1. See [Before you begin](https://firebase.google.com/docs/auth/android/openid-connect?hl=en#before_you_begin) and follow the instructions to configure sign-in with OpenID Connect correctly.

## iOS

1. See [Before you begin](https://firebase.google.com/docs/auth/ios/openid-connect?hl=en#before_you_begin) and follow the instructions to configure and enable sign-in with OpenID Connect correctly.
**Attention**: Skip step 2. The `FirebaseAuth` pod is already added by the plugin.
2. Add custom URL schemes to your Xcode project:
1. Open your project configuration.
Select your app from the **TARGETS** section, then select the **Info** tab, and expand the **URL Types** section.
2. Click the **+** button, and add a URL scheme for your reversed client ID.
You find this value in your `GoogleService-Info.plist` configuration file.
Look for the `REVERSED_CLIENT_ID` key and paste the value of that key into the **URL Schemes** box on the configuration page.
Leave the other fields blank.

## Web

1. See [Before you begin](https://firebase.google.com/docs/auth/web/openid-connect?hl=en#before_you_begin) and follow the instructions to configure and enable sign-in with OpenID Connect correctly.
10 changes: 10 additions & 0 deletions packages/authentication/ios/Plugin/FirebaseAuthentication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ public typealias AuthStateChangedObserver = () -> Void
self.oAuthProviderHandler?.link(call: call, providerId: ProviderId.microsoft)
}

@objc func linkWithOpenIdConnect(_ call: CAPPluginCall, providerId: String) {
self.savedCall = call
self.oAuthProviderHandler?.link(call: call, providerId: providerId)
}

@objc func linkWithPhoneNumber(_ options: LinkWithPhoneNumberOptions) {
self.phoneAuthProviderHandler?.link(options)
}
Expand Down Expand Up @@ -390,6 +395,11 @@ public typealias AuthStateChangedObserver = () -> Void
self.oAuthProviderHandler?.signIn(call: call, providerId: ProviderId.microsoft)
}

@objc func signInWithOpenIdConnect(_ call: CAPPluginCall, providerId: String) {
self.savedCall = call
self.oAuthProviderHandler?.signIn(call: call, providerId: providerId)
}

@objc func signInWithPhoneNumber(_ options: SignInWithPhoneNumberOptions) {
self.phoneAuthProviderHandler?.signIn(options)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CAP_PLUGIN_METHOD(fetchSignInMethodsForEmail, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getCurrentUser, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getIdToken, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getPendingAuthResult, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getRedirectResult, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getTenantId, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(isSignInWithEmailLink, CAPPluginReturnPromise);
Expand All @@ -23,6 +24,7 @@
CAP_PLUGIN_METHOD(linkWithGithub, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(linkWithGoogle, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(linkWithMicrosoft, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(linkWithOpenIdConnect, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(linkWithPhoneNumber, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(linkWithPlayGames, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(linkWithTwitter, CAPPluginReturnPromise);
Expand All @@ -47,6 +49,7 @@
CAP_PLUGIN_METHOD(signInWithPlayGames, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(signInWithTwitter, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(signInWithYahoo, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(signInWithOpenIdConnect, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(signInWithPhoneNumber, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(signOut, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(unlink, CAPPluginReturnPromise);
Expand Down
Loading

0 comments on commit e2d6914

Please sign in to comment.