Skip to content

Commit

Permalink
Merge pull request #601 from panoratech/feat-Upgrade-API-Keys-to-sk_e…
Browse files Browse the repository at this point in the history
…nv_UUID

Feat upgrade api keys
  • Loading branch information
naelob authored Aug 3, 2024
2 parents c571494 + a77e17d commit 5fe0657
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 141 deletions.
40 changes: 37 additions & 3 deletions apps/webapp/src/app/(Dashboard)/api-keys/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,37 @@ const formSchema = z.object({
interface TSApiKeys {
id_api_key: string;
name : string;
token : string;
}

export default function Page() {
const [open,setOpen] = useState(false)
const [tsApiKeys,setTSApiKeys] = useState<TSApiKeys[] | undefined>([])
const [isKeyModalOpen, setIsKeyModalOpen] = useState(false);

const queryClient = useQueryClient();

const queryClient = useQueryClient();
const [newApiKey, setNewApiKey] = useState<{ key: string; expiration: Date } | null>(null);
const {idProject} = useProjectStore();
const {profile} = useProfileStore();
const { createApiKeyPromise } = useCreateApiKey();
const { data: apiKeys, isLoading, error } = useApiKeys();
const columns = useColumns();

useEffect(() => {
if (newApiKey) {
const timeUntilExpiration = newApiKey.expiration.getTime() - Date.now();
const timer = setTimeout(() => {
setNewApiKey(null);
}, timeUntilExpiration);

return () => clearTimeout(timer);
}
}, [newApiKey]);

useEffect(() => {
const temp_tsApiKeys = apiKeys?.map((key) => ({
id_api_key: key.id_api_key,
name: key.name || "",
token: key.api_key_hash,
}))
setTSApiKeys(temp_tsApiKeys)
},[apiKeys])
Expand Down Expand Up @@ -107,6 +118,13 @@ export default function Page() {
queryClient.setQueryData<any[]>(['api-keys'], (oldQueryData = []) => {
return [...oldQueryData, data];
});
// Store the API key and its expiration time in state
setNewApiKey({
key: data.api_key,
expiration: new Date(Date.now() + 60000),
});
setIsKeyModalOpen(true); // Open the modal

return (
<div className="flex flex-row items-center">
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.49991 0.877045C3.84222 0.877045 0.877075 3.84219 0.877075 7.49988C0.877075 11.1575 3.84222 14.1227 7.49991 14.1227C11.1576 14.1227 14.1227 11.1575 14.1227 7.49988C14.1227 3.84219 11.1576 0.877045 7.49991 0.877045ZM1.82708 7.49988C1.82708 4.36686 4.36689 1.82704 7.49991 1.82704C10.6329 1.82704 13.1727 4.36686 13.1727 7.49988C13.1727 10.6329 10.6329 13.1727 7.49991 13.1727C4.36689 13.1727 1.82708 10.6329 1.82708 7.49988ZM10.1589 5.53774C10.3178 5.31191 10.2636 5.00001 10.0378 4.84109C9.81194 4.68217 9.50004 4.73642 9.34112 4.96225L6.51977 8.97154L5.35681 7.78706C5.16334 7.59002 4.84677 7.58711 4.64973 7.78058C4.45268 7.97404 4.44978 8.29061 4.64325 8.48765L6.22658 10.1003C6.33054 10.2062 6.47617 10.2604 6.62407 10.2483C6.77197 10.2363 6.90686 10.1591 6.99226 10.0377L10.1589 5.53774Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
Expand Down Expand Up @@ -225,6 +243,22 @@ export default function Page() {
{tsApiKeys && <DataTable data={tsApiKeys} columns={columns} />}
</Suspense>
</div>
<Dialog open={isKeyModalOpen} onOpenChange={setIsKeyModalOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Your New API Key</DialogTitle>
<DialogDescription>
This key will only be shown for the next minute. Please save it now.
</DialogDescription>
</DialogHeader>
<div className="mt-4">
<strong>API Key:</strong> <p>{newApiKey?.key}</p>
</div>
<DialogFooter>
<Button size="sm" className="h-7 gap-1" onClick={() => setIsKeyModalOpen(false)}>Close</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
);
}
45 changes: 0 additions & 45 deletions apps/webapp/src/components/ApiKeys/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,51 +45,6 @@ export function useColumns() {
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "token",
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Token" />
),
cell: ({ row }) => {
const token: string = row.getValue("token");
const copied = copiedState[token] || false;

return (
<div className="flex items-center">
<div className="truncate mr-2">
<PasswordInput value={token} readOnly className="rounded-xl" />
</div>
<div
className="cursor-pointer"
onClick={() => handleCopy(token)}
>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button size="sm" variant="outline">{copied ? (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="15" height="15" fill="#ffffff">
<path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/>
</svg>
) : (
<>
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 2V1H10V2H5ZM4.75 0C4.33579 0 4 0.335786 4 0.75V1H3.5C2.67157 1 2 1.67157 2 2.5V12.5C2 13.3284 2.67157 14 3.5 14H11.5C12.3284 14 13 13.3284 13 12.5V2.5C13 1.67157 12.3284 1 11.5 1H11V0.75C11 0.335786 10.6642 0 10.25 0H4.75ZM11 2V2.25C11 2.66421 10.6642 3 10.25 3H4.75C4.33579 3 4 2.66421 4 2.25V2H3.5C3.22386 2 3 2.22386 3 2.5V12.5C3 12.7761 3.22386 13 3.5 13H11.5C11.7761 13 12 12.7761 12 12.5V2.5C12 2.22386 11.7761 2 11.5 2H11Z" fill="currentColor" fillRule="evenodd" clipRule="evenodd"></path>
</svg>
</>
)}
</Button>
</TooltipTrigger>
<TooltipContent>
<p className="text-sm">Copy Key</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>

</div>
</div>
);
},
},
{
id: "actions",
cell: ({ row }) => <DataTableRowActions row={row} object={"api-key"}/>,
Expand Down
1 change: 0 additions & 1 deletion apps/webapp/src/components/ApiKeys/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { z } from "zod"
export const apiKeySchema = z.object({
id_api_key: z.string(),
name: z.string(),
token: z.string(),
})

export type ApiKey = z.infer<typeof apiKeySchema>
2 changes: 1 addition & 1 deletion apps/webapp/src/hooks/delete/useDeleteApiKey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface IApiKeyDto {

const useDeleteApiKey = () => {
const remove = async (apiKeyData: IApiKeyDto) => {
const response = await fetch(`${config.API_URL}/auth/api-keys/${apiKeyData.id_api_key}`, {
const response = await fetch(`${config.API_URL}/auth/api_keys/${apiKeyData.id_api_key}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
Expand Down
1 change: 1 addition & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ services:
context: ./
dockerfile: ./packages/api/Dockerfile.dev
environment:
ENV: ${ENV}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/${POSTGRES_DB}?ssl=false
DISTRIBUTION: ${DISTRIBUTION}
WEBHOOK_INGRESS: ${WEBHOOK_INGRESS}
Expand Down
1 change: 1 addition & 0 deletions docker-compose.source.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ services:
context: ./
dockerfile: ./packages/api/Dockerfile
environment:
ENV: ${ENV}
DOPPLER_TOKEN: ${DOPPLER_TOKEN_API}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/${POSTGRES_DB}?ssl=false
DISTRIBUTION: ${DISTRIBUTION}
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ services:
api:
image: panora.docker.scarf.sh/panoradotdev/backend-api:selfhosted
environment:
ENV: ${ENV}
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/${POSTGRES_DB}?ssl=false
DISTRIBUTION: ${DISTRIBUTION}
WEBHOOK_INGRESS: ${WEBHOOK_INGRESS}
Expand Down
67 changes: 40 additions & 27 deletions packages/api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -1637,17 +1637,18 @@ model acc_vendor_credits {
}

model ecom_customers {
id_ecom_customer String @id(map: "pk_ecom_customers") @db.Uuid
remote_id String?
email String?
first_name String?
last_name String?
phone_number String?
modifed_at DateTime @db.Timestamptz(6)
created_at DateTime @db.Timestamptz(6)
id_connection String @db.Uuid
ecom_customer_addresses ecom_customer_addresses[]
ecom_orders ecom_orders[]
id_ecom_customer String @id(map: "pk_ecom_customers") @db.Uuid
remote_id String?
email String?
first_name String?
last_name String?
phone_number String?
modified_at DateTime @db.Timestamptz(6)
created_at DateTime @db.Timestamptz(6)
id_connection String @db.Uuid
remote_deleted Boolean
ecom_addresses ecom_addresses[]
ecom_orders ecom_orders[]
}

/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
Expand Down Expand Up @@ -1681,8 +1682,10 @@ model ecom_orders {
remote_id String?
id_ecom_customer String? @db.Uuid
id_connection String @db.Uuid
modifed_at DateTime @db.Timestamptz(6)
modified_at DateTime @db.Timestamptz(6)
created_at DateTime @db.Timestamptz(6)
remote_deleted Boolean
ecom_addresses ecom_addresses[]
ecom_fulfilments ecom_fulfilments[]
ecom_customers ecom_customers? @relation(fields: [id_ecom_customer], references: [id_ecom_customer], onDelete: NoAction, onUpdate: NoAction, map: "fk_ecom_customer_orders")
Expand Down Expand Up @@ -1725,21 +1728,31 @@ model ecom_products {
}

/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
model ecom_customer_addresses {
id_ecom_customer_address String @id(map: "pk_ecom_customer_addresses") @db.Uuid
address_type String?
line_1 String?
line_2 String?
street_1 String?
street_2 String?
city String?
state String?
postal_code String?
country String?
id_ecom_customer String @db.Uuid
modified_at DateTime @db.Timestamptz(6)
created_at DateTime @db.Timestamptz(6)
ecom_customers ecom_customers @relation(fields: [id_ecom_customer], references: [id_ecom_customer], onDelete: NoAction, onUpdate: NoAction, map: "fk_ecom_customer_customeraddress")
model ecom_addresses {
id_ecom_address String @id(map: "pk_ecom_customer_addresses") @db.Uuid
address_type String?
street_1 String?
street_2 String?
city String?
state String?
postal_code String?
country String?
id_ecom_customer String @db.Uuid
modified_at DateTime @db.Timestamptz(6)
created_at DateTime @db.Timestamptz(6)
remote_deleted Boolean
id_ecom_order String @db.Uuid
ecom_customers ecom_customers @relation(fields: [id_ecom_customer], references: [id_ecom_customer], onDelete: NoAction, onUpdate: NoAction, map: "fk_ecom_customer_customeraddress")
ecom_orders ecom_orders @relation(fields: [id_ecom_order], references: [id_ecom_order], onDelete: NoAction, onUpdate: NoAction, map: "fk_ecom_order_address")
@@index([id_ecom_customer], map: "fk_index_ecom_customer_customeraddress")
@@index([id_ecom_order], map: "fk_index_fk_ecom_order_address")
}

model ecom_fulfilment_orders {
id_ecom_fulfilment_order String @id(map: "pk_ecom_fulfilment_order") @db.Uuid
}

model ecom_order_line_items {
id_ecom_order_line_item String @id(map: "pk_106") @db.Uuid
}
Loading

0 comments on commit 5fe0657

Please sign in to comment.