Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions source/api/src/main/kotlin/com/clerk/api/auth/Auth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,11 @@ class Auth internal constructor() {
}

/**
* Signs in with a ticket.
* Signs in with a ticket generated by the Backend API.
*
* When the ticket is scoped to an organization, the resulting session is activated for that
* organization. The updated session, including [Session.lastActiveOrganizationId], is available
* through [Clerk.sessionFlow] when this method returns successfully.
*
* @param ticket The authentication ticket.
* @return A [ClerkResult] containing the [SignIn] object on success, or a [ClerkErrorResponse] on
Expand All @@ -369,14 +373,7 @@ class Auth internal constructor() {
* ```
*/
suspend fun signInWithTicket(ticket: String): ClerkResult<SignIn, ClerkErrorResponse> {
val params =
mapOf(
"strategy" to com.clerk.api.Constants.Strategy.TICKET,
"ticket" to ticket,
"locale" to Clerk.locale.value.orEmpty(),
)

val result = ClerkApi.signIn.createSignIn(params)
val result = SignIn.create(SignIn.CreateParams.Strategy.Ticket(ticket))
result.onFailure { emitAuthError(it) }
return result
}
Expand Down
20 changes: 20 additions & 0 deletions source/api/src/test/java/com/clerk/api/auth/AuthTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,26 @@ class AuthTest {
coVerify(exactly = 0) { signInApi.prepareSignInFirstFactor(any(), any()) }
}

@Test
fun `signInWithTicket creates sign in with ticket strategy`() = runTest {
val signInApi = mockk<SignInApi>()
val createdSignIn = SignIn(id = "sign_in_123")
val createParams = slot<Map<String, String>>()
mockkObject(ClerkApi)
every { ClerkApi.signIn } returns signInApi
coEvery { signInApi.createSignIn(capture(createParams)) } returns
ClerkResult.success(createdSignIn)

val result = Auth().signInWithTicket("ticket_123")

assertTrue(result is ClerkResult.Success)
assertSame(createdSignIn, (result as ClerkResult.Success).value)
assertEquals("ticket", createParams.captured["strategy"])
assertEquals("ticket_123", createParams.captured["ticket"])
assertTrue(createParams.captured.containsKey("locale"))
coVerify(exactly = 1) { signInApi.createSignIn(any()) }
}

@Test
fun `sessions exposes all sessions on the current client`() {
val firstSession = testSession("sess_1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,62 @@ class ClientSyncingMiddlewareTest {
assertEquals(listOf(session), Clerk.sessionsFlow.value)
}

@Test
fun `ticket sign in syncs session with active organization`() {
val middleware = ClientSyncingMiddleware(json = ClerkApi.json)
val request =
Request.Builder()
.url("https://api.clerk.com/v1/client/sign_ins")
.post(
"strategy=ticket&ticket=ticket_123"
.toRequestBody("application/x-www-form-urlencoded".toMediaType())
)
.build()
val response =
Response.Builder()
.request(request)
.protocol(Protocol.HTTP_1_1)
.code(200)
.message("OK")
.body(
"""
{
"response": {
"id": "sign_in_123",
"status": "complete",
"created_session_id": "sess_123"
},
"client": {
"id": "client_123",
"sessions": [
{
"id": "sess_123",
"status": "active",
"expire_at": 10000,
"last_active_at": 1000,
"last_active_organization_id": "org_123",
"created_at": 1000,
"updated_at": 1000
}
],
"last_active_session_id": "sess_123"
}
}
"""
.trimIndent()
.toResponseBody("application/json".toMediaType())
)
.build()
val chain = mockk<Interceptor.Chain>()
every { chain.request() } returns request
every { chain.proceed(request) } returns response

middleware.intercept(chain)

assertEquals("sess_123", Clerk.sessionFlow.value?.id)
assertEquals("org_123", Clerk.sessionFlow.value?.lastActiveOrganizationId)
}

@Test
fun `intercept hydrates direct client response with server date`() {
val middleware = ClientSyncingMiddleware(json = ClerkApi.json)
Expand Down