Skip to content

Commit 26de3f1

Browse files
committed
feat(auth): add support for cognito oidc parameters in managed login
1 parent 7253c7e commit 26de3f1

File tree

8 files changed

+217
-8
lines changed

8 files changed

+217
-8
lines changed

aws-auth-cognito/api/aws-auth-cognito.api

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,11 @@ public final class com/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUI
611611
public fun equals (Ljava/lang/Object;)Z
612612
public fun getBrowserPackage ()Ljava/lang/String;
613613
public fun getIdpIdentifier ()Ljava/lang/String;
614+
public fun getLanguage ()Ljava/lang/String;
615+
public fun getLoginHint ()Ljava/lang/String;
616+
public fun getNonce ()Ljava/lang/String;
617+
public fun getPrompt ()Ljava/util/List;
618+
public fun getResource ()Ljava/lang/String;
614619
public fun hashCode ()I
615620
public fun toString ()Ljava/lang/String;
616621
}
@@ -623,6 +628,11 @@ public final class com/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUI
623628
public fun getThis ()Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
624629
public synthetic fun getThis ()Lcom/amplifyframework/auth/options/AuthWebUISignInOptions$Builder;
625630
public fun idpIdentifier (Ljava/lang/String;)Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
631+
public fun language (Ljava/lang/String;)Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
632+
public fun loginHint (Ljava/lang/String;)Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
633+
public fun nonce (Ljava/lang/String;)Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
634+
public fun prompt ([Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;)Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
635+
public fun resource (Ljava/lang/String;)Lcom/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions$CognitoBuilder;
626636
}
627637

