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

feature(locksmith): Update access control for checkoutConfigs #14833

Merged
merged 24 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
24 changes: 15 additions & 9 deletions locksmith/src/controllers/v2/checkoutController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,20 @@ export const createOrUpdateCheckoutConfig: RequestHandler = async (
createdBy: request.user!.walletAddress,
})

if (!createdConfig) {
return response.status(403).send({
message:
'Unauthorized: You do not have permission to create or update this configuration.',
})
}

return response.status(200).send({
id: createdConfig.id,
by: createdConfig.createdBy,
name: createdConfig.name,
config: createdConfig.config,
updatedAt: createdConfig.updatedAt.toISOString(),
createdAt: createdConfig.createdAt.toISOString(),
id: createdConfig?.id,
by: createdConfig?.createdBy,
name: createdConfig?.name,
config: createdConfig?.config,
updatedAt: createdConfig?.updatedAt.toISOString(),
createdAt: createdConfig?.createdAt.toISOString(),
})
0xTxbi marked this conversation as resolved.
Show resolved Hide resolved
} catch (error) {
console.error('Error creating/updating checkout config:', error)
Expand Down Expand Up @@ -113,9 +120,8 @@ export const deleteCheckoutConfig: RequestHandler = async (
const deleted = await deleteCheckoutConfigOperation(userAddress, id)
0xTxbi marked this conversation as resolved.
Show resolved Hide resolved

if (!deleted) {
return response.status(403).send({
message:
'Unauthorized: You do not have permission to delete this configuration.',
return response.status(404).send({
0xTxbi marked this conversation as resolved.
Show resolved Hide resolved
message: 'Config not found or you do not have permission to delete it.',
})
}

Expand Down
37 changes: 13 additions & 24 deletions locksmith/src/operations/checkoutConfigOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { PaywallConfig } from '@unlock-protocol/core'
import { Web3Service } from '@unlock-protocol/unlock-js'
import networks from '@unlock-protocol/networks'

const web3Service = new Web3Service(networks)

interface SaveCheckoutConfigArgs {
id?: string
name: string
Expand Down Expand Up @@ -42,6 +40,7 @@ const isLockManager = async (
userAddress: string,
network: number
): Promise<boolean> => {
const web3Service = new Web3Service(networks)
try {
return await web3Service.isLockManager(lockAddress, userAddress, network)
} catch (error) {
Expand Down Expand Up @@ -78,7 +77,7 @@ const isUserAuthorized = async (
/**
* Creates or updates a checkout configuration
* @param args - The SaveCheckoutConfigArgs object
* @returns The created or updated checkout configuration
* @returns The created or updated checkout configuration or null if not authorized
*/
export const saveCheckoutConfig = async ({
id,
Expand All @@ -95,6 +94,17 @@ export const saveCheckoutConfig = async ({
checkoutConfigData.referrer = createdBy
}

// Check if the user is authorized to save/update the config
if (id) {
const existingConfig = await CheckoutConfig.findOne({ where: { id } })
if (
existingConfig &&
!(await isUserAuthorized(createdBy, existingConfig))
0xTxbi marked this conversation as resolved.
Show resolved Hide resolved
) {
return null
}
}

const [createdConfig] = await CheckoutConfig.upsert(
{
id: generatedId,
0xTxbi marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -133,27 +143,6 @@ export const getCheckoutConfigById = async (id: string) => {
return null
}

/**
* Checks if a user is authorized to manage a specific checkout config
* @param userAddress - The address of the user
* @param configId - The ID of the checkout configuration
* @returns A boolean indicating whether the user is authorized
*/
export const isAuthorizedToManageConfig = async (
userAddress: string,
configId: string
): Promise<boolean> => {
const checkoutConfig = await CheckoutConfig.findOne({
where: {
id: configId,
},
})
if (!checkoutConfig) {
return false
}
return isUserAuthorized(userAddress, checkoutConfig)
}

export const getCheckoutConfigsByUserOperation = async (
0xTxbi marked this conversation as resolved.
Show resolved Hide resolved
userAddress: string
) => {
Expand Down
Loading