Skip to content

Commit

Permalink
Merge pull request #4483 from Shopify/jm/bp-4473
Browse files Browse the repository at this point in the history
[3.67] - Ensure that theme store is initialized in local storage when validating storefront password
  • Loading branch information
jamesmengo committed Sep 19, 2024
2 parents 8410e97 + 28de21b commit a1fcc90
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .changeset/metal-eggs-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@shopify/theme': patch
'@shopify/app': patch
---

Fixes a bug where some users were unable to intialize their app dev command with theme app extensions
16 changes: 8 additions & 8 deletions packages/theme/src/cli/services/local-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface ThemeStorePasswordSchema {
let _themeLocalStorageInstance: LocalStorage<ThemeLocalStorageSchema> | undefined
let _developmentThemeLocalStorageInstance: LocalStorage<DevelopmentThemeLocalStorageSchema> | undefined
let _replThemeLocalStorageInstance: LocalStorage<DevelopmentThemeLocalStorageSchema> | undefined
let _themeStoreLocalStorageInstance: LocalStorage<ThemeStorePasswordSchema> | undefined
let _themeStorePasswordStorageInstance: LocalStorage<ThemeStorePasswordSchema> | undefined

function themeLocalStorage() {
if (!_themeLocalStorageInstance) {
Expand All @@ -45,13 +45,13 @@ function replThemeLocalStorage() {
return _replThemeLocalStorageInstance
}

function themeStoreLocalStorage() {
if (!_themeStoreLocalStorageInstance) {
_themeStoreLocalStorageInstance = new LocalStorage<ThemeStorePasswordSchema>({
function themeStorePasswordStorage() {
if (!_themeStorePasswordStorageInstance) {
_themeStorePasswordStorageInstance = new LocalStorage<ThemeStorePasswordSchema>({
projectName: 'shopify-cli-theme-store-password',
})
}
return _themeStoreLocalStorageInstance
return _themeStorePasswordStorageInstance
}

export function getThemeStore() {
Expand Down Expand Up @@ -95,17 +95,17 @@ export function removeREPLTheme(): void {
export function getStorefrontPassword(): string | undefined {
const themeStore = getThemeStore()
outputDebug(outputContent`Getting storefront password for shop ${themeStore}...`)
return themeStoreLocalStorage().get(getThemeStore())
return themeStorePasswordStorage().get(getThemeStore())
}

export function setStorefrontPassword(password: string): void {
const themeStore = getThemeStore()
outputDebug(outputContent`Setting storefront password for shop ${themeStore}...`)
themeStoreLocalStorage().set(themeStore, password)
themeStorePasswordStorage().set(themeStore, password)
}

export function removeStorefrontPassword(): void {
const themeStore = getThemeStore()
outputDebug(outputContent`Removing storefront password for ${themeStore}...`)
themeStoreLocalStorage().delete(themeStore)
themeStorePasswordStorage().delete(themeStore)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import {ensureValidPassword} from './storefront-password-prompt.js'
import {isStorefrontPasswordProtected, isStorefrontPasswordCorrect} from './storefront-session.js'
import {getStorefrontPassword, removeStorefrontPassword, setStorefrontPassword} from '../../services/local-storage.js'
import {
getStorefrontPassword,
getThemeStore,
removeStorefrontPassword,
setStorefrontPassword,
} from '../../services/local-storage.js'
import {ensureThemeStore} from '../theme-store.js'
import {renderTextPrompt} from '@shopify/cli-kit/node/ui'
import {describe, beforeEach, vi, test, expect} from 'vitest'

vi.mock('@shopify/cli-kit/node/ui')
vi.mock('../theme-environment/storefront-session.js')
vi.mock('../../services/local-storage.js')
vi.mock('../theme-store.js')
vi.mock('../utilities/repl-theme-manager.js', () => {
const REPLThemeManager = vi.fn()
REPLThemeManager.prototype.findOrCreate = () => ({
Expand Down Expand Up @@ -91,4 +98,17 @@ describe('ensureValidPassword', () => {
expect(setStorefrontPassword).toHaveBeenCalledWith('correctPassword')
expect(removeStorefrontPassword).toHaveBeenCalled()
})

test('should call ensureThemeStore with the store URL', async () => {
// Given
vi.mocked(isStorefrontPasswordProtected).mockResolvedValue(true)
vi.mocked(isStorefrontPasswordCorrect).mockResolvedValue(true)
vi.mocked(getThemeStore).mockReturnValue(undefined as any)

// When
await ensureValidPassword('testPassword', 'test-store')

// Then
expect(ensureThemeStore).toHaveBeenCalledWith({store: 'test-store'})
})
})
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import {isStorefrontPasswordCorrect} from './storefront-session.js'
import {getStorefrontPassword, removeStorefrontPassword, setStorefrontPassword} from '../../services/local-storage.js'
import {
getStorefrontPassword,
getThemeStore,
removeStorefrontPassword,
setStorefrontPassword,
} from '../../services/local-storage.js'
import {ensureThemeStore} from '../theme-store.js'
import {renderTextPrompt} from '@shopify/cli-kit/node/ui'

export async function ensureValidPassword(password: string | undefined, store: string) {
/*
* This allows us to call ensureValidPassword() in other packages
* without the need to explicitly import and call ensureThemeStore() upstream
*/
if (!getThemeStore()) {
ensureThemeStore({store})
}

let finalPassword = password || getStorefrontPassword() || (await promptPassword('Enter your store password'))
let isPasswordRemoved = false

Expand Down

0 comments on commit a1fcc90

Please sign in to comment.