628638
public final class com/amplifyframework/auth/cognito/options/AuthFlowType : java/lang/Enum {
@@ -636,6 +646,17 @@ public final class com/amplifyframework/auth/cognito/options/AuthFlowType : java
636646
public static fun values ()[Lcom/amplifyframework/auth/cognito/options/AuthFlowType;
637647
}
638648

649+
public final class com/amplifyframework/auth/cognito/options/AuthWebUIPrompt : java/lang/Enum {
650+
public static final field CONSENT Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;
651+
public static final field LOGIN Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;
652+
public static final field NONE Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;
653+
public static final field SELECT_ACCOUNT Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;
654+
public static fun getEntries ()Lkotlin/enums/EnumEntries;
655+
public final fun getValue ()Ljava/lang/String;
656+
public static fun valueOf (Ljava/lang/String;)Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;
657+
public static fun values ()[Lcom/amplifyframework/auth/cognito/options/AuthWebUIPrompt;
658+
}
659+
639660
public final class com/amplifyframework/auth/cognito/options/FederateToIdentityPoolOptions {
640661
public static final field Companion Lcom/amplifyframework/auth/cognito/options/FederateToIdentityPoolOptions$Companion;
641662
public static final fun builder ()Lcom/amplifyframework/auth/cognito/options/FederateToIdentityPoolOptions$CognitoBuilder;

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/HostedUIClient.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,31 @@ internal class HostedUIClient private constructor(
164164
builder.appendQueryParameter("scope", it)
165165
}
166166

167+
// check if nonce is set as param.
168+
hostedUIOptions.nonce?.takeIf { it.isNotEmpty() }?.let {
169+
builder.appendQueryParameter("nonce", it)
170+
}
171+
172+
// check if language is set as param.
173+
hostedUIOptions.language?.takeIf { it.isNotEmpty() }?.let {
174+
builder.appendQueryParameter("lang", it)
175+
}
176+
177+
// check if loginHint is set as param.
178+
hostedUIOptions.loginHint?.takeIf { it.isNotEmpty() }?.let {
179+
builder.appendQueryParameter("login_hint", it)
180+
}
181+
182+
// check if prompt is set as param.
183+
hostedUIOptions.prompt?.joinToString(" ") { it.value }.let {
184+
builder.appendQueryParameter("prompt", it)
185+
}
186+
187+
// check if resource is set as param.
188+
hostedUIOptions.resource?.takeIf { it.isNotEmpty() }?.let {
189+
builder.appendQueryParameter("resource", it)
190+
}
191+
167192
return builder.build()
168193
}
169194

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/helpers/HostedUIHelper.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ internal object HostedUIHelper {
3636
idpIdentifier = (options as? AWSCognitoAuthWebUISignInOptions)?.idpIdentifier
3737
),
3838
browserPackage = (options as? AWSCognitoAuthWebUISignInOptions)?.browserPackage,
39-
preferPrivateSession = options.preferPrivateSession
39+
preferPrivateSession = options.preferPrivateSession,
40+
nonce = (options as? AWSCognitoAuthWebUISignInOptions)?.nonce,
41+
language = (options as? AWSCognitoAuthWebUISignInOptions)?.language,
42+
loginHint = (options as? AWSCognitoAuthWebUISignInOptions)?.loginHint,
43+
prompt = (options as? AWSCognitoAuthWebUISignInOptions)?.prompt,
44+
resource = (options as? AWSCognitoAuthWebUISignInOptions)?.resource
4045
)
4146

4247
/**

aws-auth-cognito/src/main/java/com/amplifyframework/auth/cognito/options/AWSCognitoAuthWebUISignInOptions.java

Lines changed: 104 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.amplifyframework.auth.options.AuthWebUISignInOptions;
2323
import com.amplifyframework.util.Immutable;
2424

25+
import java.util.ArrayList;
2526
import java.util.List;
2627

2728
/**
@@ -30,7 +31,11 @@
3031
public final class AWSCognitoAuthWebUISignInOptions extends AuthWebUISignInOptions {
3132
private final String idpIdentifier;
3233
private final String browserPackage;
33-
34+
private final String nonce;
35+
private final String language;
36+
private final String loginHint;
37+
private final List<AuthWebUIPrompt> prompt;
38+
private final String resource;
3439
/**
3540
* Advanced options for signing in via a hosted web ui.
3641
* @param scopes specify OAUTH scopes
@@ -43,11 +48,21 @@ protected AWSCognitoAuthWebUISignInOptions(
4348
List<String> scopes,
4449
String idpIdentifier,
4550
String browserPackage,
46-
Boolean preferPrivateSession
51+
Boolean preferPrivateSession,
52+
String nonce,
53+
String language,
54+
String loginHint,
55+
List<AuthWebUIPrompt> prompt,
56+
String resource
4757
) {
4858
super(scopes, preferPrivateSession);
4959
this.idpIdentifier = idpIdentifier;
5060
this.browserPackage = browserPackage;
61+
this.nonce = nonce;
62+
this.language = language;
63+
this.loginHint = loginHint;
64+
this.prompt = prompt;
65+
this.resource = resource;
5166
}
5267

5368
/**
@@ -68,6 +83,31 @@ public String getBrowserPackage() {
6883
return browserPackage;
6984
}
7085

86+
@Nullable
87+
public String getNonce() {
88+
return nonce;
89+
}
90+
91+
@Nullable
92+
public String getLanguage() {
93+
return language;
94+
}
95+
96+
@Nullable
97+
public String getLoginHint() {
98+
return loginHint;
99+
}
100+
101+
@Nullable
102+
public List<AuthWebUIPrompt> getPrompt() {
103+
return prompt;
104+
}
105+
106+
@Nullable
107+
public String getResource() {
108+
return resource;
109+
}
110+
71111
/**
72112
* Returns a builder for this object.
73113
* @return a builder for this object.
@@ -83,7 +123,12 @@ public int hashCode() {
83123
getScopes(),
84124
getIdpIdentifier(),
85125
getBrowserPackage(),
86-
getPreferPrivateSession()
126+
getPreferPrivateSession(),
127+
getNonce(),
128+
getLanguage(),
129+
getLoginHint(),
130+
getPrompt(),
131+
getResource()
87132
);
88133
}
89134

@@ -98,7 +143,12 @@ public boolean equals(Object obj) {
98143
return ObjectsCompat.equals(getScopes(), webUISignInOptions.getScopes()) &&
99144
ObjectsCompat.equals(getIdpIdentifier(), webUISignInOptions.getIdpIdentifier()) &&
100145
ObjectsCompat.equals(getBrowserPackage(), webUISignInOptions.getBrowserPackage()) &&
101-
ObjectsCompat.equals(getPreferPrivateSession(), webUISignInOptions.getPreferPrivateSession());
146+
ObjectsCompat.equals(getPreferPrivateSession(), webUISignInOptions.getPreferPrivateSession()) &&
147+
ObjectsCompat.equals(getNonce(), webUISignInOptions.getNonce()) &&
148+
ObjectsCompat.equals(getLanguage(), webUISignInOptions.getLanguage()) &&
149+
ObjectsCompat.equals(getLoginHint(), webUISignInOptions.getLoginHint()) &&
150+
ObjectsCompat.equals(getPrompt(), webUISignInOptions.getPrompt()) &&
151+
ObjectsCompat.equals(getResource(), webUISignInOptions.getResource());
102152
}
103153
}
104154

@@ -108,7 +158,12 @@ public String toString() {
108158
"scopes=" + getScopes() +
109159
", idpIdentifier=" + getIdpIdentifier() +
110160
", browserPackage=" + getBrowserPackage() +
111-
", preferPrivateSession=" + getPreferPrivateSession() +
161+
", preferPrivateSession=" + getPreferPrivateSession() +
162+
", nonce=" + getNonce() +
163+
", language=" + getLanguage() +
164+
", loginHint=" + getLoginHint() +
165+
", prompt=" + getPrompt() +
166+
", resource=" + getResource() +
112167
'}';
113168
}
114169

@@ -118,6 +173,11 @@ public String toString() {
118173
public static final class CognitoBuilder extends Builder<CognitoBuilder> {
119174
private String idpIdentifier;
120175
private String browserPackage;
176+
private String nonce;
177+
private String language;
178+
private String loginHint;
179+
private List<AuthWebUIPrompt> prompt;
180+
private String resource;
121181

122182
/**
123183
* Constructs the builder.
@@ -146,6 +206,39 @@ public CognitoBuilder idpIdentifier(@NonNull String idpIdentifier) {
146206
return getThis();
147207
}
148208

209+
@NonNull
210+
public CognitoBuilder nonce(@NonNull String nonce) {
211+
this.nonce = nonce;
212+
return getThis();
213+
}
214+
215+
@NonNull
216+
public CognitoBuilder language(@NonNull String language) {
217+
this.language = language;
218+
return getThis();
219+
}
220+
221+
@NonNull
222+
public CognitoBuilder loginHint(@NonNull String loginHint) {
223+
this.loginHint = loginHint;
224+
return getThis();
225+
}
226+
227+
@NonNull
228+
public CognitoBuilder prompt(AuthWebUIPrompt... prompt) {
229+
this.prompt = new ArrayList<>();
230+
for (AuthWebUIPrompt value: prompt) {
231+
this.prompt.add(value);
232+
}
233+
return getThis();
234+
}
235+
236+
@NonNull
237+
public CognitoBuilder resource(@NonNull String resource) {
238+
this.resource = resource;
239+
return getThis();
240+
}
241+
149242
/**
150243
* This can optionally be set to specify which browser package should perform the sign in action
151244
* (e.g. "org.mozilla.firefox"). Defaults to the Chrome package if not set.
@@ -168,7 +261,12 @@ public AWSCognitoAuthWebUISignInOptions build() {
168261
Immutable.of(super.getScopes()),
169262
idpIdentifier,
170263
browserPackage,
171-
super.getPreferPrivateSession()
264+
super.getPreferPrivateSession(),
265+
nonce,
266+
language,
267+
loginHint,
268+
prompt,
269+
resource
172270
);
173271
}
174272
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.amplifyframework.auth.cognito.options
2+
3+
public enum class AuthWebUIPrompt(val value: String) {
4+
NONE(value = "none"),
5+
6+
LOGIN(value = "login"),
7+
8+
SELECT_ACCOUNT(value = "select_account"),
9+
10+
CONSENT(value = "consent")
11+
}

aws-auth-cognito/src/main/java/com/amplifyframework/statemachine/codegen/data/HostedUIOptions.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616
package com.amplifyframework.statemachine.codegen.data
1717

1818
import android.app.Activity
19+
import com.amplifyframework.auth.cognito.options.AuthWebUIPrompt
1920

2021
internal data class HostedUIOptions(
2122
val callingActivity: Activity,
2223
val scopes: List<String>?,
2324
val providerInfo: HostedUIProviderInfo,
2425
val browserPackage: String?,
25-
val preferPrivateSession: Boolean?
26+
val preferPrivateSession: Boolean?,
27+
val nonce: String?,
28+
val language: String?,
29+
val loginHint: String?,
30+
val prompt: List<AuthWebUIPrompt>?,
31+
val resource: String?
2632
)

aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/helpers/HostedUIHelperTest.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.amplifyframework.auth.cognito.helpers
1818
import android.app.Activity
1919
import com.amplifyframework.auth.AuthProvider
2020
import com.amplifyframework.auth.cognito.options.AWSCognitoAuthWebUISignInOptions
21+
import com.amplifyframework.auth.cognito.options.AuthWebUIPrompt
2122
import io.kotest.matchers.shouldBe
2223
import io.mockk.mockk
2324
import org.junit.Test
@@ -88,6 +89,30 @@ class HostedUIHelperTest {
8889
hostedUIOptions.preferPrivateSession shouldBe null
8990
}
9091

92+
@Test
93+
fun `createHostedUIOptions with Cognito OIDC parameters`() {
94+
val options = AWSCognitoAuthWebUISignInOptions.builder()
95+
.nonce("nonce")
96+
.language("en")
97+
.loginHint("username")
98+
.prompt(AuthWebUIPrompt.LOGIN, AuthWebUIPrompt.CONSENT)
99+
.resource("myapp://")
100+
.build()
101+
102+
val hostedUIOptions = HostedUIHelper.createHostedUIOptions(
103+
callingActivity = mockActivity,
104+
authProvider = null,
105+
options = options
106+
)
107+
108+
hostedUIOptions.callingActivity shouldBe mockActivity
109+
hostedUIOptions.nonce shouldBe "nonce"
110+
hostedUIOptions.language shouldBe "en"
111+
hostedUIOptions.loginHint shouldBe "username"
112+
hostedUIOptions.prompt shouldBe listOf(AuthWebUIPrompt.LOGIN, AuthWebUIPrompt.CONSENT)
113+
hostedUIOptions.resource shouldBe "myapp://"
114+
}
115+
91116
@Test
92117
fun `selectRedirectUri prefers non-HTTP scheme`() {
93118
val redirectUris = listOf(

aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/options/APIOptionsContractTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,22 @@ public void testCognitoOptions() {
127127
Assert.assertEquals("test-idp", federateToIdentityPoolOptions
128128
.getDeveloperProvidedIdentityId());
129129
}
130+
131+
@Test
132+
public void testCognitoAuthWebUISignInOIDCParameters() {
133+
List<AuthWebUIPrompt> prompt = Arrays.asList(AuthWebUIPrompt.LOGIN, AuthWebUIPrompt.CONSENT);
134+
AWSCognitoAuthWebUISignInOptions webUISignInOptionsWithOIDCParameters =
135+
AWSCognitoAuthWebUISignInOptions.builder()
136+
.nonce("nonce")
137+
.language("en")
138+
.loginHint("username")
139+
.prompt(AuthWebUIPrompt.LOGIN, AuthWebUIPrompt.CONSENT)
140+
.resource("myapp://")
141+
.build();
142+
Assert.assertEquals("nonce", webUISignInOptionsWithOIDCParameters.getNonce());
143+
Assert.assertEquals("en", webUISignInOptionsWithOIDCParameters.getLanguage());
144+
Assert.assertEquals("username", webUISignInOptionsWithOIDCParameters.getLoginHint());
145+
Assert.assertEquals(prompt, webUISignInOptionsWithOIDCParameters.getPrompt());
146+
Assert.assertEquals("myapp://", webUISignInOptionsWithOIDCParameters.getResource());
147+
}
130148
}

0 commit comments

Comments
 (0)