diff --git a/internal/core/ports/identity_service.go b/internal/core/ports/identity_service.go index 4361a63ff..ef55e6caa 100644 --- a/internal/core/ports/identity_service.go +++ b/internal/core/ports/identity_service.go @@ -13,6 +13,11 @@ import ( "github.com/polygonid/sh-id-platform/internal/kms" ) +const ( + // AuthorizationRequestQRCallbackURL is the URL to call back after the user has authenticated + AuthorizationRequestQRCallbackURL = "%s/v2/authentication/callback?sessionID=%s" +) + // DIDCreationOptions represents options for DID creation type DIDCreationOptions struct { Method core.DIDMethod `json:"method"` diff --git a/internal/core/ports/link_service.go b/internal/core/ports/link_service.go index 54d1890df..2e097077d 100644 --- a/internal/core/ports/link_service.go +++ b/internal/core/ports/link_service.go @@ -29,10 +29,12 @@ type CreateQRCodeResponse struct { type LinkStatus string const ( - LinkAll LinkStatus = "all" // LinkAll : All links - LinkActive LinkStatus = "active" // LinkActive : Active links - LinkInactive LinkStatus = "inactive" // LinkInactive : Inactive links - LinkExceeded LinkStatus = "exceeded" // LinkExceeded : Expired links or with more credentials issued than expected + LinkAll LinkStatus = "all" // LinkAll : All links + LinkActive LinkStatus = "active" // LinkActive : Active links + LinkInactive LinkStatus = "inactive" // LinkInactive : Inactive links + LinkExceeded LinkStatus = "exceeded" // LinkExceeded : Expired links or with more credentials issued than expected + AgentUrl = "%s/v2/agent" // AgentUrl : Agent URL + LinksCallbackURL = "%s/v2/identities/%s/credentials/links/callback?sessionID=%s&linkID=%s" // LinksCallbackURL : Links callback URL ) // LinkTypeReqFromString constructs a LinkStatus from a string @@ -58,7 +60,7 @@ type LinkService interface { GetByID(ctx context.Context, issuerID w3c.DID, id uuid.UUID) (*domain.Link, error) GetAll(ctx context.Context, issuerDID w3c.DID, status LinkStatus, query *string) ([]domain.Link, error) CreateQRCode(ctx context.Context, issuerDID w3c.DID, linkID uuid.UUID, serverURL string) (*CreateQRCodeResponse, error) - IssueOrFetchClaim(ctx context.Context, sessionID string, issuerDID w3c.DID, userDID w3c.DID, linkID uuid.UUID, hostURL string) (*protocol.CredentialsOfferMessage, error) + IssueOrFetchClaim(ctx context.Context, issuerDID w3c.DID, userDID w3c.DID, linkID uuid.UUID, hostURL string) (*protocol.CredentialsOfferMessage, error) ProcessCallBack(ctx context.Context, message string, sessionID uuid.UUID, linkID uuid.UUID, hostURL string) (*protocol.CredentialsOfferMessage, error) GetQRCode(ctx context.Context, sessionID uuid.UUID, issuerID w3c.DID, linkID uuid.UUID) (*GetQRCodeResponse, error) } diff --git a/internal/core/ports/qrstore_service.go b/internal/core/ports/qrstore_service.go index 2c21b4ddb..4e9cf49e4 100644 --- a/internal/core/ports/qrstore_service.go +++ b/internal/core/ports/qrstore_service.go @@ -7,6 +7,13 @@ import ( "github.com/google/uuid" ) +const ( + // QRStoreUrl is the URL to the QR store service + QRStoreUrl = "iden3comm://?request_uri=%s/v2/qr-store?id=%s" + // UniversalLinkURL - is the URL to the Universal Link + UniversalLinkURL = "%s#request_uri=%s/v2/qr-store?id=%s" +) + // QrStoreService is the interface that provides methods to store and retrieve the body of QR codes and to provide support // to the QR url shortener functionality. type QrStoreService interface { diff --git a/internal/core/services/claims.go b/internal/core/services/claims.go index 029b875c4..ee40ed670 100644 --- a/internal/core/services/claims.go +++ b/internal/core/services/claims.go @@ -353,7 +353,7 @@ func (c *claim) GetCredentialQrCode(ctx context.Context, issID *w3c.DID, id uuid ID: claim.ID.String(), }, }, - URL: fmt.Sprintf("%s/v2/agent", strings.TrimSuffix(hostURL, "/")), + URL: fmt.Sprintf(ports.AgentUrl, strings.TrimSuffix(hostURL, "/")), }, From: claim.Issuer, ID: credID.String(), diff --git a/internal/core/services/identity.go b/internal/core/services/identity.go index b9cc580b6..930773610 100644 --- a/internal/core/services/identity.go +++ b/internal/core/services/identity.go @@ -548,7 +548,7 @@ func (i *identity) CreateAuthenticationQRCode(ctx context.Context, serverURL str Typ: packers.MediaTypePlainMessage, Type: protocol.AuthorizationRequestMessageType, Body: protocol.AuthorizationRequestMessageBody{ - CallbackURL: fmt.Sprintf("%s/v2/authentication/callback?sessionID=%s", serverURL, sessionID), + CallbackURL: fmt.Sprintf(ports.AuthorizationRequestQRCallbackURL, serverURL, sessionID), Reason: authReason, Scope: make([]protocol.ZeroKnowledgeProofRequest, 0), }, @@ -1230,7 +1230,7 @@ func newDIDDocument(serverURL string, issuerDID w3c.DID) verifiable.DIDDocument verifiable.Service{ ID: fmt.Sprintf("%s#%s", issuerDID, verifiable.Iden3CommServiceType), Type: verifiable.Iden3CommServiceType, - ServiceEndpoint: fmt.Sprintf("%s/v2/agent", serverURL), + ServiceEndpoint: fmt.Sprintf(ports.AgentUrl, serverURL), }, }, } diff --git a/internal/core/services/link.go b/internal/core/services/link.go index 86ce5754d..890dfc26e 100644 --- a/internal/core/services/link.go +++ b/internal/core/services/link.go @@ -40,10 +40,6 @@ var ( ErrLinkMaxExceeded = errors.New("cannot issue a credential for an expired link") // ErrLinkInactive - link inactive ErrLinkInactive = errors.New("cannot issue a credential for an inactive link") - // ErrClaimAlreadyIssued - claim already issued - ErrClaimAlreadyIssued = errors.New("the claim was already issued for the user") - // ErrUnsupportedCredentialStatusType - unsupported credential status type - ErrUnsupportedCredentialStatusType = errors.New("unsupported credential status type") ) // Link - represents a link in the issuer node @@ -187,7 +183,7 @@ func (ls *Link) CreateQRCode(ctx context.Context, issuerDID w3c.DID, linkID uuid Typ: packers.MediaTypePlainMessage, Type: protocol.AuthorizationRequestMessageType, Body: protocol.AuthorizationRequestMessageBody{ - CallbackURL: fmt.Sprintf("%s/v2/identities/%s/credentials/links/callback?sessionID=%s&linkID=%s", serverURL, issuerDID.String(), sessionID, linkID.String()), + CallbackURL: fmt.Sprintf(ports.LinksCallbackURL, serverURL, issuerDID.String(), sessionID, linkID.String()), Reason: authReason, Scope: make([]protocol.ZeroKnowledgeProofRequest, 0), }, @@ -198,11 +194,6 @@ func (ls *Link) CreateQRCode(ctx context.Context, issuerDID w3c.DID, linkID uuid return nil, err } - err = ls.sessionManager.SetLink(ctx, linkState.CredentialStateCacheKey(linkID.String(), sessionID), *linkState.NewStatePending()) - if err != nil { - return nil, err - } - raw, err := json.Marshal(qrCode) if err != nil { return nil, err @@ -223,7 +214,7 @@ func (ls *Link) CreateQRCode(ctx context.Context, issuerDID w3c.DID, linkID uuid } // IssueOrFetchClaim - Create a new claim -func (ls *Link) IssueOrFetchClaim(ctx context.Context, sessionID string, issuerDID w3c.DID, userDID w3c.DID, linkID uuid.UUID, hostURL string) (*protocol.CredentialsOfferMessage, error) { +func (ls *Link) IssueOrFetchClaim(ctx context.Context, issuerDID w3c.DID, userDID w3c.DID, linkID uuid.UUID, hostURL string) (*protocol.CredentialsOfferMessage, error) { link, err := ls.linkRepository.GetByID(ctx, issuerDID, linkID) if err != nil { log.Error(ctx, "cannot fetch the link", "err", err) @@ -237,12 +228,7 @@ func (ls *Link) IssueOrFetchClaim(ctx context.Context, sessionID string, issuerD } if err := ls.validate(ctx, link); err != nil { - setLinkError := ls.sessionManager.SetLink(ctx, linkState.CredentialStateCacheKey(linkID.String(), sessionID), *linkState.NewStateError(err)) - if setLinkError != nil { - log.Error(ctx, "cannot set the state", "err", setLinkError) - return nil, setLinkError - } - + log.Error(ctx, "cannot validate the link", "err", err) return nil, err } @@ -314,11 +300,11 @@ func (ls *Link) IssueOrFetchClaim(ctx context.Context, sessionID string, issuerD credentialIssued.ID = credentialIssuedID if link.CredentialSignatureProof { - credOffer, err := notifications.NewOfferMsg(fmt.Sprintf("%s/v2/agent", hostURL), credentialIssued) + credOffer, err := notifications.NewOfferMsg(fmt.Sprintf(ports.AgentUrl, hostURL), credentialIssued) return credOffer, err } else { if credentialIssued.MTPProof.Bytes != nil { - credOffer, err := notifications.NewOfferMsg(fmt.Sprintf("%s/v2/agent", hostURL), credentialIssued) + credOffer, err := notifications.NewOfferMsg(fmt.Sprintf(ports.AgentUrl, hostURL), credentialIssued) return credOffer, err } log.Info(ctx, "credential issued without MTP proof. Publishing state have to be done", "credential", credentialIssued.ID.String()) @@ -346,7 +332,7 @@ func (ls *Link) ProcessCallBack(ctx context.Context, message string, sessionID u return nil, err } - offer, err := ls.IssueOrFetchClaim(ctx, sessionID.String(), *issuerDID, *userDID, linkID, hostURL) + offer, err := ls.IssueOrFetchClaim(ctx, *issuerDID, *userDID, linkID, hostURL) if err != nil { log.Error(ctx, "error issuing claim", "err", err) return nil, err diff --git a/internal/core/services/link_test.go b/internal/core/services/link_test.go index 94ab4da20..a97727545 100644 --- a/internal/core/services/link_test.go +++ b/internal/core/services/link_test.go @@ -180,8 +180,7 @@ func Test_link_issueClaim(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - sessionID := uuid.New().String() - offer, err := linkService.IssueOrFetchClaim(ctx, sessionID, tc.did, tc.userDID, tc.LinkID, "host_url") + offer, err := linkService.IssueOrFetchClaim(ctx, tc.did, tc.userDID, tc.LinkID, "host_url") if tc.expected.err != nil { assert.Error(t, err) assert.Equal(t, tc.expected.err, err) diff --git a/internal/core/services/qrstore.go b/internal/core/services/qrstore.go index 2b2816cc5..0edadfa77 100644 --- a/internal/core/services/qrstore.go +++ b/internal/core/services/qrstore.go @@ -9,6 +9,7 @@ import ( "github.com/google/uuid" + "github.com/polygonid/sh-id-platform/internal/core/ports" "github.com/polygonid/sh-id-platform/internal/log" "github.com/polygonid/sh-id-platform/pkg/cache" ) @@ -60,12 +61,12 @@ func (s *QrStoreService) Store(ctx context.Context, qrCode []byte, ttl time.Dura // ToDeepLink constructs a deeplink that will be used to get the body of a QR code. func (s *QrStoreService) ToDeepLink(hostURL string, id uuid.UUID) string { - return fmt.Sprintf("iden3comm://?request_uri=%s/v2/qr-store?id=%s", hostURL, id.String()) + return fmt.Sprintf(ports.QRStoreUrl, hostURL, id.String()) } // ToUniversalLink constructs a universal link func (s *QrStoreService) ToUniversalLink(uLinkBaseUrl string, hostURL string, id uuid.UUID) string { - return fmt.Sprintf("%s#request_uri=%s/v2/qr-store?id=%s", uLinkBaseUrl, hostURL, id.String()) + return fmt.Sprintf(ports.UniversalLinkURL, uLinkBaseUrl, hostURL, id.String()) } func (s *QrStoreService) key(id uuid.UUID) string { diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 573fc99ec..2bf439d4e 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -20,7 +20,7 @@ type Cache interface { // Set sets a value in the caches accessible by the key. The ttl param is the maximum time to live in the cache // a ttl=0 means that the entry could be cached forever Set(ctx context.Context, key string, value any, ttl time.Duration) error - // Get searches for a non expired entry in the cache and returns the result in the value variable sent as reference and a found paramenter. You should only trust the returned value if f is true + // Get searches for a non expired entry in the cache and returns the result in the value variable sent as reference and a found parameter. You should only trust the returned value if f is true Get(ctx context.Context, key string, value any) bool // Exists tells whether a key exists in the cache with a valid ttl Exists(ctx context.Context, key string) bool