Skip to content

Commit

Permalink
Merge branch 'main' into totp-secret
Browse files Browse the repository at this point in the history
  • Loading branch information
faroceann committed Jun 3, 2024
2 parents a947d51 + 709ab52 commit ec8b720
Show file tree
Hide file tree
Showing 17 changed files with 2,483 additions and 335 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI

on:
push:
branches:
- 'main'
pull_request: {}

defaults:
run:
shell: bash

jobs:
test:
name: Test Go ${{ matrix.go }}
runs-on: ubuntu-latest
strategy:
matrix:
go:
- 'stable'
- 'oldstable'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}

- name: Run Tests
run: |
go mod download
go test -v ./...
- name: Code style
run: |
gofmt -d ./
git diff --exit-code
34 changes: 0 additions & 34 deletions .semaphore/semaphore.yml

This file was deleted.

13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ directorysync.SetAPIKey("<WORKOS_API_KEY>");

For our SDKs WorkOS follows a Semantic Versioning ([SemVer](https://semver.org/)) process where all releases will have a version X.Y.Z (like 1.0.0) pattern wherein Z would be a bug fix (e.g., 1.0.1), Y would be a minor release (1.1.0) and X would be a major release (2.0.0). We permit any breaking changes to only be released in major versions and strongly recommend reading changelogs before making any major version upgrades.

## Beta Releases

WorkOS has features in Beta that can be accessed via Beta releases. We would love for you to try these
and share feedback with us before these features reach general availability (GA). To install a Beta version,
please follow the [installation steps](#installation) above using the Beta release version.

> Note: there can be breaking changes between Beta versions. Therefore, we recommend pinning the package version to a
> specific version. This way you can install the same version each time without breaking changes unless you are
> intentionally looking for the latest Beta version.
We highly recommend keeping an eye on when the Beta feature you are interested in goes from Beta to stable so that you
can move to using the stable version.

## More Information

- [User Management Guide](https://workos.com/docs/user-management)
Expand Down
2 changes: 1 addition & 1 deletion internal/workos/workos.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package workos

const (
// Version represents the SDK version number.
Version = "v4.0.0"
Version = "v4.11.0"
)
6 changes: 6 additions & 0 deletions pkg/common/role.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package common

type RoleResponse struct {
// The slug of the role
Slug string `json:"slug"`
}
3 changes: 3 additions & 0 deletions pkg/directorysync/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ type User struct {

// The User's updated at date
UpdatedAt string `json:"updated_at"`

// The role given to this Directory User
Role common.RoleResponse `json:"role,omitempty"`
}

// ListUsersOpts contains the options to request provisioned Directory Users.
Expand Down
6 changes: 6 additions & 0 deletions pkg/directorysync/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ func TestListUsers(t *testing.T) {
State: Active,
RawAttributes: json.RawMessage(`{"foo":"bar"}`),
CustomAttributes: json.RawMessage(`{"foo":"bar"}`),
Role: common.RoleResponse{
Slug: "member",
},
},
},
ListMetadata: common.ListMetadata{
Expand Down Expand Up @@ -126,6 +129,7 @@ func listUsersTestHandler(w http.ResponseWriter, r *http.Request) {
State: Active,
RawAttributes: json.RawMessage(`{"foo":"bar"}`),
CustomAttributes: json.RawMessage(`{"foo":"bar"}`),
Role: common.RoleResponse{Slug: "member"},
},
},
ListMetadata: common.ListMetadata{
Expand Down Expand Up @@ -291,6 +295,7 @@ func TestGetUser(t *testing.T) {
State: Active,
RawAttributes: json.RawMessage(`{"foo":"bar"}`),
CustomAttributes: json.RawMessage(`{"foo":"bar"}`),
Role: common.RoleResponse{Slug: "member"},
},
},
}
Expand Down Expand Up @@ -349,6 +354,7 @@ func getUserTestHandler(w http.ResponseWriter, r *http.Request) {
State: Active,
RawAttributes: json.RawMessage(`{"foo":"bar"}`),
CustomAttributes: json.RawMessage(`{"foo":"bar"}`),
Role: common.RoleResponse{Slug: "member"},
})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
Expand Down
10 changes: 10 additions & 0 deletions pkg/directorysync/directorysync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ func TestDirectorySyncListUsers(t *testing.T) {
}
SetAPIKey("test")

expectedRole := common.RoleResponse{
Slug: "member",
}

expectedResponse := ListUsersResponse{
Data: []User{
User{
Expand All @@ -45,6 +49,7 @@ func TestDirectorySyncListUsers(t *testing.T) {
State: Active,
RawAttributes: json.RawMessage(`{"foo":"bar"}`),
CustomAttributes: json.RawMessage(`{"foo":"bar"}`),
Role: expectedRole,
},
},
ListMetadata: common.ListMetadata{
Expand Down Expand Up @@ -109,6 +114,10 @@ func TestDirectorySyncGetUser(t *testing.T) {
}
SetAPIKey("test")

expectedRole := common.RoleResponse{
Slug: "member",
}

expectedResponse := User{
ID: "directory_user_id",
FirstName: "Rick",
Expand All @@ -131,6 +140,7 @@ func TestDirectorySyncGetUser(t *testing.T) {
State: Active,
RawAttributes: json.RawMessage(`{"foo":"bar"}`),
CustomAttributes: json.RawMessage(`{"foo":"bar"}`),
Role: expectedRole,
}
directoryUserResponse, err := GetUser(context.Background(), GetUserOpts{
User: "directory_user_id",
Expand Down
16 changes: 13 additions & 3 deletions pkg/events/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,16 @@ const (
UserCreated = "user.created"
UserUpdated = "user.updated"
UserDeleted = "user.deleted"
OrganizationMembershipAdded = "organization_membership.added"
OrganizationMembershipRemoved = "organization_membership.removed"
OrganizationMembershipAdded = "organization_membership.added" // Deprecated: use OrganizationMembershipCreated instead
OrganizationMembershipCreated = "organization_membership.created"
OrganizationMembershipDeleted = "organization_membership.deleted"
OrganizationMembershipUpdated = "organization_membership.updated"
OrganizationMembershipRemoved = "organization_membership.removed" // Deprecated: use OrganizationMembershipDeleted instead
SessionCreated = "session.created"
EmailVerificationCreated = "email_verification.created"
InvitationCreated = "invitation.created"
MagicAuthCreated = "magic_auth.created"
PasswordResetCreated = "password_reset.created"
)

// Client represents a client that performs Event requests to the WorkOS API.
Expand Down Expand Up @@ -87,7 +95,7 @@ type Event struct {
// ListEventsOpts contains the options to request provisioned Events.
type ListEventsOpts struct {
// Filter to only return Events of particular types.
Events []string `url:"events,omitempty"`
Events []string `url:"events"`

// Maximum number of records to return.
Limit int `url:"limit"`
Expand All @@ -100,6 +108,8 @@ type ListEventsOpts struct {

// Date range end for stream of Events.
RangeEnd string `url:"range_end,omitempty"`

OrganizationId string `url:"organization_id,omitempty"`
}

// GetEventsResponse describes the response structure when requesting
Expand Down
39 changes: 38 additions & 1 deletion pkg/events/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ func TestListEvents(t *testing.T) {
},
}

events, err := client.ListEvents(context.Background(), ListEventsOpts{})
params := ListEventsOpts{
Events: []string{"dsync.user.created"},
}
events, err := client.ListEvents(context.Background(), params)

require.NoError(t, err)
require.Equal(t, expectedResponse, events)
Expand All @@ -56,6 +59,7 @@ func TestListEvents(t *testing.T) {
rangeEnd := currentTime.AddDate(0, 0, -1)

params := ListEventsOpts{
Events: []string{"dsync.user.created"},
RangeStart: rangeStart.String(),
RangeEnd: rangeEnd.String(),
}
Expand All @@ -78,6 +82,39 @@ func TestListEvents(t *testing.T) {
require.NoError(t, err)
require.Equal(t, expectedResponse, events)
})

t.Run("ListEvents succeeds to fetch Events with an organization_id", func(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(ListEventsTestHandler))
defer server.Close()
client := &Client{
HTTPClient: server.Client(),
Endpoint: server.URL,
APIKey: "test",
}

params := ListEventsOpts{
Events: []string{"dsync.user.created"},
OrganizationId: "org_1234",
}

expectedResponse := ListEventsResponse{
Data: []Event{
{
ID: "event_abcd1234",
Event: "dsync.user.created",
Data: json.RawMessage(`{"foo":"bar"}`),
},
},
ListMetadata: common.ListMetadata{
After: "",
},
}

events, err := client.ListEvents(context.Background(), params)

require.NoError(t, err)
require.Equal(t, expectedResponse, events)
})
}

func ListEventsTestHandler(w http.ResponseWriter, r *http.Request) {
Expand Down
6 changes: 5 additions & 1 deletion pkg/events/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ func TestEventsListEvents(t *testing.T) {
}
SetAPIKey("test")

params := ListEventsOpts{
Events: []string{"dsync.user.created"},
}

expectedResponse := ListEventsResponse{
Data: []Event{
{
Expand All @@ -33,7 +37,7 @@ func TestEventsListEvents(t *testing.T) {
After: "",
},
}
eventsResponse, err := ListEvents(context.Background(), ListEventsOpts{})
eventsResponse, err := ListEvents(context.Background(), params)

require.NoError(t, err)
require.Equal(t, expectedResponse, eventsResponse)
Expand Down
26 changes: 26 additions & 0 deletions pkg/organizations/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ type ListOrganizationsResponse struct {
ListMetadata common.ListMetadata `json:"listMetadata"`
}

type OrganizationDomainDataState string

const (
Verified OrganizationDomainDataState = "verified"
Pending OrganizationDomainDataState = "pending"
)

// OrganizationDomainData contains data used to create an OrganizationDomain.
type OrganizationDomainData struct {
// The domain's value.
Domain string `json:"domain"`

// The domain's state.
State OrganizationDomainDataState `json:"state"`
}

// CreateOrganizationOpts contains the options to create an Organization.
type CreateOrganizationOpts struct {
// Name of the Organization.
Expand All @@ -135,8 +151,13 @@ type CreateOrganizationOpts struct {
AllowProfilesOutsideOrganization bool `json:"allow_profiles_outside_organization"`

// Domains of the Organization.
//
// Deprecated: Use DomainData instead.
Domains []string `json:"domains"`

// Domains of the Organization.
DomainData []OrganizationDomainData `json:"domain_data"`

// Optional unique identifier to ensure idempotency
IdempotencyKey string `json:"idempotency_iey,omitempty"`
}
Expand All @@ -154,7 +175,12 @@ type UpdateOrganizationOpts struct {
AllowProfilesOutsideOrganization bool

// Domains of the Organization.
//
// Deprecated: Use DomainData instead.
Domains []string

// Domains of the Organization.
DomainData []OrganizationDomainData `json:"domain_data"`
}

// GetOrganization gets an Organization.
Expand Down
Loading

0 comments on commit ec8b720

Please sign in to comment.