passkit

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2022 License: MIT Imports: 19 Imported by: 0

README

PassKit

This is a library for generating Apple Wallet PKPasses.

How to use

This library was heavily inspired by drallgood's jpasskit library which was written in Java, so the objects and functions are very similar to the ones available on jpasskit.

Define a pass

To define a pass you use the Pass struct, which represents the pass.json file. This struct is modeled as closely as possible to the json file, so adding data is straightforward:

c := passkit.NewBoardingPass(passkit.TransitTypeAir)
field := passkit.Field{
    Key: "key",
    Label: "label",
    Value:"value",
}

c.AddHeaderField(field)
c.AddPrimaryFields(field)
c.AddSecondaryFields(field)

p := passkit.Pass{
    FormatVersion:       1,
    TeamIdentifier:      "TEAMID",
    PassTypeIdentifier:  "pass.type.id",
    AuthenticationToken: "123141lkjdasj12314",
    OrganizationName:    "Your Organization",
    SerialNumber:        "1234",
    Description:         "test",
    BoardingPass:         c,
    Barcodes: []passkit.Barcode{
        {
            Format:          passkit.BarcodeFormatPDF417,
            Message:         "1312312312312312312312312312",
            MessageEncoding: "utf-8",
        },
    },
}
Templates

Usually, passes contain additional information that need to be included in the final, signed pass, e.g.

  • Images (icons, logos, background images)
  • Translations

These templates are defined in the apple wallet developer documentation.

To create the pass structure you need a PassTemplate instance, either using streams (with InMemoryPassTemplate) or files (with FolderPassTemplate).

Using files

To load the pass with files in the file system you create an instance of FolderPassTemplate passing the absolute file path of the folder:

folderTemplate := passkit.NewFolderPassTemplate("/home/user/pass")

When building the pass the files in the folder will be added.

Using streams (In Memory)

The second approach is more flexible, having the option of loading files using data streams:

memTemplate := passkit.NewInMemoryPassTemplate()

memTemplate.AddFileBytes(passkit.BundleThumbnail, bytes)
memTemplate.AddFileBytesLocalized(passkit.BundleIcon, "en", bytes)
err := memTemplate.AddFileFromURL(passkit.BundleLogo, "http://example.com/file.png")
err := memTemplate.AddFileFromURLLocalized(passkit.BundleLogo, "en", "http://example.com/file.png")
err := memTemplate.AddAllFiles("/home/user/pass")

Note: There are no checks, that the content of a provided file is valid. So if you'd provide a PDF file but store it as icon.png, it will not work.

Signing and zipping a pass

To create a pkpass file you need to use a Signer. There are two types of signers:

  • FileBasedSigner (uses a temp folder to create the zip file)
  • MemoryBasedSigner (creates the zip on memory as bytes)

To use any of the Signer instances you need an instance of SigningInformation. There are two methods to obtain an instance:

signer, err := passkit.LoadSigningInformationFromFiles("/home/user/pass_cert.p12", "password", "/home/user/AppleWWDRCA.cer")
signer, err := passkit.LoadSigningInformationFromBytes(passCertBytes, "password", wwdrcaBytes)

To create a zip you use the Pass, Signer, SigningInformation, and PassTemplate instances created previously:

signer := passkit.NewMemoryBasedSigner()
z, err := signer.CreateSignedAndZippedPassArchive(&pass, template, signInfo)
if err != nil {
    panic(err)
}

err = ioutil.WriteFile("/home/user/pass.pkpass", z, 0644)
if err != nil {
    panic(err)
}

Documentation

Index

Constants

