Skip to content

Commit

Permalink
chore: Rename TokenRepository to IdentityRepository
Browse files Browse the repository at this point in the history
BREAKING CHANGE: TokenRepository is now IdentityRepository. The DDB table token DDB table is now identity
  • Loading branch information
activescott committed Jan 30, 2021
1 parent 12fd3ea commit 347edcd
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 104 deletions.
4 changes: 2 additions & 2 deletions server/app.arc
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ folder public
user
id *String

token
identity
id *String

@indexes
user
email *String

token
identity
provider_subject *String
4 changes: 2 additions & 2 deletions server/src/http/get-auth-me/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as arc from "@architect/functions"
import userRepositoryFactory from "@architect/shared/architect/oauth/repository/UserRepository"
import tokenRepositoryFactory from "@architect/shared/architect/oauth/repository/TokenRepository"
import identityRepositoryFactory from "@architect/shared/architect/oauth/repository/IdentityRepository"
import meHandlerFactory from "@architect/shared/architect/oauth/handlers/me"

const handlerImp = meHandlerFactory(
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
export const handler = arc.http.async(handlerImp)
4 changes: 2 additions & 2 deletions server/src/http/get-auth-redirect-000provider/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import oAuthRedirectHandlerFactory from "@architect/shared/architect/oauth/handlers/redirect"
import tokenRepositoryFactory from "@architect/shared/architect/oauth/repository/TokenRepository"
import identityRepositoryFactory from "@architect/shared/architect/oauth/repository/IdentityRepository"
import userRepositoryFactory from "@architect/shared/architect/oauth/repository/UserRepository"
import { fetchJson } from "@architect/shared/fetch"

const impl = oAuthRedirectHandlerFactory(
fetchJson,
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)

export const handler = impl
4 changes: 2 additions & 2 deletions server/src/http/post-auth-redirect-000provider/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import oAuthRedirectHandlerFactory from "@architect/shared/architect/oauth/handlers/redirect"
import tokenRepositoryFactory from "@architect/shared/architect/oauth/repository/TokenRepository"
import identityRepositoryFactory from "@architect/shared/architect/oauth/repository/IdentityRepository"
import userRepositoryFactory from "@architect/shared/architect/oauth/repository/UserRepository"
import { fetchJson } from "@architect/shared/fetch"

const impl = oAuthRedirectHandlerFactory(
fetchJson,
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)

export const handler = impl
8 changes: 4 additions & 4 deletions server/src/shared/architect/oauth/handlers/me.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HttpHandler, HttpRequest, HttpResponse } from "@architect/functions"
import { map } from "irritable-iterable"
import { readSessionID } from "../../middleware/session"
import { TokenRepository } from "../repository/TokenRepository"
import { IdentityRepository } from "../repository/IdentityRepository"
import { StoredUser, UserRepository } from "../repository/UserRepository"

