Skip to content

Commit

Permalink
feat: unlink alby account
Browse files Browse the repository at this point in the history
  • Loading branch information
rolznz committed Jul 26, 2024
1 parent 45600ee commit fdf7baa
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 1 deletion.
9 changes: 9 additions & 0 deletions alby/alby_oauth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,15 @@ func (svc *albyOAuthService) GetAuthUrl() string {
return svc.oauthConf.AuthCodeURL("unused")
}

func (svc *albyOAuthService) UnlinkAccount(ctx context.Context) error {
svc.cfg.SetUpdate(userIdentifierKey, "", "")
svc.cfg.SetUpdate(accessTokenKey, "", "")
svc.cfg.SetUpdate(accessTokenExpiryKey, "", "")
svc.cfg.SetUpdate(refreshTokenKey, "", "")

return nil
}

func (svc *albyOAuthService) LinkAccount(ctx context.Context, lnClient lnclient.LNClient, budget uint64, renewal string) error {
connectionPubkey, err := svc.createAlbyAccountNWCNode(ctx)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions alby/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type AlbyOAuthService interface {
GetMe(ctx context.Context) (*AlbyMe, error)
SendPayment(ctx context.Context, invoice string) error
DrainSharedWallet(ctx context.Context, lnClient lnclient.LNClient) error
UnlinkAccount(ctx context.Context) error
RequestAutoChannel(ctx context.Context, lnClient lnclient.LNClient, isPublic bool) (*AutoChannelResponse, error)
}

Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/layouts/SettingsLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export default function SettingsLayout() {
{hasNodeBackup && (
<MenuItem to="/settings/node-backup">Migrate Node</MenuItem>
)}
<MenuItem to="/settings/alby-account">Alby Account</MenuItem>
<MenuItem to="/debug-tools">
Debug Tools
<ExternalLink className="w-4 h-4 ml-2" />
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import BuyBitcoin from "src/screens/onchain/BuyBitcoin";
import DepositBitcoin from "src/screens/onchain/DepositBitcoin";
import ConnectPeer from "src/screens/peers/ConnectPeer";
import Peers from "src/screens/peers/Peers";
import { AlbyAccount } from "src/screens/settings/AlbyAccount";
import { ChangeUnlockPassword } from "src/screens/settings/ChangeUnlockPassword";
import DebugTools from "src/screens/settings/DebugTools";
import Settings from "src/screens/settings/Settings";
Expand Down Expand Up @@ -129,6 +130,10 @@ const routes = [
path: "node-backup",
element: <BackupNode />,
},
{
path: "alby-account",
element: <AlbyAccount />,
},
],
},
],
Expand Down
93 changes: 93 additions & 0 deletions frontend/src/screens/settings/AlbyAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { ExitIcon } from "@radix-ui/react-icons";
import { ExternalLinkIcon } from "lucide-react";

import ExternalLink from "src/components/ExternalLink";
import SettingsHeader from "src/components/SettingsHeader";
import {
Card,
CardDescription,
CardHeader,
CardTitle,
} from "src/components/ui/card";
import { useToast } from "src/components/ui/use-toast";
import { useCSRF } from "src/hooks/useCSRF";
import { useInfo } from "src/hooks/useInfo";
import { request } from "src/utils/request";

export function AlbyAccount() {
const { data: csrf } = useCSRF();
const { toast } = useToast();
const { mutate: refetchInfo } = useInfo();

const unlink = async () => {
if (
!confirm(
"Please log out at https://getalby.com, then click ok to continue."
)
) {
return;
}

if (
!confirm("Are you sure you want to change the Alby Account for your hub?")
) {
return;
}

try {
if (!csrf) {
throw new Error("No CSRF token");
}
await request("/api/alby/unlink-account", {
method: "POST",
headers: {
"X-CSRF-Token": csrf,
"Content-Type": "application/json",
},
});
await refetchInfo();
toast({
title: "Alby Account Unlinked",
description: "Please login with another Alby Account",
});
} catch (error) {
toast({
title: "Unlink account failed",
description: (error as Error).message,
variant: "destructive",
});
}
};

return (
<>
<SettingsHeader
title="Alby Account"
description="Manage your Alby Account"
/>
<ExternalLink
to="https://getalby.com/settings"
className="w-full flex flex-row items-center gap-2"
>
<Card className="w-full">
<CardHeader>
<CardTitle>Your Alby Account</CardTitle>
<CardDescription className="flex gap-2 items-center">
<ExternalLinkIcon className="w-4 h-4" /> Manage your Alby Account
Settings
</CardDescription>
</CardHeader>
</Card>
</ExternalLink>
<Card className="w-full cursor-pointer" onClick={unlink}>
<CardHeader>
<CardTitle>Change Alby Account</CardTitle>
<CardDescription className="flex gap-2 items-center">
<ExitIcon className="w-4 h-4" /> Link your Hub to a different Alby
Account
</CardDescription>
</CardHeader>
</Card>
</>
);
}
17 changes: 16 additions & 1 deletion http/alby_http_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func (albyHttpSvc *AlbyHttpService) RegisterSharedRoutes(e *echo.Echo, authMiddl
e.POST("/api/alby/drain", albyHttpSvc.albyDrainHandler, authMiddleware)
e.POST("/api/alby/link-account", albyHttpSvc.albyLinkAccountHandler, authMiddleware)
e.POST("/api/alby/auto-channel", albyHttpSvc.autoChannelHandler, authMiddleware)
e.POST("/api/alby/unlink-account", albyHttpSvc.unlinkHandler, authMiddleware)
}

func (albyHttpSvc *AlbyHttpService) autoChannelHandler(c echo.Context) error {
Expand All @@ -49,13 +50,27 @@ func (albyHttpSvc *AlbyHttpService) autoChannelHandler(c echo.Context) error {

if err != nil {
return c.JSON(http.StatusInternalServerError, ErrorResponse{
Message: fmt.Sprintf("Failed to request wrapped invoice: %s", err.Error()),
Message: fmt.Sprintf("Failed to request auto channel: %s", err.Error()),
})
}

return c.JSON(http.StatusOK, autoChannelResponseResponse)
}

func (albyHttpSvc *AlbyHttpService) unlinkHandler(c echo.Context) error {
ctx := c.Request().Context()

err := albyHttpSvc.albyOAuthSvc.UnlinkAccount(ctx)

if err != nil {
return c.JSON(http.StatusInternalServerError, ErrorResponse{
Message: fmt.Sprintf("Failed to request wrapped invoice: %s", err.Error()),
})
}

return c.NoContent(http.StatusNoContent)
}

func (albyHttpSvc *AlbyHttpService) albyCallbackHandler(c echo.Context) error {
code := c.QueryParam("code")

Expand Down
6 changes: 6 additions & 0 deletions wails/wails_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ func (app *WailsApp) WailsRequestRouter(route string, method string, body string
return WailsRequestRouterResponse{Body: nil, Error: err.Error()}
}
return WailsRequestRouterResponse{Body: nil, Error: ""}
case "/api/alby/unlink-account":
err := app.svc.GetAlbyOAuthSvc().UnlinkAccount(ctx)
if err != nil {
return WailsRequestRouterResponse{Body: nil, Error: err.Error()}
}
return WailsRequestRouterResponse{Body: nil, Error: ""}
case "/api/alby/pay":
payRequest := &alby.AlbyPayRequest{}
err := json.Unmarshal([]byte(body), payRequest)
Expand Down

0 comments on commit fdf7baa

Please sign in to comment.