func editItem(vault *onepass.Vault, pattern string) { item, err := lookupSingleItem(vault, pattern) if err != nil { fatalErr(err, "Failed to find item") } logItemAction("Editing item", item) content, err := item.Content() if err != nil { fatalErr(err, "Unable to read item content") } formSectionId := len(content.Sections) + 1 urlSectionId := len(content.Sections) + 2 for i, section := range content.Sections { fmt.Printf("%d : %s\n", i+1, section.Title) } fmt.Printf("%d : Web Form fields\n", formSectionId) fmt.Printf("%d : URLs\n", urlSectionId) var section *onepass.ItemSection var field *onepass.ItemField sectionIdStr := readLinePrompt("Section (or title of new section)") sectionId, err := strconv.Atoi(sectionIdStr) if err != nil { // new section content.Sections = append(content.Sections, onepass.ItemSection{ Name: sectionIdStr, Title: sectionIdStr, Fields: []onepass.ItemField{}, }) section = &content.Sections[len(content.Sections)-1] } else if sectionId > 0 && sectionId <= len(content.Sections) { section = &content.Sections[sectionId-1] } else if sectionId != formSectionId && sectionId != urlSectionId { fatalErr(nil, "Unknown section number") } if section != nil { for i, field := range section.Fields { fmt.Printf("%d : %s (%s)\n", i+1, field.Title, field.ValueString()) } fieldIdStr := readLinePrompt("Field (or title of new field)") fieldId, err := strconv.Atoi(fieldIdStr) if err != nil { // new field section.Fields = append(section.Fields, onepass.ItemField{ Name: fieldIdStr, Kind: "string", Title: fieldIdStr, }) field = §ion.Fields[len(section.Fields)-1] } else if fieldId > 0 && fieldId <= len(section.Fields) { field = §ion.Fields[fieldId-1] } else { fatalErr(nil, "Unknown field number") } field.Value = readFieldValue(*field) } else if sectionId == formSectionId { for i, field := range content.FormFields { fmt.Printf("%d : %s (%s)\n", i+1, field.Name, field.Value) } fieldIdStr := readLinePrompt("Field") fieldId, err := strconv.Atoi(fieldIdStr) if err == nil && fieldId > 0 && fieldId <= len(content.FormFields) { content.FormFields[fieldId-1].Value = readFormFieldValue(content.FormFields[fieldId-1]) } else { fatalErr(nil, "Unknown field number") } } else if sectionId == urlSectionId { for i, url := range content.Urls { fmt.Printf("%d : %s (%s)\n", i+1, url.Label, url.Url) } var url *onepass.ItemUrl urlIdStr := readLinePrompt("URL (or label of new URL)") urlId, err := strconv.Atoi(urlIdStr) if err != nil { // new URL content.Urls = append(content.Urls, onepass.ItemUrl{ Label: urlIdStr, }) url = &content.Urls[len(content.Urls)-1] } else if urlId > 0 && urlId <= len(content.Urls) { url = &content.Urls[urlId-1] } else { fatalErr(nil, "Unknown URL number") } url.Url = readLinePrompt("%s", url.Label) } err = item.SetContent(content) if err != nil { fatalErr(err, "Unable to save updated content") } err = item.Save() if err != nil { fatalErr(err, "Unable to save updated item") } }
// create a set of item templates based on existing // items in a vault func exportItemTemplates(vault *onepass.Vault, pattern string) { items, err := vault.ListItems() if err != nil { fatalErr(err, "Unable to list vault items") } typeTemplates := map[string]onepass.ItemContent{} for _, item := range items { typeTemplate := onepass.ItemContent{ Sections: []onepass.ItemSection{}, FormFields: []onepass.WebFormField{}, } if !strings.HasPrefix(strings.ToLower(item.Title), pattern) { continue } content, err := item.Content() if err != nil { fmt.Fprintf(os.Stderr, "Failed to decrypt item: %v\n", err) } // section templates for _, section := range content.Sections { sectionTemplate := onepass.ItemSection{ Name: section.Name, Title: section.Title, Fields: []onepass.ItemField{}, } for _, field := range section.Fields { fieldTemplate := onepass.ItemField{ Name: field.Name, Title: field.Title, Kind: field.Kind, } sectionTemplate.Fields = append(sectionTemplate.Fields, fieldTemplate) } typeTemplate.Sections = append(typeTemplate.Sections, sectionTemplate) } // web form field templates for _, formField := range content.FormFields { formTemplate := onepass.WebFormField{ Name: formField.Name, Id: formField.Id, Type: formField.Type, Designation: formField.Designation, } typeTemplate.FormFields = append(typeTemplate.FormFields, formTemplate) } // URL templates for _, url := range content.Urls { urlTemplate := onepass.ItemUrl{Label: url.Label} typeTemplate.Urls = append(typeTemplate.Urls, urlTemplate) } typeTemplates[item.TypeName] = typeTemplate } data, err := json.Marshal(typeTemplates) if err != nil { fatalErr(err, "Unable to export item templates") } _, _ = os.Stdout.Write(prettyJson(data)) }
func addItem(vault *onepass.Vault, title string, shortTypeName string) { itemContent := onepass.ItemContent{} var typeName string for typeKey, itemType := range onepass.ItemTypes { if itemType.ShortAlias == shortTypeName { itemContent = onepass.ItemContent{} typeName = typeKey } } if len(typeName) == 0 { fatalErr(fmt.Errorf("Unknown item type '%s'", shortTypeName), "") } template, ok := onepass.StandardTemplate(typeName) if !ok { fatalErr(fmt.Errorf("No template for item type '%s'", shortTypeName), "") } // read sections for _, sectionTemplate := range template.Sections { section := onepass.ItemSection{ Name: sectionTemplate.Name, Title: sectionTemplate.Title, Fields: []onepass.ItemField{}, } for _, fieldTemplate := range sectionTemplate.Fields { field := onepass.ItemField{ Name: fieldTemplate.Name, Title: fieldTemplate.Title, Kind: fieldTemplate.Kind, } field.Value = readFieldValue(field) section.Fields = append(section.Fields, field) } itemContent.Sections = append(itemContent.Sections, section) } // read form fields for _, formFieldTemplate := range template.FormFields { field := onepass.WebFormField{ Name: formFieldTemplate.Name, Id: formFieldTemplate.Id, Type: formFieldTemplate.Type, Designation: formFieldTemplate.Designation, } field.Value = readFormFieldValue(field) itemContent.FormFields = append(itemContent.FormFields, field) } // read URLs for _, urlTemplate := range template.Urls { url := onepass.ItemUrl{ Label: urlTemplate.Label, } url.Url = readLinePrompt("%s (URL)", url.Label) itemContent.Urls = append(itemContent.Urls, url) } // save item to vault item, err := vault.AddItem(title, typeName, itemContent) if err != nil { fatalErr(err, "Unable to add item") } logItemAction("Added new item", item) }