import * as STATUS from "./httpStatus"
Expand All @@ -12,7 +12,7 @@ import * as STATUS from "./httpStatus"
*/
export default function meHandlerFactory(
userRepository: UserRepository,
tokenRepository: TokenRepository
identityRepository: IdentityRepository
): HttpHandler {
async function handlerImp(req: HttpRequest): Promise<HttpResponse> {
const sessionID = readSessionID(req)
Expand Down Expand Up @@ -52,8 +52,8 @@ export default function meHandlerFactory(
user: StoredUser
): Promise<{ providers: string[] }> {
try {
const tokens = await tokenRepository.listForUser(user.id)
const providers: string[] = map(tokens, (t) => t.provider).collect()
const identities = await identityRepository.listForUser(user.id)
const providers: string[] = map(identities, (t) => t.provider).collect()
return {
providers,
}
Expand Down
36 changes: 18 additions & 18 deletions server/src/shared/architect/oauth/handlers/redirect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
injectSessionToRequest,
readSessionID,
} from "../../middleware/session"
import tokenRepositoryFactory from "../repository/TokenRepository"
import identityRepositoryFactory from "../repository/IdentityRepository"
import userRepositoryFactory from "../repository/UserRepository"
import oAuthRedirectHandlerFactory from "./redirect"
import * as jwt from "node-webtokens"
Expand Down Expand Up @@ -44,7 +44,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()
req.queryStringParameters.error = "unknown"
Expand All @@ -59,7 +59,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()
req.queryStringParameters.error = errorCode
Expand All @@ -78,7 +78,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()

Expand All @@ -98,7 +98,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()

Expand Down Expand Up @@ -126,7 +126,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
fetchJson,
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)

// invoke handler
Expand Down Expand Up @@ -154,13 +154,13 @@ describe("redirect", () => {

// setup mocks:
const userRepo = userRepositoryFactory()
const tokenRepo = tokenRepositoryFactory()
const identityRepo = identityRepositoryFactory()
const email = randomEmail()
const fetchJson = mockFetchJsonWithEmail(email)
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
fetchJson,
userRepo,
tokenRepo
identityRepo
)

// invoke handler
Expand All @@ -178,7 +178,7 @@ describe("redirect", () => {
mockProviderConfigInEnvironment()

// setup mocks:
const tokenRepo = tokenRepositoryFactory()
const identityRepo = identityRepositoryFactory()
const userRepo = userRepositoryFactory()
const email = randomEmail()
// now create the user in the user repo so that we can ensure it isn't re-created:
Expand All @@ -192,7 +192,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
fetchJson,
userRepo,
tokenRepo
identityRepo
)

// invoke handler
Expand All @@ -207,16 +207,16 @@ describe("redirect", () => {

// setup mocks:
const userRepo = userRepositoryFactory()
const tokenRepo = tokenRepositoryFactory()
const identityRepo = identityRepositoryFactory()
const email = randomEmail()
const fetchJson = mockFetchJsonWithEmail(email)
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
fetchJson,
userRepo,
tokenRepo
identityRepo
)

const tokenRepoUpsert = sinon.spy(tokenRepo, "upsert")
const identityRepoUpsert = sinon.spy(identityRepo, "upsert")

// invoke handler
await oauthRedirectHandler(req)
Expand All @@ -225,8 +225,8 @@ describe("redirect", () => {
const newUser = await userRepo.getFromEmail(email)
if (!newUser) throw new Error("newUser must not be null")

expect(tokenRepoUpsert.callCount).toEqual(1)
const actualToken = tokenRepoUpsert.firstCall.args[0]
expect(identityRepoUpsert.callCount).toEqual(1)
const actualToken = identityRepoUpsert.firstCall.args[0]
expect(actualToken).toHaveProperty("provider", PROVIDER_NAME)
expect(actualToken).toHaveProperty("userID", newUser.id)
expect(actualToken).toHaveProperty("expires_at", expect.anything())
Expand All @@ -239,7 +239,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()

Expand All @@ -261,7 +261,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()

Expand All @@ -285,7 +285,7 @@ describe("redirect", () => {
const oauthRedirectHandler = oAuthRedirectHandlerFactory(
mockFetchJson(),
userRepositoryFactory(),
tokenRepositoryFactory()
identityRepositoryFactory()
)
const req = await mockAuthorizationCodeResponseRequest()

Expand Down
6 changes: 3 additions & 3 deletions server/src/shared/architect/oauth/handlers/redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { fetchJson as fetchJsonImpl, FetchJsonFunc } from "../../../fetch"
import { isTokenValid } from "../../middleware/csrf"
import { readSessionID } from "../../middleware/session"
import { Config, OAuthProviderConfig } from "../OAuthProviderConfig"
import { TokenRepository } from "../repository/TokenRepository"
import { IdentityRepository } from "../repository/IdentityRepository"
import { StoredUser, UserRepository } from "../repository/UserRepository"
import {
BAD_REQUEST,
Expand All @@ -27,7 +27,7 @@ import {
export default function oAuthRedirectHandlerFactory(
fetchJson: FetchJsonFunc = fetchJsonImpl,
userRepository: UserRepository,
tokenRepository: TokenRepository
identityRepository: IdentityRepository
): LambdaHttpHandler {
// This is the actual implementation. We're returning it from a factory so we can inject a mock fetch here. Injection is better than jest's auto-mock voodoo due to introducing time-wasting troubleshooting
async function oauthRedirectHandler(
Expand Down Expand Up @@ -108,7 +108,7 @@ export default function oAuthRedirectHandlerFactory(
assert(user != null, "user was not found and was not created?")

// save access/refresh tokens
await tokenRepository.upsert({
await identityRepository.upsert({
userID: user.id,
provider: providerName,
subject: parsed.payload.sub,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import { first } from "irritable-iterable"
import { randomInt } from "../../../../../test/support"
import tokenRepositoryFactory, {
StoredToken,
StoredTokenProposal,
TokenRepository,
} from "./TokenRepository"
import identityRepositoryFactory, {
StoredIdentity,
StoredIdentityProposal,
IdentityRepository,
} from "./IdentityRepository"

let repo: TokenRepository
let repo: IdentityRepository

beforeEach(() => {
repo = tokenRepositoryFactory()
repo = identityRepositoryFactory()
})

afterEach(async () => {
for (const token of await repo.list()) {
await repo.delete(token.id)
for (const identity of await repo.list()) {
await repo.delete(identity.id)
}
})

describe("upsert", () => {
it("should add a new token for existing user", async () => {
const proposed = randomToken()
it("should add a new identity for existing user", async () => {
const proposed = randomIdentity()
const added = await repo.upsert(proposed)
expectStrictTokenProps(added)
expectStrictIdentityProps(added)
})

it("should overwrite an existing token", async () => {
const proposed = randomToken()
it("should overwrite an existing identity", async () => {
const proposed = randomIdentity()

await Promise.allSettled([repo.upsert(proposed), repo.upsert(proposed)])

Expand All @@ -38,16 +38,16 @@ describe("upsert", () => {
})

describe("get", () => {
it("should return token if exists", async () => {
const proposed = randomToken()
it("should return identity if exists", async () => {
const proposed = randomIdentity()
const added = await repo.upsert(proposed)
await expect(repo.get(proposed.userID, proposed.provider)).resolves.toEqual(
added
)
})

it("should return null if doesn't exist", async () => {
const proposed = randomToken()
const proposed = randomIdentity()
//DON'T Add it; const added = await repo.upsert(proposed)
await expect(
repo.get(proposed.userID, proposed.provider)
Expand All @@ -67,15 +67,15 @@ describe("get", () => {
})

describe("getByProviderSubject", () => {
it("should return token if exists", async () => {
const proposed = randomToken()
it("should return identity if exists", async () => {
const proposed = randomIdentity()
const added = await repo.upsert(proposed)
await expect(
repo.getByProviderSubject(proposed.provider, proposed.subject)
).resolves.toEqual(added)
})
it("should return null if doesn't exist", async () => {
const proposed = randomToken()
const proposed = randomIdentity()
// don't added it..
await expect(
repo.getByProviderSubject(proposed.provider, proposed.subject)
Expand All @@ -95,18 +95,18 @@ describe("getByProviderSubject", () => {

describe("listForUser", () => {
it("should return providers", async () => {
const proposed = randomToken()
const proposed = randomIdentity()
await repo.upsert(proposed)
const tokens = await repo.listForUser(proposed.userID)
expect(tokens).toHaveLength(1)
expect(first(tokens)).toHaveProperty("provider", proposed.provider)
const identities = await repo.listForUser(proposed.userID)
expect(identities).toHaveLength(1)
expect(first(identities)).toHaveProperty("provider", proposed.provider)
})

it("should be empty with no tokens", async () => {
const proposed = randomToken()
it("should be empty with no identities", async () => {
const proposed = randomIdentity()
// don't add user:
const tokens = await repo.listForUser(proposed.userID)
expect(tokens).toHaveLength(0)
const identities = await repo.listForUser(proposed.userID)
expect(identities).toHaveLength(0)
})

it("should reject if missing args", async () => {
Expand All @@ -121,7 +121,7 @@ describe("listForUser", () => {
})
})

function expectStrictTokenProps(actual: StoredToken): void {
function expectStrictIdentityProps(actual: StoredIdentity): void {
const expectedProps: Record<string, string> = {
id: "string",
userID: "string",
Expand All @@ -148,7 +148,7 @@ function expectStrictTokenProps(actual: StoredToken): void {
}
}

function randomToken(): StoredTokenProposal {
function randomIdentity(): StoredIdentityProposal {
return {
userID: `uid:${randomInt()}`,
provider: `provider:${randomInt()}`,
Expand Down

0 comments on commit 347edcd

Please sign in to comment.