View Source
const (

	//PKTextAlignment
	TextAlignmentLeft    TextAlignment = "PKTextAlignmentLeft"
	TextAlignmentCenter  TextAlignment = "PKTextAlignmentCenter"
	TextAlignmentRight   TextAlignment = "PKTextAlignmentRight"
	TextAlignmentNatural TextAlignment = "PKTextAlignmentNatural"

	//PKBarcodeFormat
	BarcodeFormatQR      BarcodeFormat = "PKBarcodeFormatQR"
	BarcodeFormatPDF417  BarcodeFormat = "PKBarcodeFormatPDF417"
	BarcodeFormatAztec   BarcodeFormat = "PKBarcodeFormatAztec"
	BarcodeFormatCode128 BarcodeFormat = "PKBarcodeFormatCode128"

	//PKDataDetectorType
	DataDetectorTypePhoneNumber   DataDetectorType = "PKDataDetectorTypePhoneNumber"
	DataDetectorTypeLink          DataDetectorType = "PKDataDetectorTypeLink"
	DataDetectorTypeAddress       DataDetectorType = "PKDataDetectorTypeAddress"
	DataDetectorTypeCalendarEvent DataDetectorType = "PKDataDetectorTypeCalendarEvent"

	//PKDateStyle
	DateStyleNone   DateStyle = "PKDateStyleNone"
	DateStyleShort  DateStyle = "PKDateStyleShort"
	DateStyleMedium DateStyle = "PKDateStyleMedium"
	DateStyleLong   DateStyle = "PKDateStyleLong"
	DateStyleFull   DateStyle = "PKDateStyleFull"

	//PKNumberStyle
	NumberStyleDecimal    NumberStyle = "PKNumberStyleDecimal"
	NumberStylePercent    NumberStyle = "PKNumberStylePercent"
	NumberStyleScientific NumberStyle = "PKNumberStyleScientific"
	NumberStyleSpellOut   NumberStyle = "PKNumberStyleSpellOut"

	//PKPassPersonalizationField
	PassPersonalizationFieldName         PassPersonalizationField = "PKPassPersonalizationFieldName"
	PassPersonalizationFieldPostalCode   PassPersonalizationField = "PKPassPersonalizationFieldPostalCode"
	PassPersonalizationFieldEmailAddress PassPersonalizationField = "PKPassPersonalizationFieldEmailAddress"
	PassPersonalizationFieldPhoneNumber  PassPersonalizationField = "PKPassPersonalizationFieldPhoneNumber"

	//PKTransitType
	TransitTypeAir     TransitType = "PKTransitTypeAir"
	TransitTypeBoat    TransitType = "PKTransitTypeBoat"
	TransitTypeBus     TransitType = "PKTransitTypeBus"
	TransitTypeGeneric TransitType = "PKTransitTypeGeneric"
	TransitTypeTrain   TransitType = "PKTransitTypeTrain"
)
View Source
const (
	BundleIconRetinaHD                = "icon@3x.png"
	BundleIconRetina                  = "icon@2x.png"
	BundleIcon                        = "icon.png"
	BundleLogoRetinaHD                = "logo@3x.png"
	BundleLogoRetina                  = "logo@2x.png"
	BundleThumbnailRetinaHD           = "thumbnail@3x.png"
	BundleThumbnailRetina             = "thumbnail@2x.png"
	BundleThumbnail                   = "thumbnail.png"
	BundleStripRetinaHD               = "strip@3x.png"
	BundleStripRetina                 = "strip@2x.png"
	BundleStrip                       = "strip.png"
	BundleBackgroundRetinaHD          = "background@3x.png"
	BundleBackgroundRetina            = "background@2x.png"
	BundleBackground                  = "background.png"
	BundleFooterRetinaHD              = "footer@3x.png"
	BundleFooterRetina                = "footer@2x.png"
	BundleFooter                      = "footer.png"
	BundlePersonalizationLogoRetinaHD = "personalizationLogo@3x.png"
	BundlePersonalizationLogoRetina   = "personalizationLogo@2x.png"
)

Variables

Functions

func NewFolderPassTemplate

func NewFolderPassTemplate(templateDir string) *folderPassTemplate

func NewInMemoryPassTemplate

func NewInMemoryPassTemplate() *inMemoryPassTemplate

Types

type Barcode

type Barcode struct {
	Format          BarcodeFormat `json:"format,omitempty"`
	AltText         string        `json:"altText,omitempty"`
	Message         string        `json:"message,omitempty"`
	MessageEncoding string        `json:"messageEncoding,omitempty"`
}

func (*Barcode) GetValidationErrors

func (b *Barcode) GetValidationErrors() []string

func (*Barcode) IsValid

func (b *Barcode) IsValid() bool

type BarcodeFormat

type BarcodeFormat string

type Beacon

type Beacon struct {
	Major         int    `json:"major,omitempty"`
	Minor         int    `json:"minor,omitempty"`
	ProximityUUID string `json:"proximityUUID,omitempty"`
	RelevantText  string `json:"relevantText,omitempty"`
}

func (*Beacon) GetValidationErrors

func (b *Beacon) GetValidationErrors() []string

func (*Beacon) IsValid

func (b *Beacon) IsValid() bool

type BoardingPass

type BoardingPass struct {
	*GenericPass
	TransitType TransitType `json:"transitType,omitempty"`
}

func NewBoardingPass

func NewBoardingPass(transitType TransitType) *BoardingPass

