Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use RNSecureKeyStore for auth token persistent storage #3122

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3b09a63
Use RNSecureKeyStore for auth token persistent storage
2624789 Mar 19, 2024
1d9ec4e
Fix typo
2624789 Mar 25, 2024
3159fbd
ci: nixify concourse setup (#3127)
sandipndev Mar 21, 2024
b23a521
ci: fix for prod builds
sandipndev Mar 22, 2024
c986671
ci: fix version file name for prod
sandipndev Mar 22, 2024
a120fee
feat: add price and marketing settings (#3124)
UncleSamtoshi Mar 22, 2024
0274c56
ci: testflight version was missing
sandipndev Mar 23, 2024
06c91ed
test(e2e): detox tests (#3126)
sandipndev Mar 23, 2024
da3a6ca
chore: updating react native vision library to 3.9.1 (#3130)
nicolasburtey Mar 24, 2024
957f7d6
chore: forceExit to build the mobile app (#3132)
nicolasburtey Mar 25, 2024
c09c117
chore: update firebase / fix crash on ios (#3131)
nicolasburtey Mar 25, 2024
7e5385d
feat: april circles challenge (#3133)
UncleSamtoshi Mar 25, 2024
dfcfe32
Updates for file app/i18n/raw-i18n/source/en.json (#3134)
transifex-integration[bot] Mar 25, 2024
e38808f
chore: getting to prior firebase version (#3138)
nicolasburtey Mar 26, 2024
9097cc8
feat: conversation screen (#2995)
nicolasburtey Mar 28, 2024
5fa5a6f
chore: update build numbers for mobile v2.2.239 (#3141)
galoybot-app[bot] Mar 28, 2024
4cc76b8
fix: confirm payment slider bug in rtl layouts (#3143)
Prakhar-Agarwal-byte Mar 28, 2024
dfbd075
feat: Add link opening functionality in ScanningQRCodeScreen (#3145)
Prakhar-Agarwal-byte Mar 29, 2024
bffc32a
chore: putting ErrorBoundary within NavigationContainer (#3147)
nicolasburtey Mar 30, 2024
9fef057
Updates for file app/i18n/raw-i18n/source/en.json (#3152)
transifex-integration[bot] Apr 2, 2024
c552828
feat: settings screen fresh look (#2893)
sandipndev Apr 5, 2024
f04f7d5
feat: send flow but animated (#3148)
sandipndev Apr 5, 2024
3292855
chore: css fix for large usernames on settings screen
sandipndev Apr 5, 2024
a5b88c9
fix: css issue - weird rendering of send payment screen
sandipndev Apr 5, 2024
741766d
fix: secondary amount display in send payment screen
sandipndev Apr 5, 2024
362e7aa
chore: addressing feedback for settings screen update (#3155)
sandipndev Apr 5, 2024
f4412a2
fix: send animations have minimum duration, end loops removed (#3156)
sandipndev Apr 6, 2024
951a53c
chore: port to dotlottie files (#3157)
sandipndev Apr 6, 2024
6ed668d
ci: upload recordings to gcs (#3153)
sandipndev Apr 6, 2024
f51f68c
chore: restructuring data around settings screen (#3159)
sandipndev Apr 9, 2024
2f33401
revert: send animations (#3162)
sandipndev Apr 10, 2024
d0aec1b
feat: dashboard access (#3161)
sandipndev Apr 10, 2024
377a6a5
Use RNSecureKeyStore for auth token persistent storage
2624789 Mar 19, 2024
56e319d
Fix typo
2624789 Mar 25, 2024
54f055c
Merge branch 'GaloyMoney:main' into 848-use-react-native-keychain
2624789 Apr 11, 2024
c6dbe9d
Renames PersistentState to LocalStorageState
2624789 Apr 11, 2024
b4e05c9
Renames PersistentState to LocalStorageState
2624789 Apr 11, 2024
e6d18db
Merge branch '848-use-react-native-keychain' of https://github.com/26…
2624789 Apr 11, 2024
a9952a8
Fixed persistent storage tests
2624789 Apr 12, 2024
7013cca
Fixed existing tests
2624789 Apr 15, 2024
a5a1f53
Add tests for state migration from 4 to 7
2624789 Apr 15, 2024
014ff99
Add tests for state migration from 3 to 7
2624789 Apr 15, 2024
3973d10
Fix test filename
2624789 Apr 17, 2024
34a7988
Adds tests for KeyStoreWrapper
2624789 Apr 17, 2024
c13a93a
Refactor persitent state test files structure
2624789 Apr 23, 2024
7c57dbd
Adds loads persistent state test
2624789 Apr 23, 2024
fdec0ee
Merge branch 'main' into 848-use-react-native-keychain
2624789 Apr 23, 2024
c46b065
Merge branch 'main' into 848-use-react-native-keychain
2624789 Apr 25, 2024
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
11 changes: 3 additions & 8 deletions .storybook/views/story-screen.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import * as React from "react"
import { PersistentStateContext } from "../../app/store/persistent-state"
import { PersistentStateContext } from "@app/store/persistent-state"
import { defaultPersistentState } from "@app/store/persistent-state/state-migrations"

const PersistentStateWrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
<PersistentStateContext.Provider
value={{
persistentState: {
schemaVersion: 6,
galoyInstance: {
id: "Main",
},
galoyAuthToken: "",
},
persistentState: defaultPersistentState,
updateState: () => {},
resetState: () => {},
}}
Expand Down
30 changes: 30 additions & 0 deletions __mocks__/react-native-secure-key-store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ACCESSIBLE } from "react-native-secure-key-store"

export { ACCESSIBLE }

class RNSecureKeyStoreMock {
store

constructor() {
this.store = new Map()
}

get(k) {
const result = this.store.get(k)
return Promise.resolve(result)
}

remove(k) {
this.store.delete(k)
return Promise.resolve(true)
}

set(k, value) {
this.store.set(k, value)
return Promise.resolve(true)
}
}

const RNSecureKeyStore = new RNSecureKeyStoreMock()

export default RNSecureKeyStore
44 changes: 0 additions & 44 deletions __tests__/persistent-storage.spec.ts

This file was deleted.

50 changes: 50 additions & 0 deletions __tests__/store/persistent-state/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from "react"
import { View, Text } from "react-native"

import {
PersistentStateProvider,
usePersistentStateContext,
} from "@app/store/persistent-state"
import * as StateMigrations from "@app/store/persistent-state/state-migrations"
import KeyStoreWrapper from "@app/utils/storage/secureStorage"
import { act, render } from "@testing-library/react-native"

const MockConsumer: React.FC = () => {
const { persistentState } = usePersistentStateContext()
const { galoyAuthToken, schemaVersion, galoyInstance } = persistentState

return (
<View>
<Text>{schemaVersion}</Text>
<Text>{galoyAuthToken}</Text>
<Text>{galoyInstance.id}</Text>
</View>
)
}

describe("PersistentStateProvider", () => {
it("loads persistent state from storage and secure storage", async () => {
const getSecureStorageStateSpy = jest.spyOn(KeyStoreWrapper, "getSecureStorageState")
const migrateAndGetLocalStorageStateSpy = jest.spyOn(
StateMigrations,
"migrateAndGetLocalStorageState",
)

getSecureStorageStateSpy.mockResolvedValue({ galoyAuthToken: "myToken" })
migrateAndGetLocalStorageStateSpy.mockResolvedValue({
schemaVersion: 7,
galoyInstance: { id: "Main" },
})

const { getByText } = render(
<PersistentStateProvider>
<MockConsumer />
</PersistentStateProvider>,
)
await act(async () => {})

expect(getByText("7")).toBeTruthy()
expect(getByText("myToken")).toBeTruthy()
expect(getByText("Main")).toBeTruthy()
})
})
185 changes: 185 additions & 0 deletions __tests__/store/persistent-state/state-migrations.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import {
defaultLocalStorageState,
migrateAndGetLocalStorageState,
} from "@app/store/persistent-state/state-migrations"

describe("migrateAndGetLocalStorageState", () => {
it("uses default state when none is present", async () => {
const state = await migrateAndGetLocalStorageState({})
expect(state).toEqual(defaultLocalStorageState)
})

it("migrates persistent state", async () => {
const state = await migrateAndGetLocalStorageState({
schemaVersion: 0,
isUsdDisabled: true,
})
expect(state).toEqual({
...defaultLocalStorageState,
})
})

it("returns default when schema is not present", async () => {
const state = await migrateAndGetLocalStorageState({
schemaVersion: -2,
})
expect(state).toEqual(defaultLocalStorageState)
})

it("migrates instance from 3 to 7 ", async () => {
const state3 = {
schemaVersion: 3,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "Blink" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Main" },
}

const res = await migrateAndGetLocalStorageState(state3)

expect(res).toStrictEqual(state7)
})

it("migrates unknown instance from 3 to 7 ", async () => {
const state3 = {
schemaVersion: 3,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "Unknown" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Main" },
}

const res = await migrateAndGetLocalStorageState(state3)

expect(res).toStrictEqual(state7)
})

it("migrates Blink instance from 4 to 7 ", async () => {
const state4 = {
schemaVersion: 4,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "Blink" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Main" },
}

const res = await migrateAndGetLocalStorageState(state4)

expect(res).toStrictEqual(state7)
})

it("migrates Staging instance from 4 to 7 ", async () => {
const state4 = {
schemaVersion: 4,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "Staging" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Staging" },
}

const res = await migrateAndGetLocalStorageState(state4)

expect(res).toStrictEqual(state7)
})

it("migrates Local instance from 4 to 7 ", async () => {
const state4 = {
schemaVersion: 4,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "Local" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Local" },
}

const res = await migrateAndGetLocalStorageState(state4)

expect(res).toStrictEqual(state7)
})

it("migrates BBW instance from 4 to 7", async () => {
const state4 = {
schemaVersion: 4,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "BBW" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Main" },
}

const res = await migrateAndGetLocalStorageState(state4)

expect(res).toStrictEqual(state7)
})

it("migrates Custom instance from 4 to 7", async () => {
const state4 = {
schemaVersion: 4,
hasShownStableSatsWelcome: true,
isUsdDisabled: true,
galoyInstance: { id: "Main", name: "Custom" },
galoyAuthToken: "token",
isAnalyticsEnabled: false,
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Custom", name: "Custom" },
}

const res = await migrateAndGetLocalStorageState(state4)

expect(res).toStrictEqual(state7)
})

it("migration from 5 to 7", async () => {
const state5 = {
schemaVersion: 5,
galoyInstance: { id: "Main" },
galoyAuthToken: "myToken",
}

const state7 = {
schemaVersion: 7,
galoyInstance: { id: "Main" },
}

const res = await migrateAndGetLocalStorageState(state5)

expect(res).toStrictEqual(state7)
})
})
Loading
Loading