func (*BoardingPass) GetValidationErrors

func (b *BoardingPass) GetValidationErrors() []string

func (*BoardingPass) IsValid

func (b *BoardingPass) IsValid() bool

type Coupon

type Coupon struct {
	*GenericPass
}

func NewCoupon

func NewCoupon() *Coupon

type DataDetectorType

type DataDetectorType string

type DateStyle

type DateStyle string

type EventTicket

type EventTicket struct {
	*GenericPass
}

func NewEventTicket

func NewEventTicket() *EventTicket

type Field

type Field struct {
	Key               string             `json:"key,omitempty"`
	Label             string             `json:"label,omitempty"`
	Value             interface{}        `json:"value,omitempty"`
	AttributedValue   interface{}        `json:"attributedValue,omitempty"`
	ChangeMessage     string             `json:"changeMessage,omitempty"`
	TextAlignment     TextAlignment      `json:"textAlignment,omitempty"`
	DataDetectorTypes []DataDetectorType `json:"dataDetectorTypes,omitempty"`
	CurrencyCode      string             `json:"currencyCode,omitempty"`
	NumberStyle       NumberStyle        `json:"numberStyle,omitempty"`
	DateStyle         DateStyle          `json:"dateStyle,omitempty"`
	TimeStyle         DateStyle          `json:"timeStyle,omitempty"`
	IsRelative        bool               `json:"isRelative,omitempty"`
	IgnoreTimeZone    bool               `json:"ignoresTimeZone,omitempty"`
}

func (*Field) GetValidationErrors

func (f *Field) GetValidationErrors() []string

func (*Field) IsValid

func (f *Field) IsValid() bool

type GenericPass

type GenericPass struct {
	HeaderFields    []Field `json:"headerFields,omitempty"`
	PrimaryFields   []Field `json:"primaryFields,omitempty"`
	SecondaryFields []Field `json:"secondaryFields,omitempty"`
	AuxiliaryFields []Field `json:"auxiliaryFields,omitempty"`
	BackFields      []Field `json:"backFields,omitempty"`
}

func NewGenericPass

func NewGenericPass() *GenericPass

func (*GenericPass) AddAuxiliaryFields

func (gp *GenericPass) AddAuxiliaryFields(field Field)

func (*GenericPass) AddBackFields

func (gp *GenericPass) AddBackFields(field Field)

func (*GenericPass) AddHeaderField

func (gp *GenericPass) AddHeaderField(field Field)

func (*GenericPass) AddPrimaryFields

func (gp *GenericPass) AddPrimaryFields(field Field)

func (*GenericPass) AddSecondaryFields

func (gp *GenericPass) AddSecondaryFields(field Field)

func (*GenericPass) GetValidationErrors

func (gp *GenericPass) GetValidationErrors() []string

func (*GenericPass) IsValid

func (gp *GenericPass) IsValid() bool

type Location

type Location struct {
	Latitude     float64 `json:"latitude,omitempty"`
	Longitude    float64 `json:"longitude,omitempty"`
	Altitude     float64 `json:"altitude,omitempty"`
	RelevantText string  `json:"relevantText,omitempty"`
}

func (*Location) GetValidationErrors

func (l *Location) GetValidationErrors() []string

func (*Location) IsValid

func (l *Location) IsValid() bool

type NFC

type NFC struct {
	Message             string `json:"message,omitempty"`
	EncryptionPublicKey string `json:"encryptionPublicKey,omitempty"`
}

type NumberStyle

type NumberStyle string

type PWAssociatedApp

type PWAssociatedApp struct {
	Title        string
	IdGooglePlay string
	IdAmazon     string
}

func (*PWAssociatedApp) GetValidationErrors

func (a *PWAssociatedApp) GetValidationErrors() []string

func (*PWAssociatedApp) IsValid

func (a *PWAssociatedApp) IsValid() bool

type Pass

type Pass struct {
	FormatVersion              int                    `json:"formatVersion,omitempty"`
	SerialNumber               string                 `json:"serialNumber,omitempty"`
	PassTypeIdentifier         string                 `json:"passTypeIdentifier,omitempty"`
	WebServiceURL              string                 `json:"webServiceURL,omitempty"`
	AuthenticationToken        string                 `json:"authenticationToken,omitempty"`
	Description                string                 `json:"description,omitempty"`
	TeamIdentifier             string                 `json:"teamIdentifier,omitempty"`
	OrganizationName           string                 `json:"organizationName,omitempty"`
	LogoText                   string                 `json:"logoText,omitempty"`
	ForegroundColor            string                 `json:"foregroundColor,omitempty"`
	BackgroundColor            string                 `json:"backgroundColor,omitempty"`
	LabelColor                 string                 `json:"labelColor,omitempty"`
	GroupingIdentifier         string                 `json:"groupingIdentifier,omitempty"`
	Beacons                    []Beacon               `json:"beacons,omitempty"`
	Locations                  []Location             `json:"locations,omitempty"`
	Barcodes                   []Barcode              `json:"barcodes,omitempty"`
	EventTicket                *EventTicket           `json:"eventTicket,omitempty"`
	Coupon                     *Coupon                `json:"coupon,omitempty"`
	StoreCard                  *StoreCard             `json:"storeCard,omitempty"`
	BoardingPass               *BoardingPass          `json:"boardingPass,omitempty"`
	Generic                    *GenericPass           `json:"generic,omitempty"`
	AppLaunchURL               string                 `json:"appLaunchURL,omitempty"`
	AssociatedStoreIdentifiers []int64                `json:"associatedStoreIdentifiers,omitempty"`
	UserInfo                   map[string]interface{} `json:"userInfo,omitempty"`
	MaxDistance                int64                  `json:"maxDistance,omitempty"`
	RelevantDate               *time.Time             `json:"relevantDate,omitempty"`
	ExpirationDate             *time.Time             `json:"expirationDate,omitempty"`
	Voided                     bool                   `json:"voided,omitempty"`
	Nfc                        *NFC                   `json:"nfc,omitempty"`
	SharingProhibited          bool                   `json:"sharingProhibited,omitempty"`
	// contains filtered or unexported fields
}

func (*Pass) GetValidationErrors

func (p *Pass) GetValidationErrors() []string

func (*Pass) IsValid

func (p *Pass) IsValid() bool

func (*Pass) SetBackgroundColorHex

func (p *Pass) SetBackgroundColorHex(hex string) error

func (*Pass) SetBackgroundColorRGB

func (p *Pass) SetBackgroundColorRGB(r, g, b uint8) error

func (*Pass) SetForegroundColorHex

func (p *Pass) SetForegroundColorHex(hex string) error

func (*Pass) SetForegroundColorRGB

func (p *Pass) SetForegroundColorRGB(r, g, b uint8) error

func (*Pass) SetLabelColorHex

func (p *Pass) SetLabelColorHex(hex string) error

func (*Pass) SetLabelColorRGB

func (p *Pass) SetLabelColorRGB(r, g, b uint8) error

type PassPersonalizationField

type PassPersonalizationField string

type PassTemplate

type PassTemplate interface {
	ProvisionPassAtDirectory(tmpDirPath string) error
	GetAllFiles() (map[string][]byte, error)
}

type Personalization

type Personalization struct {
	RequiredPersonalizationFields []PassPersonalizationField `json:"requiredPersonalizationFields"`
	Description                   string                     `json:"description"`
	TermsAndConditions            string                     `json:"termsAndConditions"`
}

func (*Personalization) GetValidationErrors

func (pz *Personalization) GetValidationErrors() []string

func (*Personalization) IsValid

func (pz *Personalization) IsValid() bool

type Signer

type Signer interface {
	CreateSignedAndZippedPassArchive(p *Pass, t PassTemplate, i *SigningInformation) ([]byte, error)
	CreateSignedAndZippedPersonalizedPassArchive(p *Pass, pz *Personalization, t PassTemplate, i *SigningInformation) ([]byte, error)
	SignManifestFile(manifestJson []byte, i *SigningInformation) ([]byte, error)
}

func NewFileBasedSigner

func NewFileBasedSigner() Signer

func NewMemoryBasedSigner

func NewMemoryBasedSigner() Signer

type SigningInformation

type SigningInformation struct {
	// contains filtered or unexported fields
}

func LoadSigningInformationFromBytes

func LoadSigningInformationFromBytes(pkcs12KeyStoreFile []byte, keyStorePassword string, appleWWDRCAFile []byte) (*SigningInformation, error)

func LoadSigningInformationFromFiles

func LoadSigningInformationFromFiles(pkcs12KeyStoreFilePath, keyStorePassword, appleWWDRCAFilePath string) (*SigningInformation, error)

type StoreCard

type StoreCard struct {
	*GenericPass
}

func NewStoreCard

func NewStoreCard() *StoreCard

type TextAlignment

type TextAlignment string

type TransitType

type TransitType string

type Validateable

type Validateable interface {
	IsValid() bool
	GetValidationErrors() []string
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL